LCOV - code coverage report
Current view: top level - dom/html - HTMLFrameSetElement.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 156 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 19 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "HTMLFrameSetElement.h"
       8             : #include "mozilla/dom/HTMLFrameSetElementBinding.h"
       9             : #include "mozilla/dom/EventHandlerBinding.h"
      10             : #include "nsGlobalWindow.h"
      11             : #include "mozilla/UniquePtrExtensions.h"
      12             : #include "nsAttrValueOrString.h"
      13             : 
      14           0 : NS_IMPL_NS_NEW_HTML_ELEMENT(FrameSet)
      15             : 
      16             : namespace mozilla {
      17             : namespace dom {
      18             : 
      19           0 : HTMLFrameSetElement::~HTMLFrameSetElement()
      20             : {
      21           0 : }
      22             : 
      23             : JSObject*
      24           0 : HTMLFrameSetElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
      25             : {
      26           0 :   return HTMLFrameSetElementBinding::Wrap(aCx, this, aGivenProto);
      27             : }
      28             : 
      29           0 : NS_IMPL_ISUPPORTS_INHERITED(HTMLFrameSetElement, nsGenericHTMLElement,
      30             :                             nsIDOMHTMLFrameSetElement)
      31             : 
      32           0 : NS_IMPL_ELEMENT_CLONE(HTMLFrameSetElement)
      33             : 
      34             : NS_IMETHODIMP
      35           0 : HTMLFrameSetElement::SetCols(const nsAString& aCols)
      36             : {
      37           0 :   ErrorResult rv;
      38           0 :   SetCols(aCols, rv);
      39           0 :   return rv.StealNSResult();
      40             : }
      41             : 
      42             : NS_IMETHODIMP
      43           0 : HTMLFrameSetElement::GetCols(nsAString& aCols)
      44             : {
      45           0 :   DOMString cols;
      46           0 :   GetCols(cols);
      47           0 :   cols.ToString(aCols);
      48           0 :   return NS_OK;
      49             : }
      50             : 
      51             : NS_IMETHODIMP
      52           0 : HTMLFrameSetElement::SetRows(const nsAString& aRows)
      53             : {
      54           0 :   ErrorResult rv;
      55           0 :   SetRows(aRows, rv);
      56           0 :   return rv.StealNSResult();
      57             : }
      58             : 
      59             : NS_IMETHODIMP
      60           0 : HTMLFrameSetElement::GetRows(nsAString& aRows)
      61             : {
      62           0 :   DOMString rows;
      63           0 :   GetRows(rows);
      64           0 :   rows.ToString(aRows);
      65           0 :   return NS_OK;
      66             : }
      67             : 
      68             : nsresult
      69           0 : HTMLFrameSetElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
      70             :                                    const nsAttrValueOrString* aValue,
      71             :                                    bool aNotify)
      72             : {
      73             :   /* The main goal here is to see whether the _number_ of rows or
      74             :    * columns has changed. If it has, we need to reframe; otherwise
      75             :    * we want to reflow.
      76             :    * Ideally, the style hint would be changed back to reflow after the reframe
      77             :    * has been performed. Unfortunately, however, the reframe will be performed
      78             :    * by the call to nsNodeUtils::AttributeChanged, which occurs *after*
      79             :    * AfterSetAttr is called, leaving us with no convenient way of changing the
      80             :    * value back to reflow afterwards. However, nsNodeUtils::AttributeChanged is
      81             :    * effectively the only consumer of this value, so as long as we always set
      82             :    * the value correctly here, we should be fine.
      83             :    */
      84           0 :   mCurrentRowColHint = NS_STYLE_HINT_REFLOW;
      85           0 :   if (aNamespaceID == kNameSpaceID_None) {
      86           0 :     if (aName == nsGkAtoms::rows) {
      87           0 :       if (aValue) {
      88           0 :         int32_t oldRows = mNumRows;
      89           0 :         ParseRowCol(aValue->String(), mNumRows, &mRowSpecs);
      90             : 
      91           0 :         if (mNumRows != oldRows) {
      92           0 :           mCurrentRowColHint = nsChangeHint_ReconstructFrame;
      93             :         }
      94             :       }
      95           0 :     } else if (aName == nsGkAtoms::cols) {
      96           0 :       if (aValue) {
      97           0 :         int32_t oldCols = mNumCols;
      98           0 :         ParseRowCol(aValue->String(), mNumCols, &mColSpecs);
      99             : 
     100           0 :         if (mNumCols != oldCols) {
     101           0 :           mCurrentRowColHint = nsChangeHint_ReconstructFrame;
     102             :         }
     103             :       }
     104             :     }
     105             :   }
     106             : 
     107           0 :   return nsGenericHTMLElement::BeforeSetAttr(aNamespaceID, aName, aValue, aNotify);
     108             : }
     109             : 
     110             : nsresult
     111           0 : HTMLFrameSetElement::GetRowSpec(int32_t *aNumValues,
     112             :                                 const nsFramesetSpec** aSpecs)
     113             : {
     114           0 :   NS_PRECONDITION(aNumValues, "Must have a pointer to an integer here!");
     115           0 :   NS_PRECONDITION(aSpecs, "Must have a pointer to an array of nsFramesetSpecs");
     116           0 :   *aNumValues = 0;
     117           0 :   *aSpecs = nullptr;
     118             : 
     119           0 :   if (!mRowSpecs) {
     120           0 :     const nsAttrValue* value = GetParsedAttr(nsGkAtoms::rows);
     121           0 :     if (value && value->Type() == nsAttrValue::eString) {
     122           0 :       nsresult rv = ParseRowCol(value->GetStringValue(), mNumRows,
     123           0 :                                 &mRowSpecs);
     124           0 :       NS_ENSURE_SUCCESS(rv, rv);
     125             :     }
     126             : 
     127           0 :     if (!mRowSpecs) {  // we may not have had an attr or had an empty attr
     128           0 :       mRowSpecs = MakeUnique<nsFramesetSpec[]>(1);
     129           0 :       mNumRows = 1;
     130           0 :       mRowSpecs[0].mUnit  = eFramesetUnit_Relative;
     131           0 :       mRowSpecs[0].mValue = 1;
     132             :     }
     133             :   }
     134             : 
     135           0 :   *aSpecs = mRowSpecs.get();
     136           0 :   *aNumValues = mNumRows;
     137           0 :   return NS_OK;
     138             : }
     139             : 
     140             : nsresult
     141           0 : HTMLFrameSetElement::GetColSpec(int32_t *aNumValues,
     142             :                                 const nsFramesetSpec** aSpecs)
     143             : {
     144           0 :   NS_PRECONDITION(aNumValues, "Must have a pointer to an integer here!");
     145           0 :   NS_PRECONDITION(aSpecs, "Must have a pointer to an array of nsFramesetSpecs");
     146           0 :   *aNumValues = 0;
     147           0 :   *aSpecs = nullptr;
     148             : 
     149           0 :   if (!mColSpecs) {
     150           0 :     const nsAttrValue* value = GetParsedAttr(nsGkAtoms::cols);
     151           0 :     if (value && value->Type() == nsAttrValue::eString) {
     152           0 :       nsresult rv = ParseRowCol(value->GetStringValue(), mNumCols,
     153           0 :                                 &mColSpecs);
     154           0 :       NS_ENSURE_SUCCESS(rv, rv);
     155             :     }
     156             : 
     157           0 :     if (!mColSpecs) {  // we may not have had an attr or had an empty attr
     158           0 :       mColSpecs = MakeUnique<nsFramesetSpec[]>(1);
     159           0 :       mNumCols = 1;
     160           0 :       mColSpecs[0].mUnit  = eFramesetUnit_Relative;
     161           0 :       mColSpecs[0].mValue = 1;
     162             :     }
     163             :   }
     164             : 
     165           0 :   *aSpecs = mColSpecs.get();
     166           0 :   *aNumValues = mNumCols;
     167           0 :   return NS_OK;
     168             : }
     169             : 
     170             : 
     171             : bool
     172           0 : HTMLFrameSetElement::ParseAttribute(int32_t aNamespaceID,
     173             :                                     nsIAtom* aAttribute,
     174             :                                     const nsAString& aValue,
     175             :                                     nsAttrValue& aResult)
     176             : {
     177           0 :   if (aNamespaceID == kNameSpaceID_None) {
     178           0 :     if (aAttribute == nsGkAtoms::bordercolor) {
     179           0 :       return aResult.ParseColor(aValue);
     180             :     }
     181           0 :     if (aAttribute == nsGkAtoms::frameborder) {
     182           0 :       return nsGenericHTMLElement::ParseFrameborderValue(aValue, aResult);
     183             :     }
     184           0 :     if (aAttribute == nsGkAtoms::border) {
     185           0 :       return aResult.ParseIntWithBounds(aValue, 0, 100);
     186             :     }
     187             :   }
     188             : 
     189           0 :   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
     190           0 :                                               aResult);
     191             : }
     192             : 
     193             : nsChangeHint
     194           0 : HTMLFrameSetElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
     195             :                                             int32_t aModType) const
     196             : {
     197             :   nsChangeHint retval =
     198           0 :     nsGenericHTMLElement::GetAttributeChangeHint(aAttribute, aModType);
     199           0 :   if (aAttribute == nsGkAtoms::rows ||
     200           0 :       aAttribute == nsGkAtoms::cols) {
     201           0 :     retval |= mCurrentRowColHint;
     202             :   }
     203           0 :   return retval;
     204             : }
     205             : 
     206             : /**
     207             :  * Translate a "rows" or "cols" spec into an array of nsFramesetSpecs
     208             :  */
     209             : nsresult
     210           0 : HTMLFrameSetElement::ParseRowCol(const nsAString & aValue,
     211             :                                  int32_t& aNumSpecs,
     212             :                                  UniquePtr<nsFramesetSpec[]>* aSpecs)
     213             : {
     214           0 :   if (aValue.IsEmpty()) {
     215           0 :     aNumSpecs = 0;
     216           0 :     *aSpecs = nullptr;
     217           0 :     return NS_OK;
     218             :   }
     219             : 
     220             :   static const char16_t sAster('*');
     221             :   static const char16_t sPercent('%');
     222             :   static const char16_t sComma(',');
     223             : 
     224           0 :   nsAutoString spec(aValue);
     225             :   // remove whitespace (Bug 33699) and quotation marks (bug 224598)
     226             :   // also remove leading/trailing commas (bug 31482)
     227           0 :   spec.StripChars(" \n\r\t\"\'");
     228           0 :   spec.Trim(",");
     229             : 
     230             :   // Count the commas. Don't count more than X commas (bug 576447).
     231             :   static_assert(NS_MAX_FRAMESET_SPEC_COUNT * sizeof(nsFramesetSpec) < (1 << 30),
     232             :                 "Too many frameset specs allowed to allocate");
     233           0 :   int32_t commaX = spec.FindChar(sComma);
     234           0 :   int32_t count = 1;
     235           0 :   while (commaX != kNotFound && count < NS_MAX_FRAMESET_SPEC_COUNT) {
     236           0 :     count++;
     237           0 :     commaX = spec.FindChar(sComma, commaX + 1);
     238             :   }
     239             : 
     240           0 :   auto specs = MakeUniqueFallible<nsFramesetSpec[]>(count);
     241           0 :   if (!specs) {
     242           0 :     *aSpecs = nullptr;
     243           0 :     aNumSpecs = 0;
     244           0 :     return NS_ERROR_OUT_OF_MEMORY;
     245             :   }
     246             : 
     247             :   // Pre-grab the compat mode; we may need it later in the loop.
     248           0 :   bool isInQuirks = InNavQuirksMode(OwnerDoc());
     249             : 
     250             :   // Parse each comma separated token
     251             : 
     252           0 :   int32_t start = 0;
     253           0 :   int32_t specLen = spec.Length();
     254             : 
     255           0 :   for (int32_t i = 0; i < count; i++) {
     256             :     // Find our comma
     257           0 :     commaX = spec.FindChar(sComma, start);
     258           0 :     NS_ASSERTION(i == count - 1 || commaX != kNotFound,
     259             :                  "Failed to find comma, somehow");
     260           0 :     int32_t end = (commaX == kNotFound) ? specLen : commaX;
     261             : 
     262             :     // Note: If end == start then it means that the token has no
     263             :     // data in it other than a terminating comma (or the end of the spec).
     264             :     // So default to a fixed width of 0.
     265           0 :     specs[i].mUnit = eFramesetUnit_Fixed;
     266           0 :     specs[i].mValue = 0;
     267           0 :     if (end > start) {
     268           0 :       int32_t numberEnd = end;
     269           0 :       char16_t ch = spec.CharAt(numberEnd - 1);
     270           0 :       if (sAster == ch) {
     271           0 :         specs[i].mUnit = eFramesetUnit_Relative;
     272           0 :         numberEnd--;
     273           0 :       } else if (sPercent == ch) {
     274           0 :         specs[i].mUnit = eFramesetUnit_Percent;
     275           0 :         numberEnd--;
     276             :         // check for "*%"
     277           0 :         if (numberEnd > start) {
     278           0 :           ch = spec.CharAt(numberEnd - 1);
     279           0 :           if (sAster == ch) {
     280           0 :             specs[i].mUnit = eFramesetUnit_Relative;
     281           0 :             numberEnd--;
     282             :           }
     283             :         }
     284             :       }
     285             : 
     286             :       // Translate value to an integer
     287           0 :       nsAutoString token;
     288           0 :       spec.Mid(token, start, numberEnd - start);
     289             : 
     290             :       // Treat * as 1*
     291           0 :       if ((eFramesetUnit_Relative == specs[i].mUnit) &&
     292           0 :         (0 == token.Length())) {
     293           0 :         specs[i].mValue = 1;
     294             :       }
     295             :       else {
     296             :         // Otherwise just convert to integer.
     297             :         nsresult err;
     298           0 :         specs[i].mValue = token.ToInteger(&err);
     299           0 :         if (NS_FAILED(err)) {
     300           0 :           specs[i].mValue = 0;
     301             :         }
     302             :       }
     303             : 
     304             :       // Treat 0* as 1* in quirks mode (bug 40383)
     305           0 :       if (isInQuirks) {
     306           0 :         if ((eFramesetUnit_Relative == specs[i].mUnit) &&
     307           0 :           (0 == specs[i].mValue)) {
     308           0 :           specs[i].mValue = 1;
     309             :         }
     310             :       }
     311             : 
     312             :       // Catch zero and negative frame sizes for Nav compatibility
     313             :       // Nav resized absolute and relative frames to "1" and
     314             :       // percent frames to an even percentage of the width
     315             :       //
     316             :       //if (isInQuirks && (specs[i].mValue <= 0)) {
     317             :       //  if (eFramesetUnit_Percent == specs[i].mUnit) {
     318             :       //    specs[i].mValue = 100 / count;
     319             :       //  } else {
     320             :       //    specs[i].mValue = 1;
     321             :       //  }
     322             :       //} else {
     323             : 
     324             :       // In standards mode, just set negative sizes to zero
     325           0 :       if (specs[i].mValue < 0) {
     326           0 :         specs[i].mValue = 0;
     327             :       }
     328           0 :       start = end + 1;
     329             :     }
     330             :   }
     331             : 
     332           0 :   aNumSpecs = count;
     333             :   // Transfer ownership to caller here
     334           0 :   *aSpecs = Move(specs);
     335             : 
     336           0 :   return NS_OK;
     337             : }
     338             : 
     339             : bool
     340           0 : HTMLFrameSetElement::IsEventAttributeNameInternal(nsIAtom *aName)
     341             : {
     342             :   return nsContentUtils::IsEventAttributeName(aName,
     343             :                                               EventNameType_HTML |
     344           0 :                                               EventNameType_HTMLBodyOrFramesetOnly);
     345             : }
     346             : 
     347             : 
     348             : #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the shim */
     349             : // nsGenericHTMLElement::GetOnError returns
     350             : // already_AddRefed<EventHandlerNonNull> while other getters return
     351             : // EventHandlerNonNull*, so allow passing in the type to use here.
     352             : #define WINDOW_EVENT_HELPER(name_, type_)                                      \
     353             :   type_*                                                                       \
     354             :   HTMLFrameSetElement::GetOn##name_()                                          \
     355             :   {                                                                            \
     356             :     if (nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow()) {              \
     357             :       nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win);                   \
     358             :       return globalWin->GetOn##name_();                                        \
     359             :     }                                                                          \
     360             :     return nullptr;                                                            \
     361             :   }                                                                            \
     362             :   void                                                                         \
     363             :   HTMLFrameSetElement::SetOn##name_(type_* handler)                            \
     364             :   {                                                                            \
     365             :     nsPIDOMWindowInner* win = OwnerDoc()->GetInnerWindow();                    \
     366             :     if (!win) {                                                                \
     367             :       return;                                                                  \
     368             :     }                                                                          \
     369             :                                                                                \
     370             :     nsGlobalWindow* globalWin = nsGlobalWindow::Cast(win);                     \
     371             :     return globalWin->SetOn##name_(handler);                                   \
     372             :   }
     373             : #define WINDOW_EVENT(name_, id_, type_, struct_)                               \
     374             :   WINDOW_EVENT_HELPER(name_, EventHandlerNonNull)
     375             : #define BEFOREUNLOAD_EVENT(name_, id_, type_, struct_)                         \
     376             :   WINDOW_EVENT_HELPER(name_, OnBeforeUnloadEventHandlerNonNull)
     377             : #include "mozilla/EventNameList.h" // IWYU pragma: keep
     378             : #undef BEFOREUNLOAD_EVENT
     379             : #undef WINDOW_EVENT
     380             : #undef WINDOW_EVENT_HELPER
     381             : #undef EVENT
     382             : 
     383             : } // namespace dom
     384             : } // namespace mozilla

Generated by: LCOV version 1.13