Bug 1686495 [wpt PR 27132] - Add tests for proposed WebDriver Shadow DOM support...
[gecko.git] / editor / libeditor / CSSEditUtils.h
bloba5f604b8f4d0e6663eb12a9e437765907b4ee747
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/. */
6 #ifndef mozilla_CSSEditUtils_h
7 #define mozilla_CSSEditUtils_h
9 #include "mozilla/ChangeStyleTransaction.h" // for ChangeStyleTransaction
10 #include "nsCOMPtr.h" // for already_AddRefed
11 #include "nsStringFwd.h"
12 #include "nsTArray.h" // for nsTArray
13 #include "nscore.h" // for nsAString, nsresult, nullptr
15 class nsComputedDOMStyle;
16 class nsAtom;
17 class nsIContent;
18 class nsICSSDeclaration;
19 class nsINode;
20 class nsStaticAtom;
21 class nsStyledElement;
23 namespace mozilla {
25 class HTMLEditor;
26 namespace dom {
27 class Element;
28 } // namespace dom
30 typedef void (*nsProcessValueFunc)(const nsAString* aInputString,
31 nsAString& aOutputString,
32 const char* aDefaultValueString,
33 const char* aPrependString,
34 const char* aAppendString);
36 class CSSEditUtils final {
37 public:
38 explicit CSSEditUtils(HTMLEditor* aEditor);
40 enum nsCSSEditableProperty {
41 eCSSEditableProperty_NONE = 0,
42 eCSSEditableProperty_background_color,
43 eCSSEditableProperty_background_image,
44 eCSSEditableProperty_border,
45 eCSSEditableProperty_caption_side,
46 eCSSEditableProperty_color,
47 eCSSEditableProperty_float,
48 eCSSEditableProperty_font_family,
49 eCSSEditableProperty_font_size,
50 eCSSEditableProperty_font_style,
51 eCSSEditableProperty_font_weight,
52 eCSSEditableProperty_height,
53 eCSSEditableProperty_list_style_type,
54 eCSSEditableProperty_margin_left,
55 eCSSEditableProperty_margin_right,
56 eCSSEditableProperty_text_align,
57 eCSSEditableProperty_text_decoration,
58 eCSSEditableProperty_vertical_align,
59 eCSSEditableProperty_whitespace,
60 eCSSEditableProperty_width
63 // Nb: keep these fields in an order that minimizes padding.
64 struct CSSEquivTable {
65 nsCSSEditableProperty cssProperty;
66 bool gettable;
67 bool caseSensitiveValue;
68 nsProcessValueFunc processValueFunctor;
69 const char* defaultValue;
70 const char* prependValue;
71 const char* appendValue;
74 /**
75 * Answers true if the given combination element_name/attribute_name
76 * has a CSS equivalence in this implementation.
78 * @param aNode [IN] A DOM node.
79 * @param aProperty [IN] An atom containing a HTML tag name.
80 * @param aAttribute [IN] An atom containing a HTML
81 * attribute carried by the element above.
82 * @return A boolean saying if the tag/attribute has a CSS
83 * equiv.
85 static bool IsCSSEditableProperty(nsINode* aNode, nsAtom* aProperty,
86 nsAtom* aAttribute);
88 /**
89 * Adds/remove a CSS declaration to the STYLE attribute carried by a given
90 * element.
92 * @param aStyledElement [IN] A DOM styled element.
93 * @param aProperty [IN] An atom containing the CSS property to set.
94 * @param aValue [IN] A string containing the value of the CSS
95 * property.
97 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
98 SetCSSPropertyWithTransaction(nsStyledElement& aStyledElement,
99 nsAtom& aProperty, const nsAString& aValue) {
100 return SetCSSPropertyInternal(aStyledElement, aProperty, aValue, false);
102 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult SetCSSPropertyPixelsWithTransaction(
103 nsStyledElement& aStyledElement, nsAtom& aProperty, int32_t aIntValue);
104 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
105 SetCSSPropertyPixelsWithoutTransaction(nsStyledElement& aStyledElement,
106 const nsAtom& aProperty,
107 int32_t aIntValue);
108 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult RemoveCSSPropertyWithTransaction(
109 nsStyledElement& aStyledElement, nsAtom& aProperty,
110 const nsAString& aPropertyValue) {
111 return RemoveCSSPropertyInternal(aStyledElement, aProperty, aPropertyValue,
112 false);
116 * Gets the specified/computed style value of a CSS property for a given
117 * node (or its element ancestor if it is not an element).
119 * @param aContent [IN] A DOM node.
120 * @param aProperty [IN] An atom containing the CSS property to get.
121 * @param aPropertyValue [OUT] The retrieved value of the property.
123 static nsresult GetSpecifiedProperty(nsIContent& aContent,
124 nsAtom& aCSSProperty, nsAString& aValue);
125 MOZ_CAN_RUN_SCRIPT static nsresult GetComputedProperty(nsIContent& aContent,
126 nsAtom& aCSSProperty,
127 nsAString& aValue);
130 * Removes a CSS property from the specified declarations in STYLE attribute
131 * and removes the node if it is an useless span.
133 * @param aStyledElement [IN] The styled element we want to remove a style
134 * from.
135 * @param aProperty [IN] The CSS property atom to remove.
136 * @param aPropertyValue [IN] The value of the property we have to remove
137 * if the property accepts more than one value.
139 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult RemoveCSSInlineStyleWithTransaction(
140 nsStyledElement& aStyledElement, nsAtom* aProperty,
141 const nsAString& aPropertyValue);
144 * Answers true is the property can be removed by setting a "none" CSS value
145 * on a node.
147 * @param aProperty [IN] An atom containing a CSS property.
148 * @param aAttribute [IN] Pointer to an attribute name or null if this
149 * information is irrelevant.
150 * @return A boolean saying if the property can be remove by
151 * setting a "none" value.
153 static bool IsCSSInvertible(nsAtom& aProperty, nsAtom* aAttribute);
156 * Get the default browser background color if we need it for
157 * GetCSSBackgroundColorState().
159 * @param aColor [OUT] The default color as it is defined in prefs.
161 static void GetDefaultBackgroundColor(nsAString& aColor);
164 * Get the default length unit used for CSS Indent/Outdent.
166 * @param aLengthUnit [OUT] The default length unit as it is defined in
167 * prefs.
169 static void GetDefaultLengthUnit(nsAString& aLengthUnit);
172 * Returns the list of values for the CSS equivalences to
173 * the passed HTML style for the passed node.
175 * @param aContent [IN] A DOM node.
176 * @param aHTMLProperty [IN] An atom containing an HTML property.
177 * @param aAttribute [IN] An atom of attribute name or nullptr if
178 * irrelevant.
179 * @param aValueString [OUT] The list of CSS values.
181 MOZ_CAN_RUN_SCRIPT static nsresult
182 GetComputedCSSEquivalentToHTMLInlineStyleSet(nsIContent& aContent,
183 nsAtom* aHTMLProperty,
184 nsAtom* aAttribute,
185 nsAString& aValue) {
186 return GetCSSEquivalentToHTMLInlineStyleSetInternal(
187 aContent, aHTMLProperty, aAttribute, aValue, StyleType::Computed);
191 * Does the node aNode (or his parent if it is not an element node) carries
192 * the CSS equivalent styles to the HTML style for this node ?
194 * @param aContent [IN] A DOM node.
195 * @param aHTMLProperty [IN] An atom containing an HTML property.
196 * @param aAttribute [IN] A pointer/atom to an attribute name or nullptr
197 * if irrelevant.
198 * @param aValueString [IN/OUT] The attribute value (in) the list of CSS
199 * values (out).
200 * @return A boolean being true if the css properties are
201 * not same as initial value.
203 MOZ_CAN_RUN_SCRIPT static bool IsComputedCSSEquivalentToHTMLInlineStyleSet(
204 nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
205 nsAString& aValue) {
206 MOZ_ASSERT(aHTMLProperty || aAttribute);
207 return IsCSSEquivalentToHTMLInlineStyleSetInternal(
208 aContent, aHTMLProperty, aAttribute, aValue, StyleType::Computed);
210 MOZ_CAN_RUN_SCRIPT_BOUNDARY static bool
211 IsSpecifiedCSSEquivalentToHTMLInlineStyleSet(nsIContent& aContent,
212 nsAtom* aHTMLProperty,
213 nsAtom* aAttribute,
214 nsAString& aValue) {
215 MOZ_ASSERT(aHTMLProperty || aAttribute);
216 return IsCSSEquivalentToHTMLInlineStyleSetInternal(
217 aContent, aHTMLProperty, aAttribute, aValue, StyleType::Specified);
221 * This is a kind of IsCSSEquivalentToHTMLInlineStyleSet.
222 * IsCSSEquivalentToHTMLInlineStyleSet returns whether the properties
223 * aren't same as initial value. But this method returns whether the
224 * properties aren't set.
225 * If node is <span style="font-weight: normal"/>,
226 * - Is(Computed|Specified)CSSEquivalentToHTMLInlineStyleSet returns false.
227 * - Have(Computed|Specified)CSSEquivalentStyles returns true.
229 * @param aContent [IN] A DOM node.
230 * @param aHTMLProperty [IN] An atom containing an HTML property.
231 * @param aAttribute [IN] An atom to an attribute name or nullptr
232 * if irrelevant.
233 * @return A boolean being true if the css properties are
234 * not set.
236 MOZ_CAN_RUN_SCRIPT static bool HaveComputedCSSEquivalentStyles(
237 nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute) {
238 MOZ_ASSERT(aHTMLProperty || aAttribute);
239 return HaveCSSEquivalentStylesInternal(aContent, aHTMLProperty, aAttribute,
240 StyleType::Computed);
242 MOZ_CAN_RUN_SCRIPT_BOUNDARY static bool HaveSpecifiedCSSEquivalentStyles(
243 nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute) {
244 MOZ_ASSERT(aHTMLProperty || aAttribute);
245 return HaveCSSEquivalentStylesInternal(aContent, aHTMLProperty, aAttribute,
246 StyleType::Specified);
250 * Adds to the node the CSS inline styles equivalent to the HTML style
251 * and return the number of CSS properties set by the call.
253 * @param aNode [IN] A DOM node.
254 * @param aHTMLProperty [IN] An atom containing an HTML property.
255 * @param aAttribute [IN] An atom to an attribute name or nullptr
256 * if irrelevant.
257 * @param aValue [IN] The attribute value.
259 * @return The number of CSS properties set by the call.
261 [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<int32_t, nsresult>
262 SetCSSEquivalentToHTMLStyleWithTransaction(nsStyledElement& aStyledElement,
263 nsAtom* aProperty,
264 nsAtom* aAttribute,
265 const nsAString* aValue) {
266 return SetCSSEquivalentToHTMLStyleInternal(aStyledElement, aProperty,
267 aAttribute, aValue, false);
269 [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<int32_t, nsresult>
270 SetCSSEquivalentToHTMLStyleWithoutTransaction(nsStyledElement& aStyledElement,
271 nsAtom* aProperty,
272 nsAtom* aAttribute,
273 const nsAString* aValue) {
274 return SetCSSEquivalentToHTMLStyleInternal(aStyledElement, aProperty,
275 aAttribute, aValue, true);
279 * Removes from the node the CSS inline styles equivalent to the HTML style.
281 * @param aStyledElement [IN] A DOM Element (must not be null).
282 * @param aHTMLProperty [IN] An atom containing an HTML property.
283 * @param aAttribute [IN] An atom to an attribute name or nullptr if
284 * irrelevant.
285 * @param aValue [IN] The attribute value.
287 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
288 RemoveCSSEquivalentToHTMLStyleWithTransaction(nsStyledElement& aStyledElement,
289 nsAtom* aHTMLProperty,
290 nsAtom* aAttribute,
291 const nsAString* aValue) {
292 return RemoveCSSEquivalentToHTMLStyleInternal(aStyledElement, aHTMLProperty,
293 aAttribute, aValue, false);
295 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
296 RemoveCSSEquivalentToHTMLStyleWithoutTransaction(
297 nsStyledElement& aStyledElement, nsAtom* aHTMLProperty,
298 nsAtom* aAttribute, const nsAString* aValue) {
299 return RemoveCSSEquivalentToHTMLStyleInternal(aStyledElement, aHTMLProperty,
300 aAttribute, aValue, true);
304 * Parses a "xxxx.xxxxxuuu" string where x is a digit and u an alpha char.
306 * @param aString [IN] Input string to parse.
307 * @param aValue [OUT] Numeric part.
308 * @param aUnit [OUT] Unit part.
310 static void ParseLength(const nsAString& aString, float* aValue,
311 nsAtom** aUnit);
314 * Sets the mIsCSSPrefChecked private member; used as callback from observer
315 * when the CSS pref state is changed.
317 * @param aIsCSSPrefChecked [IN] The new boolean state for the pref.
319 void SetCSSEnabled(bool aIsCSSPrefChecked);
322 * Retrieves the mIsCSSPrefChecked private member, true if the CSS pref is
323 * checked, false if it is not.
325 * @return the boolean value of the CSS pref.
327 bool IsCSSPrefChecked() const;
330 * DoStyledElementsHaveSameStyle compares two elements and checks if they have
331 * the same specified CSS declarations in the STYLE attribute. The answer is
332 * always false if at least one of them carries an ID or a class.
334 * @param aStyledElement [IN] A styled element.
335 * @param aOtherStyledElement [IN] The other styled element.
336 * @return true if the two elements are considered to
337 * have same styles.
339 static bool DoStyledElementsHaveSameStyle(
340 nsStyledElement& aStyledElement, nsStyledElement& aOtherStyledElement);
342 public:
344 * Gets the computed style for a given element. Can return null.
346 static already_AddRefed<nsComputedDOMStyle> GetComputedStyle(
347 dom::Element* aElement);
349 private:
350 enum class StyleType { Specified, Computed };
353 * Retrieves the CSS property atom from an enum.
355 * @param aProperty The enum value for the property.
356 * @return The corresponding atom.
358 static nsStaticAtom* GetCSSPropertyAtom(nsCSSEditableProperty aProperty);
361 * Retrieves the CSS declarations equivalent to a HTML style value for
362 * a given equivalence table.
364 * @param aOutArrayOfCSSProperty [OUT] The array of css properties.
365 * @param aOutArrayOfCSSValue [OUT] The array of values for the CSS
366 * properties above.
367 * @param aEquivTable The equivalence table.
368 * @param aValue The HTML style value.
369 * @param aGetOrRemoveRequest A boolean value being true if the call to
370 * the current method is made for
371 * Get*CSSEquivalentToHTMLInlineStyleSet()
372 * or
373 * RemoveCSSEquivalentToHTMLInlineStyleSet().
375 static void BuildCSSDeclarations(
376 nsTArray<nsStaticAtom*>& aOutArrayOfCSSProperty,
377 nsTArray<nsString>& aOutArrayOfCSSValue, const CSSEquivTable* aEquivTable,
378 const nsAString* aValue, bool aGetOrRemoveRequest);
381 * Retrieves the CSS declarations equivalent to the given HTML
382 * property/attribute/value for a given node.
384 * @param aElement The DOM node.
385 * @param aHTMLProperty An atom containing an HTML property.
386 * @param aAttribute An atom to an attribute name or nullptr
387 * if irrelevant
388 * @param aValue The attribute value.
389 * @param aOutArrayOfCSSProperty [OUT] The array of CSS properties.
390 * @param aOutArrayOfCSSValue [OUT] The array of values for the CSS
391 * properties above.
392 * @param aGetOrRemoveRequest A boolean value being true if the call to
393 * the current method is made for
394 * Get*CSSEquivalentToHTMLInlineStyleSet() or
395 * RemoveCSSEquivalentToHTMLInlineStyleSet().
397 static void GenerateCSSDeclarationsFromHTMLStyle(
398 dom::Element& aElement, nsAtom* aHTMLProperty, nsAtom* aAttribute,
399 const nsAString* aValue, nsTArray<nsStaticAtom*>& aOutArrayOfCSSProperty,
400 nsTArray<nsString>& aOutArrayOfCSSValue, bool aGetOrRemoveRequest);
403 * Back-end for GetSpecifiedProperty and GetComputedProperty.
405 * @param aNode [IN] A DOM node.
406 * @param aProperty [IN] A CSS property.
407 * @param aValue [OUT] The retrieved value for this property.
409 MOZ_CAN_RUN_SCRIPT static nsresult GetComputedCSSInlinePropertyBase(
410 nsIContent& aContent, nsAtom& aCSSProperty, nsAString& aValue);
411 static nsresult GetSpecifiedCSSInlinePropertyBase(nsIContent& aContent,
412 nsAtom& aCSSProperty,
413 nsAString& aValue);
416 * Those methods are wrapped with corresponding methods which do not have
417 * "Internal" in their names. Don't use these methods directly even if
418 * you want to use one of them in this class.
419 * Note that these methods may run scrip only when StyleType is Computed.
421 MOZ_CAN_RUN_SCRIPT static nsresult
422 GetCSSEquivalentToHTMLInlineStyleSetInternal(nsIContent& aContent,
423 nsAtom* aHTMLProperty,
424 nsAtom* aAttribute,
425 nsAString& aValue,
426 StyleType aStyleType);
427 MOZ_CAN_RUN_SCRIPT static bool IsCSSEquivalentToHTMLInlineStyleSetInternal(
428 nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
429 nsAString& aValue, StyleType aStyleType);
430 MOZ_CAN_RUN_SCRIPT static bool HaveCSSEquivalentStylesInternal(
431 nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
432 StyleType aStyleType);
434 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult RemoveCSSPropertyInternal(
435 nsStyledElement& aStyledElement, nsAtom& aProperty,
436 const nsAString& aPropertyValue, bool aSuppressTxn = false);
437 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
438 RemoveCSSEquivalentToHTMLStyleInternal(nsStyledElement& aStyledElement,
439 nsAtom* aHTMLProperty,
440 nsAtom* aAttribute,
441 const nsAString* aValue,
442 bool aSuppressTransaction);
443 [[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
444 SetCSSPropertyInternal(nsStyledElement& aStyledElement, nsAtom& aProperty,
445 const nsAString& aValue, bool aSuppressTxn = false);
446 [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<int32_t, nsresult>
447 SetCSSEquivalentToHTMLStyleInternal(nsStyledElement& aStyledElement,
448 nsAtom* aProperty, nsAtom* aAttribute,
449 const nsAString* aValue,
450 bool aSuppressTransaction);
452 private:
453 HTMLEditor* mHTMLEditor;
454 bool mIsCSSPrefChecked;
457 #define NS_EDITOR_INDENT_INCREMENT_IN 0.4134f
458 #define NS_EDITOR_INDENT_INCREMENT_CM 1.05f
459 #define NS_EDITOR_INDENT_INCREMENT_MM 10.5f
460 #define NS_EDITOR_INDENT_INCREMENT_PT 29.76f
461 #define NS_EDITOR_INDENT_INCREMENT_PC 2.48f
462 #define NS_EDITOR_INDENT_INCREMENT_EM 3
463 #define NS_EDITOR_INDENT_INCREMENT_EX 6
464 #define NS_EDITOR_INDENT_INCREMENT_PX 40
465 #define NS_EDITOR_INDENT_INCREMENT_PERCENT 4
467 } // namespace mozilla
469 #endif // #ifndef mozilla_CSSEditUtils_h