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