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/. */
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
16 class nsComputedDOMStyle
;
19 class nsICSSDeclaration
;
22 class nsStyledElement
;
29 using nsProcessValueFunc
= void (*)(const nsAString
* aInputString
,
30 nsAString
& aOutputString
,
31 const char* aDefaultValueString
,
32 const char* aPrependString
,
33 const char* aAppendString
);
35 class CSSEditUtils final
{
37 // To prevent the class being instantiated
38 CSSEditUtils() = delete;
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
;
67 bool caseSensitiveValue
;
68 nsProcessValueFunc processValueFunctor
;
69 const char* defaultValue
;
70 const char* prependValue
;
71 const char* appendValue
;
75 * Adds/remove a CSS declaration to the STYLE attribute carried by a given
78 * @param aHTMLEditor [IN] An HTMLEditor instance
79 * @param aStyledElement [IN] A DOM styled element.
80 * @param aProperty [IN] An atom containing the CSS property to set.
81 * @param aValue [IN] A string containing the value of the CSS
84 [[nodiscard
]] MOZ_CAN_RUN_SCRIPT
static nsresult
85 SetCSSPropertyWithTransaction(HTMLEditor
& aHTMLEditor
,
86 nsStyledElement
& aStyledElement
,
87 nsAtom
& aProperty
, const nsAString
& aValue
) {
88 return SetCSSPropertyInternal(aHTMLEditor
, aStyledElement
, aProperty
,
91 [[nodiscard
]] MOZ_CAN_RUN_SCRIPT
static nsresult
92 SetCSSPropertyPixelsWithTransaction(HTMLEditor
& aHTMLEditor
,
93 nsStyledElement
& aStyledElement
,
94 nsAtom
& aProperty
, int32_t aIntValue
);
95 [[nodiscard
]] MOZ_CAN_RUN_SCRIPT
static nsresult
96 SetCSSPropertyPixelsWithoutTransaction(nsStyledElement
& aStyledElement
,
97 const nsAtom
& aProperty
,
99 [[nodiscard
]] MOZ_CAN_RUN_SCRIPT
static nsresult
100 RemoveCSSPropertyWithTransaction(HTMLEditor
& aHTMLEditor
,
101 nsStyledElement
& aStyledElement
,
103 const nsAString
& aPropertyValue
) {
104 return RemoveCSSPropertyInternal(aHTMLEditor
, aStyledElement
, aProperty
,
105 aPropertyValue
, false);
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).
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.
116 static nsresult
GetSpecifiedProperty(nsIContent
& aContent
,
117 nsAtom
& aCSSProperty
, nsAString
& aValue
);
118 MOZ_CAN_RUN_SCRIPT
static nsresult
GetComputedProperty(nsIContent
& aContent
,
119 nsAtom
& aCSSProperty
,
123 * Removes a CSS property from the specified declarations in STYLE attribute
124 * and removes the node if it is an useless span.
126 * @param aHTMLEditor [IN] An HTMLEditor instance
127 * @param aStyledElement [IN] The styled element we want to remove a style
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.
134 [[nodiscard
]] MOZ_CAN_RUN_SCRIPT
static Result
<EditorDOMPoint
, nsresult
>
135 RemoveCSSInlineStyleWithTransaction(HTMLEditor
& aHTMLEditor
,
136 nsStyledElement
& aStyledElement
,
138 const nsAString
& aPropertyValue
);
141 * Get the default browser background color if we need it for
142 * GetCSSBackgroundColorState().
144 * @param aColor [OUT] The default color as it is defined in prefs.
146 static void GetDefaultBackgroundColor(nsAString
& aColor
);
149 * Returns the list of values for the CSS equivalences to
150 * the passed HTML style for the passed node.
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.
156 MOZ_CAN_RUN_SCRIPT
static nsresult
GetComputedCSSEquivalentTo(
157 dom::Element
& aElement
, const EditorElementStyle
& aStyle
,
158 nsAString
& aOutValue
);
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 ?
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.
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
);
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.
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
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
);
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.
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.
214 * @return The number of CSS properties set by the call.
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
);
224 * Removes from the node the CSS inline styles equivalent to the HTML style.
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
231 * @param aValue [IN] The attribute value.
233 [[nodiscard
]] MOZ_CAN_RUN_SCRIPT
static nsresult
RemoveCSSEquivalentToStyle(
234 WithTransaction aWithTransaction
, HTMLEditor
& aHTMLEditor
,
235 nsStyledElement
& aStyledElement
, const EditorElementStyle
& aStyleToRemove
,
236 const nsAString
* aValue
);
239 * Parses a "xxxx.xxxxxuuu" string where x is a digit and u an alpha char.
241 * @param aString [IN] Input string to parse.
242 * @param aValue [OUT] Numeric part.
243 * @param aUnit [OUT] Unit part.
245 static void ParseLength(const nsAString
& aString
, float* aValue
,
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.
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
258 static bool DoStyledElementsHaveSameStyle(
259 nsStyledElement
& aStyledElement
, nsStyledElement
& aOtherStyledElement
);
262 * Gets the computed style for a given element. Can return null.
264 static already_AddRefed
<nsComputedDOMStyle
> GetComputedStyle(
265 dom::Element
* aElement
);
268 enum class StyleType
{ Specified
, Computed
};
271 * Retrieves the CSS property atom from an enum.
273 * @param aProperty The enum value for the property.
274 * @return The corresponding atom.
276 static nsStaticAtom
* GetCSSPropertyAtom(nsCSSEditableProperty aProperty
);
278 struct CSSDeclaration
{
279 nsStaticAtom
& mProperty
;
280 nsString
const mValue
;
284 * Retrieves the CSS declarations for aEquivTable.
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.
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
);
301 * Retrieves the CSS declarations equivalent to the given aStyle/aValue on
304 * @param aElement The DOM node.
305 * @param aStyle The style to get equivelent CSS properties and
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.
314 static void GetCSSDeclarations(dom::Element
& aElement
,
315 const EditorElementStyle
& aStyle
,
316 const nsAString
* aValue
,
317 HandlingFor aHandlingFor
,
318 nsTArray
<CSSDeclaration
>& aOutCSSDeclarations
);
321 * Back-end for GetSpecifiedProperty and GetComputedProperty.
323 * @param aNode [IN] A DOM node.
324 * @param aProperty [IN] A CSS property.
325 * @param aValue [OUT] The retrieved value for this property.
327 MOZ_CAN_RUN_SCRIPT
static nsresult
GetComputedCSSInlinePropertyBase(
328 nsIContent
& aContent
, nsAtom
& aCSSProperty
, nsAString
& aValue
);
329 static nsresult
GetSpecifiedCSSInlinePropertyBase(nsIContent
& aContent
,
330 nsAtom
& aCSSProperty
,
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.
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
);
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);
360 * Answers true if the given aStyle on aElement or an element whose name is
361 * aTagName has a CSS equivalence in this implementation.
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
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
);
374 friend class EditorElementStyle
; // for IsCSSEditableStyle
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
387 } // namespace mozilla
389 #endif // #ifndef CSSEditUtils_h