tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CSSEditUtils.h (17086B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef CSSEditUtils_h
      7 #define CSSEditUtils_h
      8 
      9 #include "ChangeStyleTransaction.h"  // for ChangeStyleTransaction
     10 #include "EditorForwards.h"
     11 #include "nsCOMPtr.h"  // for already_AddRefed
     12 #include "nsStringFwd.h"
     13 #include "nsTArray.h"  // for nsTArray
     14 #include "nscore.h"    // for nsAString, nsresult, nullptr
     15 
     16 class nsComputedDOMStyle;
     17 class nsAtom;
     18 class nsIContent;
     19 class nsINode;
     20 class nsStaticAtom;
     21 class nsStyledElement;
     22 
     23 namespace mozilla {
     24 namespace dom {
     25 class Element;
     26 }  // namespace dom
     27 
     28 using nsProcessValueFunc = void (*)(const nsAString* aInputString,
     29                                    nsAString& aOutputString,
     30                                    const char* aDefaultValueString,
     31                                    const char* aPrependString,
     32                                    const char* aAppendString);
     33 
     34 class CSSEditUtils final {
     35 public:
     36  // To prevent the class being instantiated
     37  CSSEditUtils() = delete;
     38 
     39  enum nsCSSEditableProperty {
     40    eCSSEditableProperty_NONE = 0,
     41    eCSSEditableProperty_background_color,
     42    eCSSEditableProperty_background_image,
     43    eCSSEditableProperty_border,
     44    eCSSEditableProperty_caption_side,
     45    eCSSEditableProperty_color,
     46    eCSSEditableProperty_float,
     47    eCSSEditableProperty_font_family,
     48    eCSSEditableProperty_font_size,
     49    eCSSEditableProperty_font_style,
     50    eCSSEditableProperty_font_weight,
     51    eCSSEditableProperty_height,
     52    eCSSEditableProperty_list_style_type,
     53    eCSSEditableProperty_margin_left,
     54    eCSSEditableProperty_margin_right,
     55    eCSSEditableProperty_text_align,
     56    eCSSEditableProperty_text_decoration,
     57    eCSSEditableProperty_vertical_align,
     58    eCSSEditableProperty_whitespace,
     59    eCSSEditableProperty_width
     60  };
     61 
     62  // Nb: keep these fields in an order that minimizes padding.
     63  struct CSSEquivTable {
     64    nsCSSEditableProperty cssProperty;
     65    bool gettable;
     66    bool caseSensitiveValue;
     67    nsProcessValueFunc processValueFunctor;
     68    const char* defaultValue;
     69    const char* prependValue;
     70    const char* appendValue;
     71  };
     72 
     73  /**
     74   * Adds/remove a CSS declaration to the STYLE attribute carried by a given
     75   * element.
     76   *
     77   * @param aHTMLEditor    [IN] An HTMLEditor instance
     78   * @param aStyledElement [IN] A DOM styled element.
     79   * @param aProperty      [IN] An atom containing the CSS property to set.
     80   * @param aValue         [IN] A string containing the value of the CSS
     81   *                            property.
     82   */
     83  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsresult
     84  SetCSSPropertyWithTransaction(HTMLEditor& aHTMLEditor,
     85                                nsStyledElement& aStyledElement,
     86                                nsAtom& aProperty, const nsAString& aValue) {
     87    return SetCSSPropertyInternal(aHTMLEditor, aStyledElement, aProperty,
     88                                  aValue, false);
     89  }
     90  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsresult
     91  SetCSSPropertyPixelsWithTransaction(HTMLEditor& aHTMLEditor,
     92                                      nsStyledElement& aStyledElement,
     93                                      nsAtom& aProperty, int32_t aIntValue);
     94  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsresult
     95  SetCSSPropertyPixelsWithoutTransaction(HTMLEditor& aHTMLEditor,
     96                                         nsStyledElement& aStyledElement,
     97                                         const nsAtom& aProperty,
     98                                         int32_t aIntValue);
     99  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsresult
    100  RemoveCSSPropertyWithTransaction(HTMLEditor& aHTMLEditor,
    101                                   nsStyledElement& aStyledElement,
    102                                   nsAtom& aProperty,
    103                                   const nsAString& aPropertyValue) {
    104    return RemoveCSSPropertyInternal(aHTMLEditor, aStyledElement, aProperty,
    105                                     aPropertyValue, false);
    106  }
    107 
    108  /**
    109   * Gets the specified/computed style value of a CSS property for a given
    110   * node (or its element ancestor if it is not an element).
    111   *
    112   * @param aContent       [IN] A DOM node.
    113   * @param aProperty      [IN] An atom containing the CSS property to get.
    114   * @param aPropertyValue [OUT] The retrieved value of the property.
    115   */
    116  static nsresult GetSpecifiedProperty(nsIContent& aContent,
    117                                       nsAtom& aCSSProperty, nsAString& aValue);
    118  MOZ_CAN_RUN_SCRIPT static nsresult GetComputedProperty(nsIContent& aContent,
    119                                                         nsAtom& aCSSProperty,
    120                                                         nsAString& aValue);
    121 
    122  /**
    123   * Removes a CSS property from the specified declarations in STYLE attribute
    124   * and removes the node if it is an useless span.
    125   *
    126   * @param aHTMLEditor    [IN] An HTMLEditor instance
    127   * @param aStyledElement  [IN] The styled element we want to remove a style
    128   *                             from.
    129   * @param aProperty       [IN] The CSS property atom to remove.
    130   * @param aPropertyValue  [IN] The value of the property we have to remove
    131   *                             if the property accepts more than one value.
    132   * @return                A candidate point to put caret.
    133   */
    134  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<EditorDOMPoint, nsresult>
    135  RemoveCSSInlineStyleWithTransaction(HTMLEditor& aHTMLEditor,
    136                                      nsStyledElement& aStyledElement,
    137                                      nsAtom* aProperty,
    138                                      const nsAString& aPropertyValue);
    139 
    140  /**
    141   * Get the default browser background color if we need it for
    142   * GetCSSBackgroundColorState().
    143   *
    144   * @param aColor         [OUT] The default color as it is defined in prefs.
    145   */
    146  static void GetDefaultBackgroundColor(nsAString& aColor);
    147 
    148  /**
    149   * Returns the list of values for the CSS equivalences to
    150   * the passed HTML style for the passed node.
    151   *
    152   * @param aElement       [IN] A DOM node.
    153   * @param aStyle         [IN] The style to get the values.
    154   * @param aValueString   [OUT] The list of CSS values.
    155   */
    156  MOZ_CAN_RUN_SCRIPT static nsresult GetComputedCSSEquivalentTo(
    157      dom::Element& aElement, const EditorElementStyle& aStyle,
    158      nsAString& aOutValue);
    159 
    160  /**
    161   * Does the node aNode (or his parent if it is not an element node) carries
    162   * the CSS equivalent styles to the HTML style for this node ?
    163   *
    164   * @param aHTMLEditor    [IN] An HTMLEditor instance
    165   * @param aContent       [IN] A DOM node.
    166   * @param aStyle         [IN] The style to check.
    167   * @param aInOutValue    [IN/OUT] Input value is used for initial value of the
    168   *                                result, out value is the list of CSS values.
    169   * @return               A boolean being true if the css properties are
    170   *                       not same as initial value.
    171   */
    172  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<bool, nsresult>
    173  IsComputedCSSEquivalentTo(const HTMLEditor& aHTMLEditor, nsIContent& aContent,
    174                            const EditorInlineStyle& aStyle,
    175                            nsAString& aInOutValue);
    176  [[nodiscard]] MOZ_CAN_RUN_SCRIPT_BOUNDARY static Result<bool, nsresult>
    177  IsSpecifiedCSSEquivalentTo(const HTMLEditor& aHTMLEditor,
    178                             nsIContent& aContent,
    179                             const EditorInlineStyle& aStyle,
    180                             nsAString& aInOutValue);
    181 
    182  /**
    183   * This is a kind of Is*CSSEquivalentTo.
    184   * Is*CSSEquivalentTo returns whether the properties aren't same as initial
    185   * value.  But this method returns whether the properties aren't set.
    186   * If node is <span style="font-weight: normal"/>,
    187   *  - Is(Computed|Specified)CSSEquivalentTo returns false.
    188   *  - Have(Computed|Specified)CSSEquivalentStyles returns true.
    189   *
    190   * @param aHTMLEditor    [IN] An HTMLEditor instance
    191   * @param aContent       [IN] A DOM node.
    192   * @param aStyle         [IN] The style to check.
    193   * @return               A boolean being true if the css properties are
    194   *                       not set.
    195   */
    196  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<bool, nsresult>
    197  HaveComputedCSSEquivalentStyles(const HTMLEditor& aHTMLEditor,
    198                                  nsIContent& aContent,
    199                                  const EditorInlineStyle& aStyle);
    200  [[nodiscard]] MOZ_CAN_RUN_SCRIPT_BOUNDARY static Result<bool, nsresult>
    201  HaveSpecifiedCSSEquivalentStyles(const HTMLEditor& aHTMLEditor,
    202                                   nsIContent& aContent,
    203                                   const EditorInlineStyle& aStyle);
    204 
    205  /**
    206   * Adds to the node the CSS inline styles equivalent to the HTML style
    207   * and return the number of CSS properties set by the call.
    208   *
    209   * @param aHTMLEditor    [IN} An HTMLEditor instance
    210   * @param aNode          [IN] A DOM node.
    211   * @param aStyleToSet    [IN] The style to set.  Can be EditorInlineStyle.
    212   * @param aValue         [IN] The attribute or style value of aStyleToSet.
    213   *
    214   * @return               The number of CSS properties set by the call.
    215   */
    216  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<size_t, nsresult>
    217  SetCSSEquivalentToStyle(WithTransaction aWithTransaction,
    218                          HTMLEditor& aHTMLEditor,
    219                          nsStyledElement& aStyledElement,
    220                          const EditorElementStyle& aStyleToSet,
    221                          const nsAString* aValue);
    222 
    223  /**
    224   * Removes from the node the CSS inline styles equivalent to the HTML style.
    225   *
    226   * @param aHTMLEditor    [IN} An HTMLEditor instance
    227   * @param aStyledElement [IN] A DOM Element (must not be null).
    228   * @param aStyleToRemove [IN] The style to remove.  Can be EditorInlineStyle.
    229   * @param aAttribute     [IN] An atom to an attribute name or nullptr if
    230   *                            irrelevant.
    231   * @param aValue         [IN] The attribute value.
    232   */
    233  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsresult RemoveCSSEquivalentToStyle(
    234      WithTransaction aWithTransaction, HTMLEditor& aHTMLEditor,
    235      nsStyledElement& aStyledElement, const EditorElementStyle& aStyleToRemove,
    236      const nsAString* aValue);
    237 
    238  /**
    239   * Parses a "xxxx.xxxxxuuu" string where x is a digit and u an alpha char.
    240   *
    241   * @param aString        [IN] Input string to parse.
    242   * @param aValue         [OUT] Numeric part.
    243   * @param aUnit          [OUT] Unit part.
    244   */
    245  static void ParseLength(const nsAString& aString, float* aValue,
    246                          nsAtom** aUnit);
    247 
    248  /**
    249   * DoStyledElementsHaveSameStyle compares two elements and checks if they have
    250   * the same specified CSS declarations in the STYLE attribute. The answer is
    251   * always false if at least one of them carries an ID or a class.
    252   *
    253   * @param aStyledElement      [IN] A styled element.
    254   * @param aOtherStyledElement [IN] The other styled element.
    255   * @return                    true if the two elements are considered to
    256   *                            have same styles.
    257   */
    258  static bool DoStyledElementsHaveSameStyle(
    259      nsStyledElement& aStyledElement, nsStyledElement& aOtherStyledElement);
    260 
    261  /**
    262   * Gets the computed style for a given element.  Can return null.
    263   */
    264  static already_AddRefed<nsComputedDOMStyle> GetComputedStyle(
    265      dom::Element* aElement);
    266 
    267 private:
    268  enum class StyleType { Specified, Computed };
    269 
    270  /**
    271   * Retrieves the CSS property atom from an enum.
    272   *
    273   * @param aProperty           The enum value for the property.
    274   * @return                    The corresponding atom.
    275   */
    276  static nsStaticAtom* GetCSSPropertyAtom(nsCSSEditableProperty aProperty);
    277 
    278  struct CSSDeclaration {
    279    nsStaticAtom& mProperty;
    280    nsString const mValue;
    281  };
    282 
    283  /**
    284   * Retrieves the CSS declarations for aEquivTable.
    285   *
    286   * @param aEquivTable         The equivalence table.
    287   * @param aValue              Optional.  If specified, may return only
    288   *                            matching declarations to this value (depends on
    289   *                            the style, check how is aInputString of
    290   *                            nsProcessValueFunc for the details).
    291   * @param aHandlingFor        What's the purpose of calling this.
    292   * @param aOutCSSDeclarations [OUT] The array of CSS declarations.
    293   */
    294  enum class HandlingFor { GettingStyle, SettingStyle, RemovingStyle };
    295  static void GetCSSDeclarations(const CSSEquivTable* aEquivTable,
    296                                 const nsAString* aValue,
    297                                 HandlingFor aHandlingFor,
    298                                 nsTArray<CSSDeclaration>& aOutCSSDeclarations);
    299 
    300  /**
    301   * Retrieves the CSS declarations equivalent to the given aStyle/aValue on
    302   * aElement.
    303   *
    304   * @param aElement            The DOM node.
    305   * @param aStyle              The style to get equivelent CSS properties and
    306   *                            values.
    307   * @param aValue              Optional.  If specified, may return only
    308   *                            matching declarations to this value (depends on
    309   *                            the style, check how is aInputString of
    310   *                            nsProcessValueFunc for the details).
    311   * @param aHandlingFor        What's the purpose of calling this.
    312   * @param aOutCSSDeclarations [OUT] The array of CSS declarations.
    313   */
    314  static void GetCSSDeclarations(dom::Element& aElement,
    315                                 const EditorElementStyle& aStyle,
    316                                 const nsAString* aValue,
    317                                 HandlingFor aHandlingFor,
    318                                 nsTArray<CSSDeclaration>& aOutCSSDeclarations);
    319 
    320  /**
    321   * Back-end for GetSpecifiedProperty and GetComputedProperty.
    322   *
    323   * @param aNode               [IN] A DOM node.
    324   * @param aProperty           [IN] A CSS property.
    325   * @param aValue              [OUT] The retrieved value for this property.
    326   */
    327  MOZ_CAN_RUN_SCRIPT static nsresult GetComputedCSSInlinePropertyBase(
    328      nsIContent& aContent, nsAtom& aCSSProperty, nsAString& aValue);
    329  static nsresult GetSpecifiedCSSInlinePropertyBase(nsIContent& aContent,
    330                                                    nsAtom& aCSSProperty,
    331                                                    nsAString& aValue);
    332 
    333  /**
    334   * Those methods are wrapped with corresponding methods which do not have
    335   * "Internal" in their names.  Don't use these methods directly even if
    336   * you want to use one of them in this class.
    337   * Note that these methods may run scrip only when StyleType is Computed.
    338   */
    339  MOZ_CAN_RUN_SCRIPT static nsresult GetCSSEquivalentTo(
    340      dom::Element& aElement, const EditorElementStyle& aStyle,
    341      nsAString& aOutValue, StyleType aStyleType);
    342  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<bool, nsresult>
    343  IsCSSEquivalentTo(const HTMLEditor& aHTMLEditor, nsIContent& aContent,
    344                    const EditorInlineStyle& aStyle, nsAString& aInOutValue,
    345                    StyleType aStyleType);
    346  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<bool, nsresult>
    347  HaveCSSEquivalentStyles(const HTMLEditor& aHTMLEditor, nsIContent& aContent,
    348                          const EditorInlineStyle& aStyle,
    349                          StyleType aStyleType);
    350 
    351  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsresult RemoveCSSPropertyInternal(
    352      HTMLEditor& aHTMLEditor, nsStyledElement& aStyledElement,
    353      nsAtom& aProperty, const nsAString& aPropertyValue,
    354      bool aSuppressTxn = false);
    355  [[nodiscard]] MOZ_CAN_RUN_SCRIPT static nsresult SetCSSPropertyInternal(
    356      HTMLEditor& aHTMLEditor, nsStyledElement& aStyledElement,
    357      nsAtom& aProperty, const nsAString& aValue, bool aSuppressTxn = false);
    358 
    359  /**
    360   * Answers true if the given aStyle on aElement or an element whose name is
    361   * aTagName has a CSS equivalence in this implementation.
    362   *
    363   * @param aTagName       [IN] Tag name of an element.
    364   * @param aElement       [IN] An element.
    365   * @param aStyle         [IN] The style you want to check.
    366   * @return               A boolean saying if the tag/attribute has a CSS
    367   *                       equiv.
    368   */
    369  [[nodiscard]] static bool IsCSSEditableStyle(
    370      const nsAtom& aTagName, const EditorElementStyle& aStyle);
    371  [[nodiscard]] static bool IsCSSEditableStyle(
    372      const dom::Element& aElement, const EditorElementStyle& aStyle);
    373 
    374  friend class EditorElementStyle;  // for IsCSSEditableStyle
    375 };
    376 
    377 #define NS_EDITOR_INDENT_INCREMENT_IN 0.4134f
    378 #define NS_EDITOR_INDENT_INCREMENT_CM 1.05f
    379 #define NS_EDITOR_INDENT_INCREMENT_MM 10.5f
    380 #define NS_EDITOR_INDENT_INCREMENT_PT 29.76f
    381 #define NS_EDITOR_INDENT_INCREMENT_PC 2.48f
    382 #define NS_EDITOR_INDENT_INCREMENT_EM 3
    383 #define NS_EDITOR_INDENT_INCREMENT_EX 6
    384 #define NS_EDITOR_INDENT_INCREMENT_PX 40
    385 #define NS_EDITOR_INDENT_INCREMENT_PERCENT 4
    386 
    387 }  // namespace mozilla
    388 
    389 #endif  // #ifndef CSSEditUtils_h