LCOV - app.info - editor/libeditor/html/nsHTMLCSSUtils.cpp

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-04-21 | 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