michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsHTMLCSSUtils_h__ michael@0: #define nsHTMLCSSUtils_h__ michael@0: michael@0: #include "nsCOMPtr.h" // for already_AddRefed michael@0: #include "nsTArray.h" // for nsTArray michael@0: #include "nscore.h" // for nsAString, nsresult, nullptr michael@0: michael@0: class ChangeCSSInlineStyleTxn; michael@0: class nsComputedDOMStyle; michael@0: class nsIAtom; michael@0: class nsIContent; michael@0: class nsIDOMCSSStyleDeclaration; michael@0: class nsIDOMElement; michael@0: class nsIDOMNode; michael@0: class nsINode; michael@0: class nsString; michael@0: namespace mozilla { michael@0: namespace dom { michael@0: class Element; michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: class nsHTMLEditor; michael@0: class nsIDOMWindow; michael@0: michael@0: typedef void (*nsProcessValueFunc)(const nsAString * aInputString, nsAString & aOutputString, michael@0: const char * aDefaultValueString, michael@0: const char * aPrependString, const char* aAppendString); michael@0: michael@0: class nsHTMLCSSUtils michael@0: { michael@0: public: michael@0: explicit nsHTMLCSSUtils(nsHTMLEditor* aEditor); michael@0: ~nsHTMLCSSUtils(); michael@0: michael@0: enum nsCSSEditableProperty { michael@0: eCSSEditableProperty_NONE=0, michael@0: eCSSEditableProperty_background_color, michael@0: eCSSEditableProperty_background_image, michael@0: eCSSEditableProperty_border, michael@0: eCSSEditableProperty_caption_side, michael@0: eCSSEditableProperty_color, michael@0: eCSSEditableProperty_float, michael@0: eCSSEditableProperty_font_family, michael@0: eCSSEditableProperty_font_size, michael@0: eCSSEditableProperty_font_style, michael@0: eCSSEditableProperty_font_weight, michael@0: eCSSEditableProperty_height, michael@0: eCSSEditableProperty_list_style_type, michael@0: eCSSEditableProperty_margin_left, michael@0: eCSSEditableProperty_margin_right, michael@0: eCSSEditableProperty_text_align, michael@0: eCSSEditableProperty_text_decoration, michael@0: eCSSEditableProperty_vertical_align, michael@0: eCSSEditableProperty_whitespace, michael@0: eCSSEditableProperty_width michael@0: }; michael@0: michael@0: enum StyleType { eSpecified, eComputed }; michael@0: michael@0: michael@0: struct CSSEquivTable { michael@0: nsCSSEditableProperty cssProperty; michael@0: nsProcessValueFunc processValueFunctor; michael@0: const char * defaultValue; michael@0: const char * prependValue; michael@0: const char * appendValue; michael@0: bool gettable; michael@0: bool caseSensitiveValue; michael@0: }; michael@0: michael@0: /** answers true if the given combination element_name/attribute_name michael@0: * has a CSS equivalence in this implementation michael@0: * michael@0: * @return a boolean saying if the tag/attribute has a css equiv michael@0: * @param aNode [IN] a DOM node michael@0: * @param aProperty [IN] an atom containing a HTML tag name michael@0: * @param aAttribute [IN] a string containing the name of a HTML michael@0: * attribute carried by the element above michael@0: */ michael@0: bool IsCSSEditableProperty(nsIContent* aNode, nsIAtom* aProperty, const nsAString* aAttribute); michael@0: bool IsCSSEditableProperty(nsIDOMNode* aNode, nsIAtom* aProperty, const nsAString* aAttribute); michael@0: michael@0: /** adds/remove a CSS declaration to the STYLE atrribute carried by a given element michael@0: * michael@0: * @param aElement [IN] a DOM element michael@0: * @param aProperty [IN] an atom containing the CSS property to set michael@0: * @param aValue [IN] a string containing the value of the CSS property michael@0: * @param aSuppressTransaction [IN] a boolean indicating, when true, michael@0: * that no transaction should be recorded michael@0: */ michael@0: nsresult SetCSSProperty(nsIDOMElement * aElement, nsIAtom * aProperty, michael@0: const nsAString & aValue, michael@0: bool aSuppressTransaction); michael@0: nsresult SetCSSPropertyPixels(nsIDOMElement *aElement, nsIAtom *aProperty, michael@0: int32_t aIntValue, bool aSuppressTxn); michael@0: nsresult RemoveCSSProperty(nsIDOMElement * aElement, nsIAtom * aProperty, michael@0: const nsAString & aPropertyValue, bool aSuppressTransaction); michael@0: michael@0: /** directly adds/remove a CSS declaration to the STYLE atrribute carried by michael@0: * a given element without going through the txn manager michael@0: * michael@0: * @param aElement [IN] a DOM element michael@0: * @param aProperty [IN] a string containing the CSS property to set/remove michael@0: * @param aValue [IN] a string containing the new value of the CSS property michael@0: */ michael@0: nsresult SetCSSProperty(nsIDOMElement * aElement, michael@0: const nsAString & aProperty, michael@0: const nsAString & aValue); michael@0: nsresult SetCSSPropertyPixels(nsIDOMElement * aElement, michael@0: const nsAString & aProperty, michael@0: int32_t aIntValue); michael@0: michael@0: /** gets the specified/computed style value of a CSS property for a given node (or its element michael@0: * ancestor if it is not an element) michael@0: * michael@0: * @param aNode [IN] a DOM node michael@0: * @param aProperty [IN] an atom containing the CSS property to get michael@0: * @param aPropertyValue [OUT] the retrieved value of the property michael@0: */ michael@0: nsresult GetSpecifiedProperty(nsIDOMNode *aNode, nsIAtom *aProperty, michael@0: nsAString & aValue); michael@0: nsresult GetComputedProperty(nsIDOMNode *aNode, nsIAtom *aProperty, michael@0: nsAString & aValue); michael@0: michael@0: /** Removes a CSS property from the specified declarations in STYLE attribute michael@0: ** and removes the node if it is an useless span michael@0: * michael@0: * @param aNode [IN] the specific node we want to remove a style from michael@0: * @param aProperty [IN] the CSS property atom to remove michael@0: * @param aPropertyValue [IN] the value of the property we have to rremove if the property michael@0: * accepts more than one value michael@0: */ michael@0: nsresult RemoveCSSInlineStyle(nsIDOMNode * aNode, nsIAtom * aProperty, const nsAString & aPropertyValue); michael@0: michael@0: /** Answers true is the property can be removed by setting a "none" CSS value michael@0: * on a node michael@0: * michael@0: * @return a boolean saying if the property can be remove by setting a "none" value michael@0: * @param aProperty [IN] an atom containing a CSS property michael@0: * @param aAttribute [IN] pointer to an attribute name or null if this information is irrelevant michael@0: */ michael@0: bool IsCSSInvertable(nsIAtom * aProperty, const nsAString * aAttribute); michael@0: michael@0: /** Get the default browser background color if we need it for GetCSSBackgroundColorState michael@0: * michael@0: * @param aColor [OUT] the default color as it is defined in prefs michael@0: */ michael@0: void GetDefaultBackgroundColor(nsAString & aColor); michael@0: michael@0: /** Get the default length unit used for CSS Indent/Outdent michael@0: * michael@0: * @param aLengthUnit [OUT] the default length unit as it is defined in prefs michael@0: */ michael@0: void GetDefaultLengthUnit(nsAString & aLengthUnit); michael@0: michael@0: /** returns the list of values for the CSS equivalences to michael@0: * the passed HTML style for the passed node michael@0: * michael@0: * @param aNode [IN] a DOM node michael@0: * @param aHTMLProperty [IN] an atom containing an HTML property michael@0: * @param aAttribute [IN] a pointer to an attribute name or nullptr if irrelevant michael@0: * @param aValueString [OUT] the list of css values michael@0: * @param aStyleType [IN] eSpecified or eComputed michael@0: */ michael@0: nsresult GetCSSEquivalentToHTMLInlineStyleSet(nsINode* aNode, michael@0: nsIAtom * aHTMLProperty, michael@0: const nsAString * aAttribute, michael@0: nsAString & aValueString, michael@0: StyleType aStyleType); michael@0: michael@0: /** Does the node aNode (or his parent if it is not an element node) carries michael@0: * the CSS equivalent styles to the HTML style for this node ? michael@0: * michael@0: * @param aNode [IN] a DOM node michael@0: * @param aHTMLProperty [IN] an atom containing an HTML property michael@0: * @param aAttribute [IN] a pointer to an attribute name or nullptr if irrelevant michael@0: * @param aIsSet [OUT] a boolean being true if the css properties are set michael@0: * @param aValueString [IN/OUT] the attribute value (in) the list of css values (out) michael@0: * @param aStyleType [IN] eSpecified or eComputed michael@0: * michael@0: * The nsIContent variant returns aIsSet instead of using an out parameter. michael@0: */ michael@0: bool IsCSSEquivalentToHTMLInlineStyleSet(nsIContent* aContent, michael@0: nsIAtom* aProperty, michael@0: const nsAString* aAttribute, michael@0: const nsAString& aValue, michael@0: StyleType aStyleType); michael@0: michael@0: nsresult IsCSSEquivalentToHTMLInlineStyleSet(nsIDOMNode * aNode, michael@0: nsIAtom * aHTMLProperty, michael@0: const nsAString * aAttribute, michael@0: bool & aIsSet, michael@0: nsAString & aValueString, michael@0: StyleType aStyleType); michael@0: michael@0: /** Adds to the node the CSS inline styles equivalent to the HTML style michael@0: * and return the number of CSS properties set by the call michael@0: * michael@0: * @param aNode [IN] a DOM node michael@0: * @param aHTMLProperty [IN] an atom containing an HTML property michael@0: * @param aAttribute [IN] a pointer to an attribute name or nullptr if irrelevant michael@0: * @param aValue [IN] the attribute value michael@0: * @param aCount [OUT] the number of CSS properties set by the call michael@0: * @param aSuppressTransaction [IN] a boolean indicating, when true, michael@0: * that no transaction should be recorded michael@0: * michael@0: * aCount is returned by the dom::Element variant instead of being an out michael@0: * parameter. michael@0: */ michael@0: int32_t SetCSSEquivalentToHTMLStyle(mozilla::dom::Element* aElement, michael@0: nsIAtom* aProperty, michael@0: const nsAString* aAttribute, michael@0: const nsAString* aValue, michael@0: bool aSuppressTransaction); michael@0: nsresult SetCSSEquivalentToHTMLStyle(nsIDOMNode * aNode, michael@0: nsIAtom * aHTMLProperty, michael@0: const nsAString * aAttribute, michael@0: const nsAString * aValue, michael@0: int32_t * aCount, michael@0: bool aSuppressTransaction); michael@0: michael@0: /** removes from the node the CSS inline styles equivalent to the HTML style michael@0: * michael@0: * @param aNode [IN] a DOM node michael@0: * @param aHTMLProperty [IN] an atom containing an HTML property michael@0: * @param aAttribute [IN] a pointer to an attribute name or nullptr if irrelevant michael@0: * @param aValue [IN] the attribute value michael@0: * @param aSuppressTransaction [IN] a boolean indicating, when true, michael@0: * that no transaction should be recorded michael@0: */ michael@0: nsresult RemoveCSSEquivalentToHTMLStyle(nsIDOMNode * aNode, michael@0: nsIAtom *aHTMLProperty, michael@0: const nsAString *aAttribute, michael@0: const nsAString *aValue, michael@0: bool aSuppressTransaction); michael@0: /** removes from the node the CSS inline styles equivalent to the HTML style michael@0: * michael@0: * @param aElement [IN] a DOM Element (must not be null) michael@0: * @param aHTMLProperty [IN] an atom containing an HTML property michael@0: * @param aAttribute [IN] a pointer to an attribute name or nullptr if irrelevant michael@0: * @param aValue [IN] the attribute value michael@0: * @param aSuppressTransaction [IN] a boolean indicating, when true, michael@0: * that no transaction should be recorded michael@0: */ michael@0: nsresult RemoveCSSEquivalentToHTMLStyle(mozilla::dom::Element* aElement, michael@0: nsIAtom* aHTMLProperty, michael@0: const nsAString* aAttribute, michael@0: const nsAString* aValue, michael@0: bool aSuppressTransaction); michael@0: michael@0: /** parses a "xxxx.xxxxxuuu" string where x is a digit and u an alpha char michael@0: * we need such a parser because nsIDOMCSSStyleDeclaration::GetPropertyCSSValue() is not michael@0: * implemented michael@0: * michael@0: * @param aString [IN] input string to parse michael@0: * @param aValue [OUT] numeric part michael@0: * @param aUnit [OUT] unit part michael@0: */ michael@0: void ParseLength(const nsAString & aString, float * aValue, nsIAtom ** aUnit); michael@0: michael@0: /** sets the mIsCSSPrefChecked private member ; used as callback from observer when michael@0: * the css pref state is changed michael@0: * michael@0: * @param aIsCSSPrefChecked [IN] the new boolean state for the pref michael@0: */ michael@0: void SetCSSEnabled(bool aIsCSSPrefChecked); michael@0: michael@0: /** retrieves the mIsCSSPrefChecked private member, true if the css pref is checked, michael@0: * false if it is not michael@0: * michael@0: * @return the boolean value of the css pref michael@0: */ michael@0: bool IsCSSPrefChecked(); michael@0: michael@0: /** ElementsSameStyle compares two elements and checks if they have the same michael@0: * specified CSS declarations in the STYLE attribute michael@0: * The answer is always false if at least one of them carries an ID or a class michael@0: * michael@0: * @return true if the two elements are considered to have same styles michael@0: * @param aFirstNode [IN] a DOM node michael@0: * @param aSecondNode [IN] a DOM node michael@0: */ michael@0: bool ElementsSameStyle(mozilla::dom::Element* aFirstNode, michael@0: mozilla::dom::Element* aSecondNode); michael@0: bool ElementsSameStyle(nsIDOMNode *aFirstNode, nsIDOMNode *aSecondNode); michael@0: michael@0: /** get the specified inline styles (style attribute) for an element michael@0: * michael@0: * @param aElement [IN] the element node michael@0: * @param aCssDecl [OUT] the CSS declaration corresponding to the style attr michael@0: * @param aLength [OUT] the number of declarations in aCssDecl michael@0: */ michael@0: nsresult GetInlineStyles(mozilla::dom::Element* aElement, michael@0: nsIDOMCSSStyleDeclaration** aCssDecl, michael@0: uint32_t* aLength); michael@0: nsresult GetInlineStyles(nsIDOMElement* aElement, michael@0: nsIDOMCSSStyleDeclaration** aCssDecl, michael@0: uint32_t* aLength); michael@0: private: michael@0: nsresult GetInlineStyles(nsISupports* aElement, michael@0: nsIDOMCSSStyleDeclaration** aCssDecl, michael@0: uint32_t* aLength); michael@0: michael@0: public: michael@0: /** returns aNode itself if it is an element node, or the first ancestors being an element michael@0: * node if aNode is not one itself michael@0: * michael@0: * @param aNode [IN] a node michael@0: * @param aElement [OUT] the deepest element node containing aNode (possibly aNode itself) michael@0: */ michael@0: mozilla::dom::Element* GetElementContainerOrSelf(nsINode* aNode); michael@0: already_AddRefed GetElementContainerOrSelf(nsIDOMNode* aNode); michael@0: michael@0: /** michael@0: * Gets the computed style for a given element. Can return null. michael@0: */ michael@0: already_AddRefed michael@0: GetComputedStyle(nsIDOMElement* aElement); michael@0: already_AddRefed michael@0: GetComputedStyle(mozilla::dom::Element* aElement); michael@0: michael@0: michael@0: private: michael@0: michael@0: /** retrieves the css property atom from an enum michael@0: * michael@0: * @param aProperty [IN] the enum value for the property michael@0: * @param aAtom [OUT] the corresponding atom michael@0: */ michael@0: void GetCSSPropertyAtom(nsCSSEditableProperty aProperty, nsIAtom ** aAtom); michael@0: michael@0: /** retrieves the CSS declarations equivalent to a HTML style value for michael@0: * a given equivalence table michael@0: * michael@0: * @param aPropertyArray [OUT] the array of css properties michael@0: * @param aValueArray [OUT] the array of values for the css properties above michael@0: * @param aEquivTable [IN] the equivalence table michael@0: * @param aValue [IN] the HTML style value michael@0: * @param aGetOrRemoveRequest [IN] a boolean value being true if the call to the current method michael@0: * is made for GetCSSEquivalentToHTMLInlineStyleSet or michael@0: * RemoveCSSEquivalentToHTMLInlineStyleSet michael@0: */ michael@0: michael@0: void BuildCSSDeclarations(nsTArray & aPropertyArray, michael@0: nsTArray & cssValueArray, michael@0: const CSSEquivTable * aEquivTable, michael@0: const nsAString * aValue, michael@0: bool aGetOrRemoveRequest); michael@0: michael@0: /** retrieves the CSS declarations equivalent to the given HTML property/attribute/value michael@0: * for a given node michael@0: * michael@0: * @param aNode [IN] the DOM node michael@0: * @param aHTMLProperty [IN] an atom containing an HTML property michael@0: * @param aAttribute [IN] a pointer to an attribute name or nullptr if irrelevant michael@0: * @param aValue [IN] the attribute value michael@0: * @param aPropertyArray [OUT] the array of css properties michael@0: * @param aValueArray [OUT] the array of values for the css properties above michael@0: * @param aGetOrRemoveRequest [IN] a boolean value being true if the call to the current method michael@0: * is made for GetCSSEquivalentToHTMLInlineStyleSet or michael@0: * RemoveCSSEquivalentToHTMLInlineStyleSet michael@0: */ michael@0: void GenerateCSSDeclarationsFromHTMLStyle(mozilla::dom::Element* aNode, michael@0: nsIAtom* aHTMLProperty, michael@0: const nsAString* aAttribute, michael@0: const nsAString* aValue, michael@0: nsTArray& aPropertyArray, michael@0: nsTArray& aValueArray, michael@0: bool aGetOrRemoveRequest); michael@0: michael@0: /** creates a Transaction for setting or removing a css property michael@0: * michael@0: * @param aElement [IN] a DOM element michael@0: * @param aProperty [IN] a CSS property michael@0: * @param aValue [IN] the value to remove for this CSS property or the empty string if irrelevant michael@0: * @param aTxn [OUT] the created transaction michael@0: * @param aRemoveProperty [IN] true if we create a "remove" transaction, false for a "set" michael@0: */ michael@0: nsresult CreateCSSPropertyTxn(nsIDOMElement * aElement, michael@0: nsIAtom * aProperty, michael@0: const nsAString & aValue, michael@0: ChangeCSSInlineStyleTxn ** aTxn, michael@0: bool aRemoveProperty); michael@0: michael@0: /** back-end for GetSpecifiedProperty and GetComputedProperty michael@0: * michael@0: * @param aNode [IN] a DOM node michael@0: * @param aProperty [IN] a CSS property michael@0: * @param aValue [OUT] the retrieved value for this property michael@0: * @param aStyleType [IN] eSpecified or eComputed michael@0: */ michael@0: nsresult GetCSSInlinePropertyBase(nsINode* aNode, nsIAtom* aProperty, michael@0: nsAString& aValue, StyleType aStyleType); michael@0: nsresult GetCSSInlinePropertyBase(nsIDOMNode* aNode, nsIAtom* aProperty, michael@0: nsAString& aValue, StyleType aStyleType); michael@0: michael@0: michael@0: private: michael@0: nsHTMLEditor *mHTMLEditor; michael@0: bool mIsCSSPrefChecked; michael@0: }; michael@0: michael@0: #define NS_EDITOR_INDENT_INCREMENT_IN 0.4134f michael@0: #define NS_EDITOR_INDENT_INCREMENT_CM 1.05f michael@0: #define NS_EDITOR_INDENT_INCREMENT_MM 10.5f michael@0: #define NS_EDITOR_INDENT_INCREMENT_PT 29.76f michael@0: #define NS_EDITOR_INDENT_INCREMENT_PC 2.48f michael@0: #define NS_EDITOR_INDENT_INCREMENT_EM 3 michael@0: #define NS_EDITOR_INDENT_INCREMENT_EX 6 michael@0: #define NS_EDITOR_INDENT_INCREMENT_PX 40 michael@0: #define NS_EDITOR_INDENT_INCREMENT_PERCENT 4 michael@0: michael@0: #endif /* nsHTMLCSSUtils_h__ */