LCOV - app.info - content/html/content/src/nsHTMLFrameSetElement.cpp

LCOV - code coverage report
| Current view: | directory - content/html/content/src - nsHTMLFrameSetElement.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 148 | 0 | 0.0 %
| Date: | 2012-07-07 | Functions: | 19 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
           2                 : /* ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is Mozilla Communicator client code.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is
          18                 :  * Netscape Communications Corporation.
          19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
          20                 :  * the Initial Developer. All Rights Reserved.
          21                 :  *
          22                 :  * Contributor(s):
          23                 :  *
          24                 :  * Alternatively, the contents of this file may be used under the terms of
          25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          28                 :  * of those above. If you wish to allow use of your version of this file only
          29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          30                 :  * use your version of this file under the terms of the MPL, indicate your
          31                 :  * decision by deleting the provisions above and replace them with the notice
          32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          33                 :  * the provisions above, a recipient may use your version of this file under
          34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          35                 :  *
          36                 :  * ***** END LICENSE BLOCK ***** */
          37                 :
          38                 : #include "nsHTMLFrameSetElement.h"
          39                 : #include "jsapi.h"
          40                 :
          41               0 : NS_IMPL_NS_NEW_HTML_ELEMENT(FrameSet)
          42                 :
          43                 :
          44               0 : nsHTMLFrameSetElement::nsHTMLFrameSetElement(already_AddRefed<nsINodeInfo> aNodeInfo)
          45                 :   : nsGenericHTMLElement(aNodeInfo), mNumRows(0), mNumCols(0),
          46               0 :     mCurrentRowColHint(NS_STYLE_HINT_REFLOW)
          47                 : {
          48               0 : }
          49                 :
          50               0 : nsHTMLFrameSetElement::~nsHTMLFrameSetElement()
          51                 : {
          52               0 : }
          53                 :
          54                 :
          55               0 : NS_IMPL_ADDREF_INHERITED(nsHTMLFrameSetElement, nsGenericElement)
          56               0 : NS_IMPL_RELEASE_INHERITED(nsHTMLFrameSetElement, nsGenericElement)
          57                 :
          58                 :
          59               0 : DOMCI_NODE_DATA(HTMLFrameSetElement, nsHTMLFrameSetElement)
          60                 :
          61                 : // QueryInterface implementation for nsHTMLFrameSetElement
          62               0 : NS_INTERFACE_TABLE_HEAD(nsHTMLFrameSetElement)
          63               0 :   NS_HTML_CONTENT_INTERFACE_TABLE1(nsHTMLFrameSetElement,
          64                 :                                    nsIDOMHTMLFrameSetElement)
          65               0 :   NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLFrameSetElement,
          66                 :                                                nsGenericHTMLElement)
          67               0 : NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLFrameSetElement)
          68                 :
          69                 :
          70               0 : NS_IMPL_ELEMENT_CLONE(nsHTMLFrameSetElement)
          71                 :
          72                 :
          73               0 : NS_IMPL_STRING_ATTR(nsHTMLFrameSetElement, Cols, cols)
          74               0 : NS_IMPL_STRING_ATTR(nsHTMLFrameSetElement, Rows, rows)
          75                 :
          76                 : nsresult
          77               0 : nsHTMLFrameSetElement::SetAttr(PRInt32 aNameSpaceID,
          78                 :                                nsIAtom* aAttribute,
          79                 :                                nsIAtom* aPrefix,
          80                 :                                const nsAString& aValue,
          81                 :                                bool aNotify)
          82                 : {
          83                 :   nsresult rv;
          84                 :   /* The main goal here is to see whether the _number_ of rows or
          85                 :    *  columns has changed.  If it has, we need to reframe; otherwise
          86                 :    *  we want to reflow.  So we set mCurrentRowColHint here, then call
          87                 :    *  nsGenericHTMLElement::SetAttr, which will end up calling
          88                 :    *  GetAttributeChangeHint and notifying layout with that hint.
          89                 :    *  Once nsGenericHTMLElement::SetAttr returns, we want to go back to our
          90                 :    *  normal hint, which is NS_STYLE_HINT_REFLOW.
          91                 :    */
          92               0 :   if (aAttribute == nsGkAtoms::rows && aNameSpaceID == kNameSpaceID_None) {
          93               0 :     PRInt32 oldRows = mNumRows;
          94               0 :     ParseRowCol(aValue, mNumRows, getter_Transfers(mRowSpecs));
          95                 :
          96               0 :     if (mNumRows != oldRows) {
          97               0 :       mCurrentRowColHint = NS_STYLE_HINT_FRAMECHANGE;
          98               0 :     }
          99               0 :   } else if (aAttribute == nsGkAtoms::cols &&
         100                 :              aNameSpaceID == kNameSpaceID_None) {
         101               0 :     PRInt32 oldCols = mNumCols;
         102               0 :     ParseRowCol(aValue, mNumCols, getter_Transfers(mColSpecs));
         103                 :
         104               0 :     if (mNumCols != oldCols) {
         105               0 :       mCurrentRowColHint = NS_STYLE_HINT_FRAMECHANGE;
         106                 :     }
         107                 :   }
         108                 :
         109                 :   rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aAttribute, aPrefix,
         110               0 :                                      aValue, aNotify);
         111               0 :   mCurrentRowColHint = NS_STYLE_HINT_REFLOW;
         112                 :
         113               0 :   return rv;
         114                 : }
         115                 :
         116                 : nsresult
         117               0 : nsHTMLFrameSetElement::GetRowSpec(PRInt32 *aNumValues,
         118                 :                                   const nsFramesetSpec** aSpecs)
         119                 : {
         120               0 :   NS_PRECONDITION(aNumValues, "Must have a pointer to an integer here!");
         121               0 :   NS_PRECONDITION(aSpecs, "Must have a pointer to an array of nsFramesetSpecs");
         122               0 :   *aNumValues = 0;
         123               0 :   *aSpecs = nsnull;
         124                 :
         125               0 :   if (!mRowSpecs) {
         126               0 :     const nsAttrValue* value = GetParsedAttr(nsGkAtoms::rows);
         127               0 :     if (value && value->Type() == nsAttrValue::eString) {
         128               0 :       nsresult rv = ParseRowCol(value->GetStringValue(), mNumRows,
         129               0 :                                 getter_Transfers(mRowSpecs));
         130               0 :       NS_ENSURE_SUCCESS(rv, rv);
         131                 :     }
         132                 :
         133               0 :     if (!mRowSpecs) {  // we may not have had an attr or had an empty attr
         134               0 :       mRowSpecs = new nsFramesetSpec[1];
         135               0 :       if (!mRowSpecs) {
         136               0 :         mNumRows = 0;
         137               0 :         return NS_ERROR_OUT_OF_MEMORY;
         138                 :       }
         139               0 :       mNumRows = 1;
         140               0 :       mRowSpecs[0].mUnit  = eFramesetUnit_Relative;
         141               0 :       mRowSpecs[0].mValue = 1;
         142                 :     }
         143                 :   }
         144                 :
         145               0 :   *aSpecs = mRowSpecs;
         146               0 :   *aNumValues = mNumRows;
         147               0 :   return NS_OK;
         148                 : }
         149                 :
         150                 : nsresult
         151               0 : nsHTMLFrameSetElement::GetColSpec(PRInt32 *aNumValues,
         152                 :                                   const nsFramesetSpec** aSpecs)
         153                 : {
         154               0 :   NS_PRECONDITION(aNumValues, "Must have a pointer to an integer here!");
         155               0 :   NS_PRECONDITION(aSpecs, "Must have a pointer to an array of nsFramesetSpecs");
         156               0 :   *aNumValues = 0;
         157               0 :   *aSpecs = nsnull;
         158                 :
         159               0 :   if (!mColSpecs) {
         160               0 :     const nsAttrValue* value = GetParsedAttr(nsGkAtoms::cols);
         161               0 :     if (value && value->Type() == nsAttrValue::eString) {
         162               0 :       nsresult rv = ParseRowCol(value->GetStringValue(), mNumCols,
         163               0 :                                 getter_Transfers(mColSpecs));
         164               0 :       NS_ENSURE_SUCCESS(rv, rv);
         165                 :     }
         166                 :
         167               0 :     if (!mColSpecs) {  // we may not have had an attr or had an empty attr
         168               0 :       mColSpecs = new nsFramesetSpec[1];
         169               0 :       if (!mColSpecs) {
         170               0 :         mNumCols = 0;
         171               0 :         return NS_ERROR_OUT_OF_MEMORY;
         172                 :       }
         173               0 :       mNumCols = 1;
         174               0 :       mColSpecs[0].mUnit  = eFramesetUnit_Relative;
         175               0 :       mColSpecs[0].mValue = 1;
         176                 :     }
         177                 :   }
         178                 :
         179               0 :   *aSpecs = mColSpecs;
         180               0 :   *aNumValues = mNumCols;
         181               0 :   return NS_OK;
         182                 : }
         183                 :
         184                 :
         185                 : bool
         186               0 : nsHTMLFrameSetElement::ParseAttribute(PRInt32 aNamespaceID,
         187                 :                                       nsIAtom* aAttribute,
         188                 :                                       const nsAString& aValue,
         189                 :                                       nsAttrValue& aResult)
         190                 : {
         191               0 :   if (aNamespaceID == kNameSpaceID_None) {
         192               0 :     if (aAttribute == nsGkAtoms::bordercolor) {
         193               0 :       return aResult.ParseColor(aValue);
         194                 :     }
         195               0 :     if (aAttribute == nsGkAtoms::frameborder) {
         196               0 :       return nsGenericHTMLElement::ParseFrameborderValue(aValue, aResult);
         197                 :     }
         198               0 :     if (aAttribute == nsGkAtoms::border) {
         199               0 :       return aResult.ParseIntWithBounds(aValue, 0, 100);
         200                 :     }
         201                 :   }
         202                 :
         203                 :   return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
         204               0 :                                               aResult);
         205                 : }
         206                 :
         207                 : nsChangeHint
         208               0 : nsHTMLFrameSetElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
         209                 :                                               PRInt32 aModType) const
         210                 : {
         211                 :   nsChangeHint retval =
         212               0 :     nsGenericHTMLElement::GetAttributeChangeHint(aAttribute, aModType);
         213               0 :   if (aAttribute == nsGkAtoms::rows ||
         214                 :       aAttribute == nsGkAtoms::cols) {
         215               0 :     NS_UpdateHint(retval, mCurrentRowColHint);
         216                 :   }
         217               0 :   return retval;
         218                 : }
         219                 :
         220                 : /**
         221                 :  * Translate a "rows" or "cols" spec into an array of nsFramesetSpecs
         222                 :  */
         223                 : nsresult
         224               0 : nsHTMLFrameSetElement::ParseRowCol(const nsAString & aValue,
         225                 :                                    PRInt32& aNumSpecs,
         226                 :                                    nsFramesetSpec** aSpecs)
         227                 : {
         228               0 :   if (aValue.IsEmpty()) {
         229               0 :     aNumSpecs = 0;
         230               0 :     *aSpecs = nsnull;
         231               0 :     return NS_OK;
         232                 :   }
         233                 :
         234                 :   static const PRUnichar sAster('*');
         235                 :   static const PRUnichar sPercent('%');
         236                 :   static const PRUnichar sComma(',');
         237                 :
         238               0 :   nsAutoString spec(aValue);
         239                 :   // remove whitespace (Bug 33699) and quotation marks (bug 224598)
         240                 :   // also remove leading/trailing commas (bug 31482)
         241               0 :   spec.StripChars(" \n\r\t\"\'");
         242               0 :   spec.Trim(",");
         243                 :
         244                 :   // Count the commas. Don't count more than X commas (bug 576447).
         245                 :   PR_STATIC_ASSERT(NS_MAX_FRAMESET_SPEC_COUNT * sizeof(nsFramesetSpec) < (1 << 30));
         246               0 :   PRInt32 commaX = spec.FindChar(sComma);
         247               0 :   PRInt32 count = 1;
         248               0 :   while (commaX != kNotFound && count < NS_MAX_FRAMESET_SPEC_COUNT) {
         249               0 :     count++;
         250               0 :     commaX = spec.FindChar(sComma, commaX + 1);
         251                 :   }
         252                 :
         253               0 :   nsFramesetSpec* specs = new nsFramesetSpec[count];
         254               0 :   if (!specs) {
         255               0 :     *aSpecs = nsnull;
         256               0 :     aNumSpecs = 0;
         257               0 :     return NS_ERROR_OUT_OF_MEMORY;
         258                 :   }
         259                 :
         260                 :   // Pre-grab the compat mode; we may need it later in the loop.
         261               0 :   bool isInQuirks = InNavQuirksMode(OwnerDoc());
         262                 :
         263                 :   // Parse each comma separated token
         264                 :
         265               0 :   PRInt32 start = 0;
         266               0 :   PRInt32 specLen = spec.Length();
         267                 :
         268               0 :   for (PRInt32 i = 0; i < count; i++) {
         269                 :     // Find our comma
         270               0 :     commaX = spec.FindChar(sComma, start);
         271               0 :     NS_ASSERTION(i == count - 1 || commaX != kNotFound,
         272                 :                  "Failed to find comma, somehow");
         273               0 :     PRInt32 end = (commaX == kNotFound) ? specLen : commaX;
         274                 :
         275                 :     // Note: If end == start then it means that the token has no
         276                 :     // data in it other than a terminating comma (or the end of the spec).
         277                 :     // So default to a fixed width of 0.
         278               0 :     specs[i].mUnit = eFramesetUnit_Fixed;
         279               0 :     specs[i].mValue = 0;
         280               0 :     if (end > start) {
         281               0 :       PRInt32 numberEnd = end;
         282               0 :       PRUnichar ch = spec.CharAt(numberEnd - 1);
         283               0 :       if (sAster == ch) {
         284               0 :         specs[i].mUnit = eFramesetUnit_Relative;
         285               0 :         numberEnd--;
         286               0 :       } else if (sPercent == ch) {
         287               0 :         specs[i].mUnit = eFramesetUnit_Percent;
         288               0 :         numberEnd--;
         289                 :         // check for "*%"
         290               0 :         if (numberEnd > start) {
         291               0 :           ch = spec.CharAt(numberEnd - 1);
         292               0 :           if (sAster == ch) {
         293               0 :             specs[i].mUnit = eFramesetUnit_Relative;
         294               0 :             numberEnd--;
         295                 :           }
         296                 :         }
         297                 :       }
         298                 :
         299                 :       // Translate value to an integer
         300               0 :       nsAutoString token;
         301               0 :       spec.Mid(token, start, numberEnd - start);
         302                 :
         303                 :       // Treat * as 1*
         304               0 :       if ((eFramesetUnit_Relative == specs[i].mUnit) &&
         305               0 :         (0 == token.Length())) {
         306               0 :         specs[i].mValue = 1;
         307                 :       }
         308                 :       else {
         309                 :         // Otherwise just convert to integer.
         310                 :         PRInt32 err;
         311               0 :         specs[i].mValue = token.ToInteger(&err);
         312               0 :         if (err) {
         313               0 :           specs[i].mValue = 0;
         314                 :         }
         315                 :       }
         316                 :
         317                 :       // Treat 0* as 1* in quirks mode (bug 40383)
         318               0 :       if (isInQuirks) {
         319               0 :         if ((eFramesetUnit_Relative == specs[i].mUnit) &&
         320               0 :           (0 == specs[i].mValue)) {
         321               0 :           specs[i].mValue = 1;
         322                 :         }
         323                 :       }
         324                 :
         325                 :       // Catch zero and negative frame sizes for Nav compatibility
         326                 :       // Nav resized absolute and relative frames to "1" and
         327                 :       // percent frames to an even percentage of the width
         328                 :       //
         329                 :       //if (isInQuirks && (specs[i].mValue <= 0)) {
         330                 :       //  if (eFramesetUnit_Percent == specs[i].mUnit) {
         331                 :       //    specs[i].mValue = 100 / count;
         332                 :       //  } else {
         333                 :       //    specs[i].mValue = 1;
         334                 :       //  }
         335                 :       //} else {
         336                 :
         337                 :       // In standards mode, just set negative sizes to zero
         338               0 :       if (specs[i].mValue < 0) {
         339               0 :         specs[i].mValue = 0;
         340                 :       }
         341               0 :       start = end + 1;
         342                 :     }
         343                 :   }
         344                 :
         345               0 :   aNumSpecs = count;
         346                 :   // Transfer ownership to caller here
         347               0 :   *aSpecs = specs;
         348                 :
         349               0 :   return NS_OK;
         350                 : }
         351                 :
         352                 : // Event listener stuff
         353                 : // FIXME (https://bugzilla.mozilla.org/show_bug.cgi?id=431767)
         354                 : // nsDocument::GetInnerWindow can return an outer window in some
         355                 : // cases.  We don't want to stick an event listener on an outer
         356                 : // window, so bail if it does.  See also similar code in
         357                 : // nsGenericHTMLElement::GetEventListenerManagerForAttr.
         358                 : #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the shim */
         359                 : #define FORWARDED_EVENT(name_, id_, type_, struct_)                   \
         360                 :   NS_IMETHODIMP nsHTMLFrameSetElement::GetOn##name_(JSContext *cx,    \
         361                 :                                                jsval *vp) {           \
         362                 :     /* XXXbz note to self: add tests for this! */                     \
         363                 :     nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();             \
         364                 :     if (win && win->IsInnerWindow()) {                                \
         365                 :       nsCOMPtr<nsIInlineEventHandlers> ev = do_QueryInterface(win);   \
         366                 :       return ev->GetOn##name_(cx, vp);                                \
         367                 :     }                                                                 \
         368                 :     *vp = JSVAL_NULL;                                                 \
         369                 :     return NS_OK;                                                     \
         370                 :   }                                                                   \
         371                 :   NS_IMETHODIMP nsHTMLFrameSetElement::SetOn##name_(JSContext *cx,    \
         372                 :                                                const jsval &v) {      \
         373                 :     nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();             \
         374                 :     if (win && win->IsInnerWindow()) {                                \
         375                 :       nsCOMPtr<nsIInlineEventHandlers> ev = do_QueryInterface(win);   \
         376                 :       return ev->SetOn##name_(cx, v);                                 \
         377                 :     }                                                                 \
         378                 :     return NS_OK;                                                     \
         379                 :   }
         380                 : #define WINDOW_EVENT(name_, id_, type_, struct_)                      \
         381                 :   NS_IMETHODIMP nsHTMLFrameSetElement::GetOn##name_(JSContext *cx,    \
         382                 :                                                     jsval *vp) {      \
         383                 :     /* XXXbz note to self: add tests for this! */                     \
         384                 :     nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();             \
         385                 :     if (win && win->IsInnerWindow()) {                                \
         386                 :       return win->GetOn##name_(cx, vp);                               \
         387                 :     }                                                                 \
         388                 :     *vp = JSVAL_NULL;                                                 \
         389                 :     return NS_OK;                                                     \
         390                 :   }                                                                   \
         391                 :   NS_IMETHODIMP nsHTMLFrameSetElement::SetOn##name_(JSContext *cx,    \
         392                 :                                                     const jsval &v) { \
         393                 :     nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow();             \
         394                 :     if (win && win->IsInnerWindow()) {                                \
         395                 :       return win->SetOn##name_(cx, v);                                \
         396                 :     }                                                                 \
         397                 :     return NS_OK;                                                     \
         398                 :   }
         399                 : #include "nsEventNameList.h"
         400                 : #undef WINDOW_EVENT
         401                 : #undef FORWARDED_EVENT
         402                 : #undef EVENT

Generated by: LCOV version 1.7