LCOV - code coverage report
Current view: directory - editor/libeditor/html - nsHTMLCSSUtils.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 593 0 0.0 %
Date: 2012-06-02 Functions: 42 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.org 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                 :  *   Original Author: Daniel Glazman <glazman@netscape.com>
      24                 :  *   Ms2ger <ms2ger@gmail.com>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #include "nsHTMLEditor.h"
      41                 : #include "nsCOMPtr.h"
      42                 : #include "nsHTMLEditUtils.h"
      43                 : #include "nsEditProperty.h"
      44                 : #include "ChangeCSSInlineStyleTxn.h"
      45                 : #include "nsIDOMElement.h"
      46                 : #include "nsIDOMElementCSSInlineStyle.h"
      47                 : #include "nsIDOMDocument.h"
      48                 : #include "nsIContent.h"
      49                 : #include "nsIAtom.h"
      50                 : #include "nsTextEditUtils.h"
      51                 : #include "nsReadableUtils.h"
      52                 : #include "nsUnicharUtils.h"
      53                 : #include "nsHTMLCSSUtils.h"
      54                 : #include "nsColor.h"
      55                 : #include "nsAttrName.h"
      56                 : #include "nsAutoPtr.h"
      57                 : #include "mozilla/Preferences.h"
      58                 : 
      59                 : using namespace mozilla;
      60                 : 
      61                 : static
      62               0 : void ProcessBValue(const nsAString * aInputString, nsAString & aOutputString,
      63                 :                    const char * aDefaultValueString,
      64                 :                    const char * aPrependString, const char* aAppendString)
      65                 : {
      66               0 :   if (aInputString && aInputString->EqualsLiteral("-moz-editor-invert-value")) {
      67               0 :       aOutputString.AssignLiteral("normal");
      68                 :   }
      69                 :   else {
      70               0 :     aOutputString.AssignLiteral("bold");
      71                 :   }
      72               0 : }
      73                 : 
      74                 : static
      75               0 : void ProcessDefaultValue(const nsAString * aInputString, nsAString & aOutputString,
      76                 :                          const char * aDefaultValueString,
      77                 :                          const char * aPrependString, const char* aAppendString)
      78                 : {
      79               0 :   CopyASCIItoUTF16(aDefaultValueString, aOutputString);
      80               0 : }
      81                 : 
      82                 : static
      83               0 : void ProcessSameValue(const nsAString * aInputString, nsAString & aOutputString,
      84                 :                       const char * aDefaultValueString,
      85                 :                       const char * aPrependString, const char* aAppendString)
      86                 : {
      87               0 :   if (aInputString) {
      88               0 :     aOutputString.Assign(*aInputString);
      89                 :   }
      90                 :   else
      91               0 :     aOutputString.Truncate();
      92               0 : }
      93                 : 
      94                 : static
      95               0 : void ProcessExtendedValue(const nsAString * aInputString, nsAString & aOutputString,
      96                 :                           const char * aDefaultValueString,
      97                 :                           const char * aPrependString, const char* aAppendString)
      98                 : {
      99               0 :   aOutputString.Truncate();
     100               0 :   if (aInputString) {
     101               0 :     if (aPrependString) {
     102               0 :       AppendASCIItoUTF16(aPrependString, aOutputString);
     103                 :     }
     104               0 :     aOutputString.Append(*aInputString);
     105               0 :     if (aAppendString) {
     106               0 :       AppendASCIItoUTF16(aAppendString, aOutputString);
     107                 :     }
     108                 :   }
     109               0 : }
     110                 : 
     111                 : static
     112               0 : void ProcessLengthValue(const nsAString * aInputString, nsAString & aOutputString,
     113                 :                         const char * aDefaultValueString,
     114                 :                         const char * aPrependString, const char* aAppendString)
     115                 : {
     116               0 :   aOutputString.Truncate();
     117               0 :   if (aInputString) {
     118               0 :     aOutputString.Append(*aInputString);
     119               0 :     if (-1 == aOutputString.FindChar(PRUnichar('%'))) {
     120               0 :       aOutputString.AppendLiteral("px");
     121                 :     }
     122                 :   }
     123               0 : }
     124                 : 
     125                 : static
     126               0 : void ProcessListStyleTypeValue(const nsAString * aInputString, nsAString & aOutputString,
     127                 :                                const char * aDefaultValueString,
     128                 :                                const char * aPrependString, const char* aAppendString)
     129                 : {
     130               0 :   aOutputString.Truncate();
     131               0 :   if (aInputString) {
     132               0 :     if (aInputString->EqualsLiteral("1")) {
     133               0 :       aOutputString.AppendLiteral("decimal");
     134                 :     }
     135               0 :     else if (aInputString->EqualsLiteral("a")) {
     136               0 :       aOutputString.AppendLiteral("lower-alpha");
     137                 :     }
     138               0 :     else if (aInputString->EqualsLiteral("A")) {
     139               0 :       aOutputString.AppendLiteral("upper-alpha");
     140                 :     }
     141               0 :     else if (aInputString->EqualsLiteral("i")) {
     142               0 :       aOutputString.AppendLiteral("lower-roman");
     143                 :     }
     144               0 :     else if (aInputString->EqualsLiteral("I")) {
     145               0 :       aOutputString.AppendLiteral("upper-roman");
     146                 :     }
     147               0 :     else if (aInputString->EqualsLiteral("square")
     148               0 :              || aInputString->EqualsLiteral("circle")
     149               0 :              || aInputString->EqualsLiteral("disc")) {
     150               0 :       aOutputString.Append(*aInputString);
     151                 :     }
     152                 :   }
     153               0 : }
     154                 : 
     155                 : static
     156               0 : void ProcessMarginLeftValue(const nsAString * aInputString, nsAString & aOutputString,
     157                 :                             const char * aDefaultValueString,
     158                 :                             const char * aPrependString, const char* aAppendString)
     159                 : {
     160               0 :   aOutputString.Truncate();
     161               0 :   if (aInputString) {
     162               0 :     if (aInputString->EqualsLiteral("center") ||
     163               0 :         aInputString->EqualsLiteral("-moz-center")) {
     164               0 :       aOutputString.AppendLiteral("auto"); 
     165                 :     }
     166               0 :     else if (aInputString->EqualsLiteral("right") ||
     167               0 :              aInputString->EqualsLiteral("-moz-right")) {
     168               0 :       aOutputString.AppendLiteral("auto"); 
     169                 :     }
     170                 :     else {
     171               0 :       aOutputString.AppendLiteral("0px"); 
     172                 :     }
     173                 :   }
     174               0 : }
     175                 : 
     176                 : static
     177               0 : void ProcessMarginRightValue(const nsAString * aInputString, nsAString & aOutputString,
     178                 :                              const char * aDefaultValueString,
     179                 :                              const char * aPrependString, const char* aAppendString)
     180                 : {
     181               0 :   aOutputString.Truncate();
     182               0 :   if (aInputString) {
     183               0 :     if (aInputString->EqualsLiteral("center") ||
     184               0 :         aInputString->EqualsLiteral("-moz-center")) {
     185               0 :       aOutputString.AppendLiteral("auto"); 
     186                 :     }
     187               0 :     else if (aInputString->EqualsLiteral("left") ||
     188               0 :              aInputString->EqualsLiteral("-moz-left")) {
     189               0 :       aOutputString.AppendLiteral("auto"); 
     190                 :     }
     191                 :     else {
     192               0 :       aOutputString.AppendLiteral("0px"); 
     193                 :     }
     194                 :   }
     195               0 : }
     196                 : 
     197                 : const nsHTMLCSSUtils::CSSEquivTable boldEquivTable[] = {
     198                 :   { nsHTMLCSSUtils::eCSSEditableProperty_font_weight, ProcessBValue, nsnull, nsnull, nsnull, true, false },
     199                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     200                 : };
     201                 : 
     202                 : const nsHTMLCSSUtils::CSSEquivTable italicEquivTable[] = {
     203                 :   { nsHTMLCSSUtils::eCSSEditableProperty_font_style, ProcessDefaultValue, "italic", nsnull, nsnull, true, false },
     204                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     205                 : };
     206                 : 
     207                 : const nsHTMLCSSUtils::CSSEquivTable underlineEquivTable[] = {
     208                 :   { nsHTMLCSSUtils::eCSSEditableProperty_text_decoration, ProcessDefaultValue, "underline", nsnull, nsnull, true, false },
     209                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     210                 : };
     211                 : 
     212                 : const nsHTMLCSSUtils::CSSEquivTable strikeEquivTable[] = {
     213                 :   { nsHTMLCSSUtils::eCSSEditableProperty_text_decoration, ProcessDefaultValue, "line-through", nsnull, nsnull, true, false },
     214                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     215                 : };
     216                 : 
     217                 : const nsHTMLCSSUtils::CSSEquivTable ttEquivTable[] = {
     218                 :   { nsHTMLCSSUtils::eCSSEditableProperty_font_family, ProcessDefaultValue, "monospace", nsnull, nsnull, true, false },
     219                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     220                 : };
     221                 : 
     222                 : const nsHTMLCSSUtils::CSSEquivTable fontColorEquivTable[] = {
     223                 :   { nsHTMLCSSUtils::eCSSEditableProperty_color, ProcessSameValue, nsnull, nsnull, nsnull, true, false },
     224                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     225                 : };
     226                 : 
     227                 : const nsHTMLCSSUtils::CSSEquivTable fontFaceEquivTable[] = {
     228                 :   { nsHTMLCSSUtils::eCSSEditableProperty_font_family, ProcessSameValue, nsnull, nsnull, nsnull, true, false },
     229                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     230                 : };
     231                 : 
     232                 : const nsHTMLCSSUtils::CSSEquivTable bgcolorEquivTable[] = {
     233                 :   { nsHTMLCSSUtils::eCSSEditableProperty_background_color, ProcessSameValue, nsnull, nsnull, nsnull, true, false },
     234                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     235                 : };
     236                 : 
     237                 : const nsHTMLCSSUtils::CSSEquivTable backgroundImageEquivTable[] = {
     238                 :   { nsHTMLCSSUtils::eCSSEditableProperty_background_image, ProcessExtendedValue, nsnull, "url(", ")", true, true },
     239                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     240                 : };
     241                 : 
     242                 : const nsHTMLCSSUtils::CSSEquivTable textColorEquivTable[] = {
     243                 :   { nsHTMLCSSUtils::eCSSEditableProperty_color, ProcessSameValue, nsnull, nsnull, nsnull, true, false },
     244                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     245                 : };
     246                 : 
     247                 : const nsHTMLCSSUtils::CSSEquivTable borderEquivTable[] = {
     248                 :   { nsHTMLCSSUtils::eCSSEditableProperty_border, ProcessExtendedValue, nsnull, nsnull, "px solid", true, false },
     249                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     250                 : };
     251                 : 
     252                 : const nsHTMLCSSUtils::CSSEquivTable textAlignEquivTable[] = {
     253                 :   { nsHTMLCSSUtils::eCSSEditableProperty_text_align, ProcessSameValue, nsnull, nsnull, nsnull, true, false },
     254                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     255                 : };
     256                 : 
     257                 : const nsHTMLCSSUtils::CSSEquivTable captionAlignEquivTable[] = {
     258                 :   { nsHTMLCSSUtils::eCSSEditableProperty_caption_side, ProcessSameValue, nsnull, nsnull, nsnull, true, false },
     259                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     260                 : };
     261                 : 
     262                 : const nsHTMLCSSUtils::CSSEquivTable verticalAlignEquivTable[] = {
     263                 :   { nsHTMLCSSUtils::eCSSEditableProperty_vertical_align, ProcessSameValue, nsnull, nsnull, nsnull, true, false },
     264                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     265                 : };
     266                 : 
     267                 : const nsHTMLCSSUtils::CSSEquivTable nowrapEquivTable[] = {
     268                 :   { nsHTMLCSSUtils::eCSSEditableProperty_whitespace, ProcessDefaultValue, "nowrap", nsnull, nsnull, true, false },
     269                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     270                 : };
     271                 : 
     272                 : const nsHTMLCSSUtils::CSSEquivTable widthEquivTable[] = {
     273                 :   { nsHTMLCSSUtils::eCSSEditableProperty_width, ProcessLengthValue, nsnull, nsnull, nsnull, true, false },
     274                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     275                 : };
     276                 : 
     277                 : const nsHTMLCSSUtils::CSSEquivTable heightEquivTable[] = {
     278                 :   { nsHTMLCSSUtils::eCSSEditableProperty_height, ProcessLengthValue, nsnull, nsnull, nsnull, true, false },
     279                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     280                 : };
     281                 : 
     282                 : const nsHTMLCSSUtils::CSSEquivTable listStyleTypeEquivTable[] = {
     283                 :   { nsHTMLCSSUtils::eCSSEditableProperty_list_style_type, ProcessListStyleTypeValue, nsnull, nsnull, nsnull, true, true },
     284                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     285                 : };
     286                 : 
     287                 : const nsHTMLCSSUtils::CSSEquivTable tableAlignEquivTable[] = {
     288                 :   { nsHTMLCSSUtils::eCSSEditableProperty_text_align, ProcessDefaultValue, "left", nsnull, nsnull, false, false },
     289                 :   { nsHTMLCSSUtils::eCSSEditableProperty_margin_left, ProcessMarginLeftValue, nsnull, nsnull, nsnull, true, false },
     290                 :   { nsHTMLCSSUtils::eCSSEditableProperty_margin_right, ProcessMarginRightValue, nsnull, nsnull, nsnull, true, false },
     291                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     292                 : };
     293                 : 
     294                 : const nsHTMLCSSUtils::CSSEquivTable hrAlignEquivTable[] = {
     295                 :   { nsHTMLCSSUtils::eCSSEditableProperty_margin_left, ProcessMarginLeftValue, nsnull, nsnull, nsnull, true, false },
     296                 :   { nsHTMLCSSUtils::eCSSEditableProperty_margin_right, ProcessMarginRightValue, nsnull, nsnull, nsnull, true, false },
     297                 :   { nsHTMLCSSUtils::eCSSEditableProperty_NONE, 0 }
     298                 : };
     299                 : 
     300               0 : nsHTMLCSSUtils::nsHTMLCSSUtils(nsHTMLEditor* aEditor)
     301                 :   : mHTMLEditor(aEditor)
     302               0 :   , mIsCSSPrefChecked(false)
     303                 : {
     304                 :   // let's retrieve the value of the "CSS editing" pref
     305               0 :   mIsCSSPrefChecked = Preferences::GetBool("editor.use_css", mIsCSSPrefChecked);
     306               0 : }
     307                 : 
     308               0 : nsHTMLCSSUtils::~nsHTMLCSSUtils()
     309                 : {
     310               0 : }
     311                 : 
     312                 : // Answers true if we have some CSS equivalence for the HTML style defined
     313                 : // by aProperty and/or aAttribute for the node aNode
     314                 : bool
     315               0 : nsHTMLCSSUtils::IsCSSEditableProperty(nsIDOMNode * aNode,
     316                 :                                       nsIAtom * aProperty,
     317                 :                                       const nsAString * aAttribute)
     318                 : {
     319               0 :   NS_ASSERTION(aNode, "Shouldn't you pass aNode? - Bug 214025");
     320                 : 
     321               0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
     322               0 :   NS_ENSURE_TRUE(content, false);
     323               0 :   return IsCSSEditableProperty(content, aProperty, aAttribute);
     324                 : }
     325                 : 
     326                 : bool
     327               0 : nsHTMLCSSUtils::IsCSSEditableProperty(nsIContent* aNode,
     328                 :                                       nsIAtom* aProperty,
     329                 :                                       const nsAString* aAttribute)
     330                 : {
     331               0 :   MOZ_ASSERT(aNode);
     332                 : 
     333               0 :   nsIContent* content = aNode;
     334                 :   // we need an element node here
     335               0 :   if (content->NodeType() == nsIDOMNode::TEXT_NODE) {
     336               0 :     content = content->GetParent();
     337               0 :     NS_ENSURE_TRUE(content, false);
     338                 :   }
     339                 : 
     340               0 :   nsIAtom *tagName = content->Tag();
     341                 :   // brade: shouldn't some of the above go below the next block?
     342                 : 
     343                 :   // html inline styles B I TT U STRIKE and COLOR/FACE on FONT
     344               0 :   if (nsEditProperty::b == aProperty
     345                 :       || nsEditProperty::i == aProperty
     346                 :       || nsEditProperty::tt == aProperty
     347                 :       || nsEditProperty::u == aProperty
     348                 :       || nsEditProperty::strike == aProperty
     349                 :       || ((nsEditProperty::font == aProperty) && aAttribute &&
     350               0 :            (aAttribute->EqualsLiteral("color") ||
     351               0 :             aAttribute->EqualsLiteral("face")))) {
     352               0 :     return true;
     353                 :   }
     354                 : 
     355                 :   // ALIGN attribute on elements supporting it
     356               0 :   if (aAttribute && (aAttribute->EqualsLiteral("align")) &&
     357                 :       (nsEditProperty::div == tagName
     358                 :        || nsEditProperty::p   == tagName
     359                 :        || nsEditProperty::h1  == tagName
     360                 :        || nsEditProperty::h2  == tagName
     361                 :        || nsEditProperty::h3  == tagName
     362                 :        || nsEditProperty::h4  == tagName
     363                 :        || nsEditProperty::h5  == tagName
     364                 :        || nsEditProperty::h6  == tagName
     365                 :        || nsEditProperty::td  == tagName
     366                 :        || nsEditProperty::th  == tagName
     367                 :        || nsEditProperty::table  == tagName
     368                 :        || nsEditProperty::hr  == tagName
     369                 :        // brade: for the above, why not use nsHTMLEditUtils::SupportsAlignAttr
     370                 :        // brade: but it also checks for tbody, tfoot, thead
     371                 :        // Let's add the following elements here even if ALIGN has not
     372                 :        // the same meaning for them
     373                 :        || nsEditProperty::legend  == tagName
     374                 :        || nsEditProperty::caption == tagName)) {
     375               0 :     return true;
     376                 :   }
     377                 : 
     378               0 :   if (aAttribute && (aAttribute->EqualsLiteral("valign")) &&
     379                 :       (nsEditProperty::col == tagName
     380                 :        || nsEditProperty::colgroup   == tagName
     381                 :        || nsEditProperty::tbody  == tagName
     382                 :        || nsEditProperty::td  == tagName
     383                 :        || nsEditProperty::th  == tagName
     384                 :        || nsEditProperty::tfoot  == tagName
     385                 :        || nsEditProperty::thead  == tagName
     386                 :        || nsEditProperty::tr  == tagName)) {
     387               0 :     return true;
     388                 :   }
     389                 : 
     390                 :   // attributes TEXT, BACKGROUND and BGCOLOR on BODY
     391               0 :   if (aAttribute && (nsEditProperty::body == tagName) &&
     392               0 :       (aAttribute->EqualsLiteral("text")
     393               0 :        || aAttribute->EqualsLiteral("background")
     394               0 :        || aAttribute->EqualsLiteral("bgcolor"))) {
     395               0 :     return true;
     396                 :   }
     397                 : 
     398                 :   // attribute BGCOLOR on other elements
     399               0 :   if (aAttribute && aAttribute->EqualsLiteral("bgcolor")) {
     400               0 :     return true;
     401                 :   }
     402                 : 
     403                 :   // attributes HEIGHT, WIDTH and NOWRAP on TD and TH
     404               0 :   if (aAttribute && ((nsEditProperty::td == tagName)
     405                 :                       || (nsEditProperty::th == tagName)) &&
     406               0 :       (aAttribute->EqualsLiteral("height")
     407               0 :        || aAttribute->EqualsLiteral("width")
     408               0 :        || aAttribute->EqualsLiteral("nowrap"))) {
     409               0 :     return true;
     410                 :   }
     411                 : 
     412                 :   // attributes HEIGHT and WIDTH on TABLE
     413               0 :   if (aAttribute && (nsEditProperty::table == tagName) &&
     414               0 :       (aAttribute->EqualsLiteral("height")
     415               0 :        || aAttribute->EqualsLiteral("width"))) {
     416               0 :     return true;
     417                 :   }
     418                 : 
     419                 :   // attributes SIZE and WIDTH on HR
     420               0 :   if (aAttribute && (nsEditProperty::hr == tagName) &&
     421               0 :       (aAttribute->EqualsLiteral("size")
     422               0 :        || aAttribute->EqualsLiteral("width"))) {
     423               0 :     return true;
     424                 :   }
     425                 : 
     426                 :   // attribute TYPE on OL UL LI
     427               0 :   if (aAttribute && (nsEditProperty::ol == tagName
     428                 :                      || nsEditProperty::ul == tagName
     429                 :                      || nsEditProperty::li == tagName) &&
     430               0 :       aAttribute->EqualsLiteral("type")) {
     431               0 :     return true;
     432                 :   }
     433                 : 
     434               0 :   if (aAttribute && nsEditProperty::img == tagName &&
     435               0 :       (aAttribute->EqualsLiteral("border")
     436               0 :        || aAttribute->EqualsLiteral("width")
     437               0 :        || aAttribute->EqualsLiteral("height"))) {
     438               0 :     return true;
     439                 :   }
     440                 : 
     441                 :   // other elements that we can align using CSS even if they
     442                 :   // can't carry the html ALIGN attribute
     443               0 :   if (aAttribute && aAttribute->EqualsLiteral("align") &&
     444                 :       (nsEditProperty::ul == tagName
     445                 :        || nsEditProperty::ol == tagName
     446                 :        || nsEditProperty::dl == tagName
     447                 :        || nsEditProperty::li == tagName
     448                 :        || nsEditProperty::dd == tagName
     449                 :        || nsEditProperty::dt == tagName
     450                 :        || nsEditProperty::address == tagName
     451                 :        || nsEditProperty::pre == tagName
     452                 :        || nsEditProperty::ul == tagName)) {
     453               0 :     return true;
     454                 :   }
     455                 : 
     456               0 :   return false;
     457                 : }
     458                 : 
     459                 : // the lowest level above the transaction; adds the css declaration "aProperty : aValue" to
     460                 : // the inline styles carried by aElement
     461                 : nsresult
     462               0 : nsHTMLCSSUtils::SetCSSProperty(nsIDOMElement *aElement, nsIAtom * aProperty, const nsAString & aValue,
     463                 :                                bool aSuppressTransaction)
     464                 : {
     465               0 :   nsRefPtr<ChangeCSSInlineStyleTxn> txn;
     466                 :   nsresult result = CreateCSSPropertyTxn(aElement, aProperty, aValue,
     467               0 :                                          getter_AddRefs(txn), false);
     468               0 :   if (NS_SUCCEEDED(result))  {
     469               0 :     if (aSuppressTransaction) {
     470               0 :       result = txn->DoTransaction();
     471                 :     }
     472                 :     else {
     473               0 :       result = mHTMLEditor->DoTransaction(txn);
     474                 :     }
     475                 :   }
     476               0 :   return result;
     477                 : }
     478                 : 
     479                 : nsresult
     480               0 : nsHTMLCSSUtils::SetCSSPropertyPixels(nsIDOMElement *aElement,
     481                 :                                      nsIAtom *aProperty,
     482                 :                                      PRInt32 aIntValue,
     483                 :                                      bool aSuppressTransaction)
     484                 : {
     485               0 :   nsAutoString s;
     486               0 :   s.AppendInt(aIntValue);
     487               0 :   return SetCSSProperty(aElement, aProperty, s + NS_LITERAL_STRING("px"),
     488               0 :                         aSuppressTransaction);
     489                 : }
     490                 : 
     491                 : // the lowest level above the transaction; removes the value aValue from the list of values
     492                 : // specified for the CSS property aProperty, or totally remove the declaration if this
     493                 : // property accepts only one value
     494                 : nsresult
     495               0 : nsHTMLCSSUtils::RemoveCSSProperty(nsIDOMElement *aElement, nsIAtom * aProperty, const nsAString & aValue,
     496                 :                                   bool aSuppressTransaction)
     497                 : {
     498               0 :   nsRefPtr<ChangeCSSInlineStyleTxn> txn;
     499                 :   nsresult result = CreateCSSPropertyTxn(aElement, aProperty, aValue,
     500               0 :                                          getter_AddRefs(txn), true);
     501               0 :   if (NS_SUCCEEDED(result))  {
     502               0 :     if (aSuppressTransaction) {
     503               0 :       result = txn->DoTransaction();
     504                 :     }
     505                 :     else {
     506               0 :       result = mHTMLEditor->DoTransaction(txn);
     507                 :     }
     508                 :   }
     509               0 :   return result;
     510                 : }
     511                 : 
     512                 : nsresult 
     513               0 : nsHTMLCSSUtils::CreateCSSPropertyTxn(nsIDOMElement *aElement, 
     514                 :                                      nsIAtom * aAttribute,
     515                 :                                      const nsAString& aValue,
     516                 :                                      ChangeCSSInlineStyleTxn ** aTxn,
     517                 :                                      bool aRemoveProperty)
     518                 : {
     519               0 :   NS_ENSURE_TRUE(aElement, NS_ERROR_NULL_POINTER);
     520                 : 
     521               0 :   *aTxn = new ChangeCSSInlineStyleTxn();
     522               0 :   NS_ENSURE_TRUE(*aTxn, NS_ERROR_OUT_OF_MEMORY);
     523               0 :   NS_ADDREF(*aTxn);
     524               0 :   return (*aTxn)->Init(mHTMLEditor, aElement, aAttribute, aValue, aRemoveProperty);
     525                 : }
     526                 : 
     527                 : nsresult
     528               0 : nsHTMLCSSUtils::GetSpecifiedProperty(nsIDOMNode *aNode, nsIAtom *aProperty,
     529                 :                                      nsAString & aValue)
     530                 : {
     531               0 :   return GetCSSInlinePropertyBase(aNode, aProperty, aValue, nsnull, SPECIFIED_STYLE_TYPE);
     532                 : }
     533                 : 
     534                 : nsresult
     535               0 : nsHTMLCSSUtils::GetComputedProperty(nsIDOMNode *aNode, nsIAtom *aProperty,
     536                 :                                     nsAString & aValue)
     537                 : {
     538               0 :   nsCOMPtr<nsIDOMWindow> window;
     539               0 :   nsresult res = GetDefaultViewCSS(aNode, getter_AddRefs(window));
     540               0 :   NS_ENSURE_SUCCESS(res, res);
     541                 : 
     542               0 :   return GetCSSInlinePropertyBase(aNode, aProperty, aValue, window, COMPUTED_STYLE_TYPE);
     543                 : }
     544                 : 
     545                 : nsresult
     546               0 : nsHTMLCSSUtils::GetCSSInlinePropertyBase(nsINode* aNode, nsIAtom* aProperty,
     547                 :                                          nsAString& aValue,
     548                 :                                          nsIDOMWindow* aWindow,
     549                 :                                          PRUint8 aStyleType)
     550                 : {
     551               0 :   nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode);
     552               0 :   return GetCSSInlinePropertyBase(node, aProperty, aValue, aWindow, aStyleType);
     553                 : }
     554                 : 
     555                 : nsresult
     556               0 : nsHTMLCSSUtils::GetCSSInlinePropertyBase(nsIDOMNode *aNode, nsIAtom *aProperty,
     557                 :                                          nsAString& aValue,
     558                 :                                          nsIDOMWindow* aWindow,
     559                 :                                          PRUint8 aStyleType)
     560                 : {
     561               0 :   aValue.Truncate();
     562               0 :   NS_ENSURE_TRUE(aProperty, NS_ERROR_NULL_POINTER);
     563                 : 
     564               0 :   nsCOMPtr<nsIDOMElement> element = GetElementContainerOrSelf(aNode);
     565               0 :   NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
     566                 : 
     567               0 :   switch (aStyleType) {
     568                 :     case COMPUTED_STYLE_TYPE:
     569               0 :       if (element && aWindow) {
     570               0 :         nsAutoString value, propString;
     571               0 :         nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
     572               0 :         aProperty->ToString(propString);
     573                 :         // Get the all the computed css styles attached to the element node
     574               0 :         nsresult res = aWindow->GetComputedStyle(element, EmptyString(), getter_AddRefs(cssDecl));
     575               0 :         if (NS_FAILED(res) || !cssDecl)
     576               0 :           return res;
     577                 :         // from these declarations, get the one we want and that one only
     578               0 :         res = cssDecl->GetPropertyValue(propString, value);
     579               0 :         NS_ENSURE_SUCCESS(res, res);
     580               0 :         aValue.Assign(value);
     581                 :       }
     582               0 :       break;
     583                 :     case SPECIFIED_STYLE_TYPE:
     584               0 :       if (element) {
     585               0 :         nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
     586                 :         PRUint32 length;
     587               0 :         nsresult res = GetInlineStyles(element, getter_AddRefs(cssDecl), &length);
     588               0 :         if (NS_FAILED(res) || !cssDecl) return res;
     589               0 :         nsAutoString value, propString;
     590               0 :         aProperty->ToString(propString);
     591               0 :         res = cssDecl->GetPropertyValue(propString, value);
     592               0 :         NS_ENSURE_SUCCESS(res, res);
     593               0 :         aValue.Assign(value);
     594                 :       }
     595               0 :       break;
     596                 :   }
     597               0 :   return NS_OK;
     598                 : }
     599                 : 
     600                 : nsresult
     601               0 : nsHTMLCSSUtils::GetDefaultViewCSS(nsIDOMNode *aNode, nsIDOMWindow **aViewCSS)
     602                 : {
     603               0 :   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
     604               0 :   NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
     605               0 :   return GetDefaultViewCSS(node, aViewCSS);
     606                 : }
     607                 : 
     608                 : nsresult
     609               0 : nsHTMLCSSUtils::GetDefaultViewCSS(nsINode* aNode, nsIDOMWindow** aViewCSS)
     610                 : {
     611               0 :   MOZ_ASSERT(aNode);
     612               0 :   dom::Element* element = GetElementContainerOrSelf(aNode);
     613               0 :   NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
     614                 : 
     615               0 :   nsCOMPtr<nsIDOMWindow> window = element->OwnerDoc()->GetWindow();
     616               0 :   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
     617               0 :   window.forget(aViewCSS);
     618               0 :   return NS_OK;
     619                 : }
     620                 : 
     621                 : // remove the CSS style "aProperty : aPropertyValue" and possibly remove the whole node
     622                 : // if it is a span and if its only attribute is _moz_dirty
     623                 : nsresult
     624               0 : nsHTMLCSSUtils::RemoveCSSInlineStyle(nsIDOMNode *aNode, nsIAtom *aProperty, const nsAString & aPropertyValue)
     625                 : {
     626               0 :   nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(aNode);
     627                 : 
     628                 :   // remove the property from the style attribute
     629               0 :   nsresult res = RemoveCSSProperty(elem, aProperty, aPropertyValue, false);
     630               0 :   NS_ENSURE_SUCCESS(res, res);
     631                 : 
     632               0 :   nsCOMPtr<dom::Element> element = do_QueryInterface(aNode);
     633               0 :   if (!element || !element->IsHTML(nsGkAtoms::span) ||
     634               0 :       nsHTMLEditor::HasAttributes(element)) {
     635               0 :     return NS_OK;
     636                 :   }
     637                 : 
     638               0 :   return mHTMLEditor->RemoveContainer(aNode);
     639                 : }
     640                 : 
     641                 : // Answers true is the property can be removed by setting a "none" CSS value
     642                 : // on a node
     643                 : bool
     644               0 : nsHTMLCSSUtils::IsCSSInvertable(nsIAtom *aProperty, const nsAString *aAttribute)
     645                 : {
     646               0 :   return bool(nsEditProperty::b == aProperty);
     647                 : }
     648                 : 
     649                 : // Get the default browser background color if we need it for GetCSSBackgroundColorState
     650                 : void
     651               0 : nsHTMLCSSUtils::GetDefaultBackgroundColor(nsAString & aColor)
     652                 : {
     653               0 :   if (Preferences::GetBool("editor.use_custom_colors", false)) {
     654               0 :     nsresult rv = Preferences::GetString("editor.background_color", &aColor);
     655                 :     // XXX Why don't you validate the pref value?
     656               0 :     if (NS_FAILED(rv)) {
     657               0 :       NS_WARNING("failed to get editor.background_color");
     658               0 :       aColor.AssignLiteral("#ffffff");  // Default to white
     659                 :     }
     660               0 :     return;
     661                 :   }
     662                 : 
     663               0 :   if (Preferences::GetBool("browser.display.use_system_colors", false)) {
     664               0 :     return;
     665                 :   }
     666                 : 
     667                 :   nsresult rv =
     668               0 :     Preferences::GetString("browser.display.background_color", &aColor);
     669                 :   // XXX Why don't you validate the pref value?
     670               0 :   if (NS_FAILED(rv)) {
     671               0 :     NS_WARNING("failed to get browser.display.background_color");
     672               0 :     aColor.AssignLiteral("#ffffff");  // Default to white
     673                 :   }
     674                 : }
     675                 : 
     676                 : // Get the default length unit used for CSS Indent/Outdent
     677                 : void
     678               0 : nsHTMLCSSUtils::GetDefaultLengthUnit(nsAString & aLengthUnit)
     679                 : {
     680                 :   nsresult rv =
     681               0 :     Preferences::GetString("editor.css.default_length_unit", &aLengthUnit);
     682                 :   // XXX Why don't you validate the pref value?
     683               0 :   if (NS_FAILED(rv)) {
     684               0 :     aLengthUnit.AssignLiteral("px");
     685                 :   }
     686               0 : }
     687                 : 
     688                 : // Unfortunately, CSSStyleDeclaration::GetPropertyCSSValue is not yet implemented...
     689                 : // We need then a way to determine the number part and the unit from aString, aString
     690                 : // being the result of a GetPropertyValue query...
     691                 : void
     692               0 : nsHTMLCSSUtils::ParseLength(const nsAString & aString, float * aValue, nsIAtom ** aUnit)
     693                 : {
     694               0 :   nsAString::const_iterator iter;
     695               0 :   aString.BeginReading(iter);
     696                 : 
     697               0 :   float a = 10.0f , b = 1.0f, value = 0;
     698               0 :   PRInt8 sign = 1;
     699               0 :   PRInt32 i = 0, j = aString.Length();
     700                 :   PRUnichar c;
     701               0 :   bool floatingPointFound = false;
     702               0 :   c = *iter;
     703               0 :   if (PRUnichar('-') == c) { sign = -1; iter++; i++; }
     704               0 :   else if (PRUnichar('+') == c) { iter++; i++; }
     705               0 :   while (i < j) {
     706               0 :     c = *iter;
     707               0 :     if ((PRUnichar('0') == c) ||
     708                 :         (PRUnichar('1') == c) ||
     709                 :         (PRUnichar('2') == c) ||
     710                 :         (PRUnichar('3') == c) ||
     711                 :         (PRUnichar('4') == c) ||
     712                 :         (PRUnichar('5') == c) ||
     713                 :         (PRUnichar('6') == c) ||
     714                 :         (PRUnichar('7') == c) ||
     715                 :         (PRUnichar('8') == c) ||
     716                 :         (PRUnichar('9') == c)) {
     717               0 :       value = (value * a) + (b * (c - PRUnichar('0')));
     718               0 :       b = b / 10 * a;
     719                 :     }
     720               0 :     else if (!floatingPointFound && (PRUnichar('.') == c)) {
     721               0 :       floatingPointFound = true;
     722               0 :       a = 1.0f; b = 0.1f;
     723                 :     }
     724               0 :     else break;
     725               0 :     iter++;
     726               0 :     i++;
     727                 :   }
     728               0 :   *aValue = value * sign;
     729               0 :   *aUnit = NS_NewAtom(StringTail(aString, j-i)); 
     730               0 : }
     731                 : 
     732                 : void
     733               0 : nsHTMLCSSUtils::GetCSSPropertyAtom(nsCSSEditableProperty aProperty, nsIAtom ** aAtom)
     734                 : {
     735               0 :   *aAtom = nsnull;
     736               0 :   switch (aProperty) {
     737                 :     case eCSSEditableProperty_background_color:
     738               0 :       *aAtom = nsEditProperty::cssBackgroundColor;
     739               0 :       break;
     740                 :     case eCSSEditableProperty_background_image:
     741               0 :       *aAtom = nsEditProperty::cssBackgroundImage;
     742               0 :       break;
     743                 :     case eCSSEditableProperty_border:
     744               0 :       *aAtom = nsEditProperty::cssBorder;
     745               0 :       break;
     746                 :     case eCSSEditableProperty_caption_side:
     747               0 :       *aAtom = nsEditProperty::cssCaptionSide;
     748               0 :       break;
     749                 :     case eCSSEditableProperty_color:
     750               0 :       *aAtom = nsEditProperty::cssColor;
     751               0 :       break;
     752                 :     case eCSSEditableProperty_float:
     753               0 :       *aAtom = nsEditProperty::cssFloat;
     754               0 :       break;
     755                 :     case eCSSEditableProperty_font_family:
     756               0 :       *aAtom = nsEditProperty::cssFontFamily;
     757               0 :       break;
     758                 :     case eCSSEditableProperty_font_size:
     759               0 :       *aAtom = nsEditProperty::cssFontSize;
     760               0 :       break;
     761                 :     case eCSSEditableProperty_font_style:
     762               0 :       *aAtom = nsEditProperty::cssFontStyle;
     763               0 :       break;
     764                 :     case eCSSEditableProperty_font_weight:
     765               0 :       *aAtom = nsEditProperty::cssFontWeight;
     766               0 :       break;
     767                 :     case eCSSEditableProperty_height:
     768               0 :       *aAtom = nsEditProperty::cssHeight;
     769               0 :       break;
     770                 :     case eCSSEditableProperty_list_style_type:
     771               0 :       *aAtom = nsEditProperty::cssListStyleType;
     772               0 :       break;
     773                 :     case eCSSEditableProperty_margin_left:
     774               0 :       *aAtom = nsEditProperty::cssMarginLeft;
     775               0 :       break;
     776                 :     case eCSSEditableProperty_margin_right:
     777               0 :       *aAtom = nsEditProperty::cssMarginRight;
     778               0 :       break;
     779                 :     case eCSSEditableProperty_text_align:
     780               0 :       *aAtom = nsEditProperty::cssTextAlign;
     781               0 :       break;
     782                 :     case eCSSEditableProperty_text_decoration:
     783               0 :       *aAtom = nsEditProperty::cssTextDecoration;
     784               0 :       break;
     785                 :     case eCSSEditableProperty_vertical_align:
     786               0 :       *aAtom = nsEditProperty::cssVerticalAlign;
     787               0 :       break;
     788                 :     case eCSSEditableProperty_whitespace:
     789               0 :       *aAtom = nsEditProperty::cssWhitespace;
     790               0 :       break;
     791                 :     case eCSSEditableProperty_width:
     792               0 :       *aAtom = nsEditProperty::cssWidth;
     793               0 :       break;
     794                 :     case eCSSEditableProperty_NONE:
     795                 :       // intentionally empty
     796               0 :       break;
     797                 :   }
     798               0 : }
     799                 : 
     800                 : // Populate aProperty and aValueArray with the CSS declarations equivalent to the
     801                 : // value aValue according to the equivalence table aEquivTable
     802                 : void
     803               0 : nsHTMLCSSUtils::BuildCSSDeclarations(nsTArray<nsIAtom*> & aPropertyArray,
     804                 :                                      nsTArray<nsString> & aValueArray,
     805                 :                                      const CSSEquivTable * aEquivTable,
     806                 :                                      const nsAString * aValue,
     807                 :                                      bool aGetOrRemoveRequest)
     808                 : {
     809                 :   // clear arrays
     810               0 :   aPropertyArray.Clear();
     811               0 :   aValueArray.Clear();
     812                 : 
     813                 :   // if we have an input value, let's use it
     814               0 :   nsAutoString value, lowerCasedValue;
     815               0 :   if (aValue) {
     816               0 :     value.Assign(*aValue);
     817               0 :     lowerCasedValue.Assign(*aValue);
     818               0 :     ToLowerCase(lowerCasedValue);
     819                 :   }
     820                 : 
     821               0 :   PRInt8 index = 0;
     822               0 :   nsCSSEditableProperty cssProperty = aEquivTable[index].cssProperty;
     823               0 :   while (cssProperty) {
     824               0 :     if (!aGetOrRemoveRequest|| aEquivTable[index].gettable) {
     825               0 :       nsAutoString cssValue, cssPropertyString;
     826                 :       nsIAtom * cssPropertyAtom;
     827                 :       // find the equivalent css value for the index-th property in
     828                 :       // the equivalence table
     829               0 :       (*aEquivTable[index].processValueFunctor) ((!aGetOrRemoveRequest || aEquivTable[index].caseSensitiveValue) ? &value : &lowerCasedValue,
     830                 :                                                  cssValue,
     831               0 :                                                  aEquivTable[index].defaultValue,
     832               0 :                                                  aEquivTable[index].prependValue,
     833               0 :                                                  aEquivTable[index].appendValue);
     834               0 :       GetCSSPropertyAtom(cssProperty, &cssPropertyAtom);
     835               0 :       aPropertyArray.AppendElement(cssPropertyAtom);
     836               0 :       aValueArray.AppendElement(cssValue);
     837                 :     }
     838               0 :     index++;
     839               0 :     cssProperty = aEquivTable[index].cssProperty;
     840                 :   }
     841               0 : }
     842                 : 
     843                 : // Populate cssPropertyArray and cssValueArray with the declarations equivalent
     844                 : // to aHTMLProperty/aAttribute/aValue for the node aNode
     845                 : void
     846               0 : nsHTMLCSSUtils::GenerateCSSDeclarationsFromHTMLStyle(dom::Element* aElement,
     847                 :                                                      nsIAtom* aHTMLProperty,
     848                 :                                                      const nsAString* aAttribute,
     849                 :                                                      const nsAString* aValue,
     850                 :                                                      nsTArray<nsIAtom*>& cssPropertyArray,
     851                 :                                                      nsTArray<nsString>& cssValueArray,
     852                 :                                                      bool aGetOrRemoveRequest)
     853                 : {
     854               0 :   MOZ_ASSERT(aElement);
     855               0 :   nsIAtom* tagName = aElement->Tag();
     856                 : 
     857               0 :   if (nsEditProperty::b == aHTMLProperty) {
     858               0 :     BuildCSSDeclarations(cssPropertyArray, cssValueArray, boldEquivTable, aValue, aGetOrRemoveRequest);
     859                 :   }
     860               0 :   else if (nsEditProperty::i == aHTMLProperty) {
     861               0 :     BuildCSSDeclarations(cssPropertyArray, cssValueArray, italicEquivTable, aValue, aGetOrRemoveRequest);
     862                 :   }
     863               0 :   else if (nsEditProperty::u == aHTMLProperty) {
     864               0 :     BuildCSSDeclarations(cssPropertyArray, cssValueArray, underlineEquivTable, aValue, aGetOrRemoveRequest);
     865                 :   }
     866               0 :   else if (nsEditProperty::strike == aHTMLProperty) {
     867               0 :     BuildCSSDeclarations(cssPropertyArray, cssValueArray, strikeEquivTable, aValue, aGetOrRemoveRequest);
     868                 :   }
     869               0 :   else if (nsEditProperty::tt == aHTMLProperty) {
     870               0 :     BuildCSSDeclarations(cssPropertyArray, cssValueArray, ttEquivTable, aValue, aGetOrRemoveRequest);
     871                 :   }
     872               0 :   else if (aAttribute) {
     873               0 :     if (nsEditProperty::font == aHTMLProperty &&
     874               0 :         aAttribute->EqualsLiteral("color")) {
     875               0 :       BuildCSSDeclarations(cssPropertyArray, cssValueArray, fontColorEquivTable, aValue, aGetOrRemoveRequest);
     876                 :     }
     877               0 :     else if (nsEditProperty::font == aHTMLProperty &&
     878               0 :              aAttribute->EqualsLiteral("face")) {
     879               0 :       BuildCSSDeclarations(cssPropertyArray, cssValueArray, fontFaceEquivTable, aValue, aGetOrRemoveRequest);
     880                 :     }
     881               0 :     else if (aAttribute->EqualsLiteral("bgcolor")) {
     882               0 :       BuildCSSDeclarations(cssPropertyArray, cssValueArray, bgcolorEquivTable, aValue, aGetOrRemoveRequest);
     883                 :     }
     884               0 :     else if (aAttribute->EqualsLiteral("background")) {
     885               0 :       BuildCSSDeclarations(cssPropertyArray, cssValueArray, backgroundImageEquivTable, aValue, aGetOrRemoveRequest);
     886                 :     }
     887               0 :     else if (aAttribute->EqualsLiteral("text")) {
     888               0 :       BuildCSSDeclarations(cssPropertyArray, cssValueArray, textColorEquivTable, aValue, aGetOrRemoveRequest);
     889                 :     }
     890               0 :     else if (aAttribute->EqualsLiteral("border")) {
     891               0 :       BuildCSSDeclarations(cssPropertyArray, cssValueArray, borderEquivTable, aValue, aGetOrRemoveRequest);
     892                 :     }
     893               0 :     else if (aAttribute->EqualsLiteral("align")) {
     894               0 :       if (nsEditProperty::table  == tagName) {
     895               0 :         BuildCSSDeclarations(cssPropertyArray, cssValueArray, tableAlignEquivTable, aValue, aGetOrRemoveRequest);
     896                 :       }
     897               0 :       else if (nsEditProperty::hr  == tagName) {
     898               0 :         BuildCSSDeclarations(cssPropertyArray, cssValueArray, hrAlignEquivTable, aValue, aGetOrRemoveRequest);
     899                 :       }
     900               0 :       else if (nsEditProperty::legend  == tagName ||
     901                 :                nsEditProperty::caption == tagName) {
     902               0 :         BuildCSSDeclarations(cssPropertyArray, cssValueArray, captionAlignEquivTable, aValue, aGetOrRemoveRequest);
     903                 :       }
     904                 :       else {
     905               0 :         BuildCSSDeclarations(cssPropertyArray, cssValueArray, textAlignEquivTable, aValue, aGetOrRemoveRequest);
     906                 :       }
     907                 :     }
     908               0 :     else if (aAttribute->EqualsLiteral("valign")) {
     909               0 :       BuildCSSDeclarations(cssPropertyArray, cssValueArray, verticalAlignEquivTable, aValue, aGetOrRemoveRequest);
     910                 :     }
     911               0 :     else if (aAttribute->EqualsLiteral("nowrap")) {
     912               0 :       BuildCSSDeclarations(cssPropertyArray, cssValueArray, nowrapEquivTable, aValue, aGetOrRemoveRequest);
     913                 :     }
     914               0 :     else if (aAttribute->EqualsLiteral("width")) {
     915               0 :       BuildCSSDeclarations(cssPropertyArray, cssValueArray, widthEquivTable, aValue, aGetOrRemoveRequest);
     916                 :     }
     917               0 :     else if (aAttribute->EqualsLiteral("height") ||
     918               0 :              (nsEditProperty::hr == tagName && aAttribute->EqualsLiteral("size"))) {
     919               0 :       BuildCSSDeclarations(cssPropertyArray, cssValueArray, heightEquivTable, aValue, aGetOrRemoveRequest);
     920                 :     }
     921               0 :     else if (aAttribute->EqualsLiteral("type") &&
     922                 :              (nsEditProperty::ol == tagName
     923                 :               || nsEditProperty::ul == tagName
     924                 :               || nsEditProperty::li == tagName)) {
     925               0 :       BuildCSSDeclarations(cssPropertyArray, cssValueArray, listStyleTypeEquivTable, aValue, aGetOrRemoveRequest);
     926                 :     }
     927                 :   }
     928               0 : }
     929                 : 
     930                 : // Add to aNode the CSS inline style equivalent to HTMLProperty/aAttribute/aValue for the node,
     931                 : // and return in aCount the number of CSS properties set by the call
     932                 : nsresult
     933               0 : nsHTMLCSSUtils::SetCSSEquivalentToHTMLStyle(nsIDOMNode * aNode,
     934                 :                                             nsIAtom *aHTMLProperty,
     935                 :                                             const nsAString *aAttribute,
     936                 :                                             const nsAString *aValue,
     937                 :                                             PRInt32 * aCount,
     938                 :                                             bool aSuppressTransaction)
     939                 : {
     940               0 :   nsCOMPtr<dom::Element> element = do_QueryInterface(aNode);
     941               0 :   *aCount = 0;
     942               0 :   if (!element || !IsCSSEditableProperty(element, aHTMLProperty, aAttribute)) {
     943               0 :     return NS_OK;
     944                 :   }
     945                 : 
     946                 :   // we can apply the styles only if the node is an element and if we have
     947                 :   // an equivalence for the requested HTML style in this implementation
     948                 : 
     949                 :   // Find the CSS equivalence to the HTML style
     950               0 :   nsTArray<nsIAtom*> cssPropertyArray;
     951               0 :   nsTArray<nsString> cssValueArray;
     952                 :   GenerateCSSDeclarationsFromHTMLStyle(element, aHTMLProperty, aAttribute,
     953                 :                                        aValue, cssPropertyArray, cssValueArray,
     954               0 :                                        false);
     955                 : 
     956               0 :   nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(element);
     957                 :   // set the individual CSS inline styles
     958               0 :   *aCount = cssPropertyArray.Length();
     959               0 :   for (PRInt32 index = 0; index < *aCount; index++) {
     960               0 :     nsresult res = SetCSSProperty(domElement, cssPropertyArray[index],
     961               0 :                                   cssValueArray[index], aSuppressTransaction);
     962               0 :     NS_ENSURE_SUCCESS(res, res);
     963                 :   }
     964               0 :   return NS_OK;
     965                 : }
     966                 : 
     967                 : // Remove from aNode the CSS inline style equivalent to HTMLProperty/aAttribute/aValue for the node
     968                 : nsresult
     969               0 : nsHTMLCSSUtils::RemoveCSSEquivalentToHTMLStyle(nsIDOMNode * aNode,
     970                 :                                                nsIAtom *aHTMLProperty,
     971                 :                                                const nsAString *aAttribute,
     972                 :                                                const nsAString *aValue,
     973                 :                                                bool aSuppressTransaction)
     974                 : {
     975               0 :   nsCOMPtr<dom::Element> element = do_QueryInterface(aNode);
     976               0 :   if (!element || !IsCSSEditableProperty(element, aHTMLProperty, aAttribute)) {
     977               0 :     return NS_OK;
     978                 :   }
     979                 : 
     980                 :   // we can apply the styles only if the node is an element and if we have
     981                 :   // an equivalence for the requested HTML style in this implementation
     982                 : 
     983                 :   // Find the CSS equivalence to the HTML style
     984               0 :   nsTArray<nsIAtom*> cssPropertyArray;
     985               0 :   nsTArray<nsString> cssValueArray;
     986                 :   GenerateCSSDeclarationsFromHTMLStyle(element, aHTMLProperty, aAttribute,
     987                 :                                        aValue, cssPropertyArray, cssValueArray,
     988               0 :                                        true);
     989                 : 
     990               0 :   nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(element);
     991                 :   // remove the individual CSS inline styles
     992               0 :   PRInt32 count = cssPropertyArray.Length();
     993               0 :   for (PRInt32 index = 0; index < count; index++) {
     994                 :     nsresult res = RemoveCSSProperty(domElement,
     995               0 :                                      cssPropertyArray[index],
     996               0 :                                      cssValueArray[index],
     997               0 :                                      aSuppressTransaction);
     998               0 :     NS_ENSURE_SUCCESS(res, res);
     999                 :   }
    1000               0 :   return NS_OK;
    1001                 : }
    1002                 : 
    1003                 : // returns in aValueString the list of values for the CSS equivalences to
    1004                 : // the HTML style aHTMLProperty/aAttribute/aValueString for the node aNode;
    1005                 : // the value of aStyleType controls the styles we retrieve : specified or
    1006                 : // computed.
    1007                 : nsresult
    1008               0 : nsHTMLCSSUtils::GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode,
    1009                 :                                                      nsIAtom *aHTMLProperty,
    1010                 :                                                      const nsAString *aAttribute,
    1011                 :                                                      nsAString & aValueString,
    1012                 :                                                      PRUint8 aStyleType)
    1013                 : {
    1014               0 :   aValueString.Truncate();
    1015               0 :   nsCOMPtr<dom::Element> theElement = GetElementContainerOrSelf(aNode);
    1016               0 :   NS_ENSURE_TRUE(theElement, NS_ERROR_NULL_POINTER);
    1017                 : 
    1018               0 :   if (!theElement || !IsCSSEditableProperty(theElement, aHTMLProperty, aAttribute)) {
    1019               0 :     return NS_OK;
    1020                 :   }
    1021                 : 
    1022                 :   // Yes, the requested HTML style has a CSS equivalence in this implementation
    1023                 :   // Retrieve the default ViewCSS if we are asked for computed styles
    1024               0 :   nsCOMPtr<nsIDOMWindow> window;
    1025               0 :   if (COMPUTED_STYLE_TYPE == aStyleType) {
    1026               0 :     nsresult res = GetDefaultViewCSS(theElement, getter_AddRefs(window));
    1027               0 :     NS_ENSURE_SUCCESS(res, res);
    1028                 :   }
    1029               0 :   nsTArray<nsIAtom*> cssPropertyArray;
    1030               0 :   nsTArray<nsString> cssValueArray;
    1031                 :   // get the CSS equivalence with last param true indicating we want only the
    1032                 :   // "gettable" properties
    1033                 :   GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute, nsnull,
    1034               0 :                                        cssPropertyArray, cssValueArray, true);
    1035               0 :   PRInt32 count = cssPropertyArray.Length();
    1036               0 :   for (PRInt32 index = 0; index < count; index++) {
    1037               0 :     nsAutoString valueString;
    1038                 :     // retrieve the specified/computed value of the property
    1039               0 :     nsresult res = GetCSSInlinePropertyBase(theElement, cssPropertyArray[index],
    1040               0 :                                             valueString, window, aStyleType);
    1041               0 :     NS_ENSURE_SUCCESS(res, res);
    1042                 :     // append the value to aValueString (possibly with a leading whitespace)
    1043               0 :     if (index) {
    1044               0 :       aValueString.Append(PRUnichar(' '));
    1045                 :     }
    1046               0 :     aValueString.Append(valueString);
    1047                 :   }
    1048               0 :   return NS_OK;
    1049                 : }
    1050                 : 
    1051                 : // Does the node aNode (or his parent if it is not an element node) carries
    1052                 : // the CSS equivalent styles to the HTML style aHTMLProperty/aAttribute/
    1053                 : // aValueString for this node ?
    1054                 : // The value of aStyleType controls the styles we retrieve : specified or
    1055                 : // computed. The return value aIsSet is true is the CSS styles are set.
    1056                 : nsresult
    1057               0 : nsHTMLCSSUtils::IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode * aNode,
    1058                 :                                                     nsIAtom *aHTMLProperty,
    1059                 :                                                     const nsAString * aHTMLAttribute,
    1060                 :                                                     bool & aIsSet,
    1061                 :                                                     nsAString & valueString,
    1062                 :                                                     PRUint8 aStyleType)
    1063                 : {
    1064               0 :   NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
    1065                 : 
    1066               0 :   nsAutoString htmlValueString(valueString);
    1067               0 :   aIsSet = false;
    1068               0 :   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
    1069               0 :   NS_NAMED_LITERAL_STRING(boldStr, "bold");
    1070               0 :   do {
    1071               0 :     valueString.Assign(htmlValueString);
    1072                 :     // get the value of the CSS equivalent styles
    1073                 :     nsresult res = GetCSSEquivalentToHTMLInlineStyleSet(node, aHTMLProperty, aHTMLAttribute,
    1074               0 :                                                         valueString, aStyleType);
    1075               0 :     NS_ENSURE_SUCCESS(res, res);
    1076                 : 
    1077                 :     // early way out if we can
    1078               0 :     if (valueString.IsEmpty()) return NS_OK;
    1079                 : 
    1080               0 :     if (nsEditProperty::b == aHTMLProperty) {
    1081               0 :       if (valueString.Equals(boldStr)) {
    1082               0 :         aIsSet = true;
    1083                 :       }
    1084               0 :       else if (valueString.EqualsLiteral("normal")) {
    1085               0 :         aIsSet = false;
    1086                 :       }
    1087               0 :       else if (valueString.EqualsLiteral("bolder")) {
    1088               0 :         aIsSet = true;
    1089               0 :         valueString.Assign(boldStr);
    1090                 :       }
    1091                 :       else {
    1092               0 :         PRInt32 weight = 0;
    1093                 :         PRInt32 errorCode;
    1094               0 :         nsAutoString value(valueString);
    1095               0 :         weight = value.ToInteger(&errorCode, 10);
    1096               0 :         if (400 < weight) {
    1097               0 :           aIsSet = true;
    1098               0 :           valueString.Assign(boldStr);
    1099                 :         }
    1100                 :         else {
    1101               0 :           aIsSet = false;
    1102               0 :           valueString.AssignLiteral("normal");
    1103                 :         }
    1104                 :       }
    1105                 :     }
    1106                 :     
    1107               0 :     else if (nsEditProperty::i == aHTMLProperty) {
    1108               0 :       if (valueString.EqualsLiteral("italic") ||
    1109               0 :           valueString.EqualsLiteral("oblique")) {
    1110               0 :         aIsSet= true;
    1111                 :       }
    1112                 :     }
    1113                 : 
    1114               0 :     else if (nsEditProperty::u == aHTMLProperty) {
    1115               0 :       nsAutoString val;
    1116               0 :       val.AssignLiteral("underline");
    1117               0 :       aIsSet = bool(ChangeCSSInlineStyleTxn::ValueIncludes(valueString, val, false));
    1118                 :     }
    1119                 : 
    1120               0 :     else if (nsEditProperty::strike == aHTMLProperty) {
    1121               0 :       nsAutoString val;
    1122               0 :       val.AssignLiteral("line-through");
    1123               0 :       aIsSet = bool(ChangeCSSInlineStyleTxn::ValueIncludes(valueString, val, false));
    1124                 :     }
    1125                 : 
    1126               0 :     else if (aHTMLAttribute &&
    1127                 :              ( (nsEditProperty::font == aHTMLProperty && 
    1128               0 :                 aHTMLAttribute->EqualsLiteral("color")) ||
    1129               0 :                aHTMLAttribute->EqualsLiteral("bgcolor"))) {
    1130               0 :       if (htmlValueString.IsEmpty())
    1131               0 :         aIsSet = true;
    1132                 :       else {
    1133                 :         nscolor rgba;
    1134               0 :         nsAutoString subStr;
    1135               0 :         htmlValueString.Right(subStr, htmlValueString.Length()-1);
    1136               0 :         if (NS_ColorNameToRGB(htmlValueString, &rgba) ||
    1137               0 :             NS_HexToRGB(subStr, &rgba)) {
    1138               0 :           nsAutoString htmlColor, tmpStr;
    1139               0 :           htmlColor.AppendLiteral("rgb(");
    1140                 : 
    1141               0 :           NS_NAMED_LITERAL_STRING(comma, ", ");
    1142                 : 
    1143               0 :           tmpStr.AppendInt(NS_GET_R(rgba), 10);
    1144               0 :           htmlColor.Append(tmpStr + comma);
    1145                 : 
    1146               0 :           tmpStr.Truncate();
    1147               0 :           tmpStr.AppendInt(NS_GET_G(rgba), 10);
    1148               0 :           htmlColor.Append(tmpStr + comma);
    1149                 : 
    1150               0 :           tmpStr.Truncate();
    1151               0 :           tmpStr.AppendInt(NS_GET_B(rgba), 10);
    1152               0 :           htmlColor.Append(tmpStr);
    1153                 : 
    1154               0 :           htmlColor.Append(PRUnichar(')'));
    1155                 :           aIsSet = htmlColor.Equals(valueString,
    1156               0 :                                     nsCaseInsensitiveStringComparator());
    1157                 :         }
    1158                 :         else
    1159                 :           aIsSet = htmlValueString.Equals(valueString,
    1160               0 :                                     nsCaseInsensitiveStringComparator());
    1161                 :       }
    1162                 :     }
    1163                 : 
    1164               0 :     else if (nsEditProperty::tt == aHTMLProperty) {
    1165               0 :       aIsSet = StringBeginsWith(valueString, NS_LITERAL_STRING("monospace"));
    1166                 :     }
    1167                 :     
    1168               0 :     else if ((nsEditProperty::font == aHTMLProperty) && aHTMLAttribute
    1169               0 :              && aHTMLAttribute->EqualsLiteral("face")) {
    1170               0 :       if (!htmlValueString.IsEmpty()) {
    1171               0 :         const PRUnichar commaSpace[] = { PRUnichar(','), PRUnichar(' '), 0 };
    1172               0 :         const PRUnichar comma[] = { PRUnichar(','), 0 };
    1173               0 :         htmlValueString.ReplaceSubstring(commaSpace, comma);
    1174               0 :         nsAutoString valueStringNorm(valueString);
    1175               0 :         valueStringNorm.ReplaceSubstring(commaSpace, comma);
    1176                 :         aIsSet = htmlValueString.Equals(valueStringNorm,
    1177               0 :                                         nsCaseInsensitiveStringComparator());
    1178                 :       }
    1179                 :       else {
    1180                 :         // ignore this, it's TT or our default
    1181               0 :         nsAutoString valueStringLower;
    1182               0 :         ToLowerCase(valueString, valueStringLower);
    1183               0 :         aIsSet = !valueStringLower.EqualsLiteral("monospace") &&
    1184               0 :                  !valueStringLower.EqualsLiteral("serif");
    1185                 :       }
    1186               0 :       return NS_OK;
    1187                 :     }
    1188               0 :     else if (aHTMLAttribute
    1189               0 :              && aHTMLAttribute->EqualsLiteral("align")) {
    1190               0 :       aIsSet = true;
    1191                 :     }
    1192                 :     else {
    1193               0 :       aIsSet = false;
    1194               0 :       return NS_OK;
    1195                 :     }
    1196                 : 
    1197               0 :     if (!htmlValueString.IsEmpty()) {
    1198               0 :       if (htmlValueString.Equals(valueString,
    1199               0 :                                  nsCaseInsensitiveStringComparator())) {
    1200               0 :         aIsSet = true;
    1201                 :       }
    1202                 :     }
    1203                 : 
    1204               0 :     if (nsEditProperty::u == aHTMLProperty || nsEditProperty::strike == aHTMLProperty) {
    1205                 :       // unfortunately, the value of the text-decoration property is not inherited.
    1206                 :       // that means that we have to look at ancestors of node to see if they are underlined
    1207               0 :       node = node->GetElementParent();  // set to null if it's not a dom element
    1208                 :     }
    1209                 :   } while ((nsEditProperty::u == aHTMLProperty || nsEditProperty::strike == aHTMLProperty) &&
    1210               0 :            !aIsSet && node);
    1211               0 :   return NS_OK;
    1212                 : }
    1213                 : 
    1214                 : nsresult
    1215               0 : nsHTMLCSSUtils::SetCSSEnabled(bool aIsCSSPrefChecked)
    1216                 : {
    1217               0 :   mIsCSSPrefChecked = aIsCSSPrefChecked;
    1218               0 :   return NS_OK;
    1219                 : }
    1220                 : 
    1221                 : bool
    1222               0 : nsHTMLCSSUtils::IsCSSPrefChecked()
    1223                 : {
    1224               0 :   return mIsCSSPrefChecked ;
    1225                 : }
    1226                 : 
    1227                 : // ElementsSameStyle compares two elements and checks if they have the same
    1228                 : // specified CSS declarations in the STYLE attribute 
    1229                 : // The answer is always negative if at least one of them carries an ID or a class
    1230                 : bool
    1231               0 : nsHTMLCSSUtils::ElementsSameStyle(nsIDOMNode *aFirstNode, nsIDOMNode *aSecondNode)
    1232                 : {
    1233                 :   nsresult res;
    1234               0 :   nsCOMPtr<nsIDOMElement> firstElement  = do_QueryInterface(aFirstNode);
    1235               0 :   nsCOMPtr<nsIDOMElement> secondElement = do_QueryInterface(aSecondNode);
    1236                 : 
    1237               0 :   NS_ASSERTION((firstElement && secondElement), "Non element nodes passed to ElementsSameStyle.");
    1238                 : 
    1239               0 :   nsAutoString firstID, secondID;
    1240                 :   bool isFirstIDSet, isSecondIDSet;
    1241               0 :   res = mHTMLEditor->GetAttributeValue(firstElement,  NS_LITERAL_STRING("id"), firstID,  &isFirstIDSet);
    1242               0 :   res = mHTMLEditor->GetAttributeValue(secondElement, NS_LITERAL_STRING("id"), secondID, &isSecondIDSet);
    1243               0 :   if (isFirstIDSet || isSecondIDSet) {
    1244                 :     // at least one of the spans carries an ID ; suspect a CSS rule applies to it and
    1245                 :     // refuse to merge the nodes
    1246               0 :     return false;
    1247                 :   }
    1248                 : 
    1249               0 :   nsAutoString firstClass, secondClass;
    1250                 :   bool isFirstClassSet, isSecondClassSet;
    1251               0 :   res = mHTMLEditor->GetAttributeValue(firstElement,  NS_LITERAL_STRING("class"), firstClass,  &isFirstClassSet);
    1252               0 :   res = mHTMLEditor->GetAttributeValue(secondElement, NS_LITERAL_STRING("class"), secondClass, &isSecondClassSet);
    1253               0 :   if (isFirstClassSet && isSecondClassSet) {
    1254                 :     // both spans carry a class, let's compare them
    1255               0 :     if (!firstClass.Equals(secondClass)) {
    1256                 :       // WARNING : technically, the comparison just above is questionable :
    1257                 :       // from a pure HTML/CSS point of view class="a b" is NOT the same than
    1258                 :       // class="b a" because a CSS rule could test the exact value of the class
    1259                 :       // attribute to be "a b" for instance ; from a user's point of view, a
    1260                 :       // wysiwyg editor should probably NOT make any difference. CSS people
    1261                 :       // need to discuss this issue before any modification.
    1262               0 :       return false;
    1263                 :     }
    1264                 :   }
    1265               0 :   else if (isFirstClassSet || isSecondClassSet) {
    1266                 :     // one span only carries a class, early way out
    1267               0 :     return false;
    1268                 :   }
    1269                 : 
    1270               0 :   nsCOMPtr<nsIDOMCSSStyleDeclaration> firstCSSDecl, secondCSSDecl;
    1271                 :   PRUint32 firstLength, secondLength;
    1272               0 :   res = GetInlineStyles(firstElement,  getter_AddRefs(firstCSSDecl),  &firstLength);
    1273               0 :   if (NS_FAILED(res) || !firstCSSDecl) return false;
    1274               0 :   res = GetInlineStyles(secondElement, getter_AddRefs(secondCSSDecl), &secondLength);
    1275               0 :   if (NS_FAILED(res) || !secondCSSDecl) return false;
    1276                 : 
    1277               0 :   if (firstLength != secondLength) {
    1278                 :     // early way out if we can
    1279               0 :     return false;
    1280                 :   }
    1281               0 :   else if (0 == firstLength) {
    1282                 :     // no inline style !
    1283               0 :     return true;
    1284                 :   }
    1285                 : 
    1286                 :   PRUint32 i;
    1287               0 :   nsAutoString propertyNameString;
    1288               0 :   nsAutoString firstValue, secondValue;
    1289               0 :   for (i=0; i<firstLength; i++) {
    1290               0 :     firstCSSDecl->Item(i, propertyNameString);
    1291               0 :     firstCSSDecl->GetPropertyValue(propertyNameString, firstValue);
    1292               0 :     secondCSSDecl->GetPropertyValue(propertyNameString, secondValue);
    1293               0 :     if (!firstValue.Equals(secondValue)) {
    1294               0 :       return false;
    1295                 :     }
    1296                 :   }
    1297               0 :   for (i=0; i<secondLength; i++) {
    1298               0 :     secondCSSDecl->Item(i, propertyNameString);
    1299               0 :     secondCSSDecl->GetPropertyValue(propertyNameString, secondValue);
    1300               0 :     firstCSSDecl->GetPropertyValue(propertyNameString, firstValue);
    1301               0 :     if (!firstValue.Equals(secondValue)) {
    1302               0 :       return false;
    1303                 :     }
    1304                 :   }
    1305                 : 
    1306               0 :   return true;
    1307                 : }
    1308                 : 
    1309                 : nsresult
    1310               0 : nsHTMLCSSUtils::GetInlineStyles(nsIDOMElement *aElement,
    1311                 :                                 nsIDOMCSSStyleDeclaration **aCssDecl,
    1312                 :                                 PRUint32 *aLength)
    1313                 : {
    1314               0 :   NS_ENSURE_TRUE(aElement && aLength, NS_ERROR_NULL_POINTER);
    1315               0 :   *aLength = 0;
    1316               0 :   nsCOMPtr<nsIDOMElementCSSInlineStyle> inlineStyles = do_QueryInterface(aElement);
    1317               0 :   NS_ENSURE_TRUE(inlineStyles, NS_ERROR_NULL_POINTER);
    1318               0 :   nsresult res = inlineStyles->GetStyle(aCssDecl);
    1319               0 :   if (NS_FAILED(res) || !aCssDecl) return NS_ERROR_NULL_POINTER;
    1320               0 :   (*aCssDecl)->GetLength(aLength);
    1321               0 :   return NS_OK;
    1322                 : }
    1323                 : 
    1324                 : already_AddRefed<nsIDOMElement>
    1325               0 : nsHTMLCSSUtils::GetElementContainerOrSelf(nsIDOMNode* aNode)
    1326                 : {
    1327               0 :   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
    1328               0 :   NS_ENSURE_TRUE(node, nsnull);
    1329                 :   nsCOMPtr<nsIDOMElement> element =
    1330               0 :     do_QueryInterface(GetElementContainerOrSelf(node));
    1331               0 :   return element.forget();
    1332                 : }
    1333                 : 
    1334                 : dom::Element*
    1335               0 : nsHTMLCSSUtils::GetElementContainerOrSelf(nsINode* aNode)
    1336                 : {
    1337               0 :   MOZ_ASSERT(aNode);
    1338               0 :   if (nsIDOMNode::DOCUMENT_NODE == aNode->NodeType()) {
    1339               0 :     return nsnull;
    1340                 :   }
    1341                 : 
    1342               0 :   nsINode* node = aNode;
    1343                 :   // Loop until we find an element.
    1344               0 :   while (node && !node->IsElement()) {
    1345               0 :     node = node->GetNodeParent();
    1346                 :   }
    1347                 : 
    1348               0 :   NS_ENSURE_TRUE(node, nsnull);
    1349               0 :   return node->AsElement();
    1350                 : }
    1351                 : 
    1352                 : nsresult
    1353               0 : nsHTMLCSSUtils::SetCSSProperty(nsIDOMElement * aElement,
    1354                 :                                const nsAString & aProperty,
    1355                 :                                const nsAString & aValue)
    1356                 : {
    1357               0 :   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl;
    1358                 :   PRUint32 length;
    1359               0 :   nsresult res = GetInlineStyles(aElement, getter_AddRefs(cssDecl), &length);
    1360               0 :   if (NS_FAILED(res) || !cssDecl) return res;
    1361                 : 
    1362               0 :   return cssDecl->SetProperty(aProperty,
    1363                 :                               aValue,
    1364               0 :                               EmptyString());
    1365                 : }
    1366                 : 
    1367                 : nsresult
    1368               0 : nsHTMLCSSUtils::SetCSSPropertyPixels(nsIDOMElement * aElement,
    1369                 :                                      const nsAString & aProperty,
    1370                 :                                      PRInt32 aIntValue)
    1371                 : {
    1372               0 :   nsAutoString s;
    1373               0 :   s.AppendInt(aIntValue);
    1374               0 :   return SetCSSProperty(aElement, aProperty, s + NS_LITERAL_STRING("px"));
    1375                 : }

Generated by: LCOV version 1.7