Bug 1627573 - part 4: Mark CSSEditUtils methods which refer computed style as MOZ_CAN_RUN_SCRIPT r=m_kato

When it refers computed value of style, it may flush pending notifications.
Therefore, they should be marked as `MOZ_CAN_RUN_SCRIPT`.

Differential Revision: https://phabricator.services.mozilla.com/D70151

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2020-04-08 15:51:17 +00:00
parent 2f8cf1135d
commit 1142d3105a
13 changed files with 531 additions and 382 deletions

View File

@ -654,85 +654,65 @@ void CSSEditUtils::ParseLength(const nsAString& aString, float* aValue,
}
// static
void CSSEditUtils::GetCSSPropertyAtom(nsCSSEditableProperty aProperty,
nsAtom** aAtom) {
*aAtom = nullptr;
nsStaticAtom* CSSEditUtils::GetCSSPropertyAtom(
nsCSSEditableProperty aProperty) {
switch (aProperty) {
case eCSSEditableProperty_background_color:
*aAtom = nsGkAtoms::backgroundColor;
break;
return nsGkAtoms::backgroundColor;
case eCSSEditableProperty_background_image:
*aAtom = nsGkAtoms::background_image;
break;
return nsGkAtoms::background_image;
case eCSSEditableProperty_border:
*aAtom = nsGkAtoms::border;
break;
return nsGkAtoms::border;
case eCSSEditableProperty_caption_side:
*aAtom = nsGkAtoms::caption_side;
break;
return nsGkAtoms::caption_side;
case eCSSEditableProperty_color:
*aAtom = nsGkAtoms::color;
break;
return nsGkAtoms::color;
case eCSSEditableProperty_float:
*aAtom = nsGkAtoms::_float;
break;
return nsGkAtoms::_float;
case eCSSEditableProperty_font_family:
*aAtom = nsGkAtoms::font_family;
break;
return nsGkAtoms::font_family;
case eCSSEditableProperty_font_size:
*aAtom = nsGkAtoms::font_size;
break;
return nsGkAtoms::font_size;
case eCSSEditableProperty_font_style:
*aAtom = nsGkAtoms::font_style;
break;
return nsGkAtoms::font_style;
case eCSSEditableProperty_font_weight:
*aAtom = nsGkAtoms::fontWeight;
break;
return nsGkAtoms::fontWeight;
case eCSSEditableProperty_height:
*aAtom = nsGkAtoms::height;
break;
return nsGkAtoms::height;
case eCSSEditableProperty_list_style_type:
*aAtom = nsGkAtoms::list_style_type;
break;
return nsGkAtoms::list_style_type;
case eCSSEditableProperty_margin_left:
*aAtom = nsGkAtoms::marginLeft;
break;
return nsGkAtoms::marginLeft;
case eCSSEditableProperty_margin_right:
*aAtom = nsGkAtoms::marginRight;
break;
return nsGkAtoms::marginRight;
case eCSSEditableProperty_text_align:
*aAtom = nsGkAtoms::textAlign;
break;
return nsGkAtoms::textAlign;
case eCSSEditableProperty_text_decoration:
*aAtom = nsGkAtoms::text_decoration;
break;
return nsGkAtoms::text_decoration;
case eCSSEditableProperty_vertical_align:
*aAtom = nsGkAtoms::vertical_align;
break;
return nsGkAtoms::vertical_align;
case eCSSEditableProperty_whitespace:
*aAtom = nsGkAtoms::white_space;
break;
return nsGkAtoms::white_space;
case eCSSEditableProperty_width:
*aAtom = nsGkAtoms::width;
break;
return nsGkAtoms::width;
case eCSSEditableProperty_NONE:
// intentionally empty
break;
return nullptr;
}
}
// Populate aProperty and aValueArray with the CSS declarations equivalent to
// the value aValue according to the equivalence table aEquivTable
// Populate aOutArrayOfCSSProperty and aOutArrayOfCSSValue with the CSS
// declarations equivalent to the value aValue according to the equivalence
// table aEquivTable
// static
void CSSEditUtils::BuildCSSDeclarations(nsTArray<nsAtom*>& aPropertyArray,
nsTArray<nsString>& aValueArray,
const CSSEquivTable* aEquivTable,
const nsAString* aValue,
bool aGetOrRemoveRequest) {
void CSSEditUtils::BuildCSSDeclarations(
nsTArray<nsStaticAtom*>& aOutArrayOfCSSProperty,
nsTArray<nsString>& aOutArrayOfCSSValue, const CSSEquivTable* aEquivTable,
const nsAString* aValue, bool aGetOrRemoveRequest) {
// clear arrays
aPropertyArray.Clear();
aValueArray.Clear();
aOutArrayOfCSSProperty.Clear();
aOutArrayOfCSSValue.Clear();
// if we have an input value, let's use it
nsAutoString value, lowerCasedValue;
@ -747,7 +727,6 @@ void CSSEditUtils::BuildCSSDeclarations(nsTArray<nsAtom*>& aPropertyArray,
while (cssProperty) {
if (!aGetOrRemoveRequest || aEquivTable[index].gettable) {
nsAutoString cssValue, cssPropertyString;
nsAtom* cssPropertyAtom;
// find the equivalent css value for the index-th property in
// the equivalence table
(*aEquivTable[index].processValueFunctor)(
@ -756,24 +735,22 @@ void CSSEditUtils::BuildCSSDeclarations(nsTArray<nsAtom*>& aPropertyArray,
: &lowerCasedValue,
cssValue, aEquivTable[index].defaultValue,
aEquivTable[index].prependValue, aEquivTable[index].appendValue);
GetCSSPropertyAtom(cssProperty, &cssPropertyAtom);
aPropertyArray.AppendElement(cssPropertyAtom);
aValueArray.AppendElement(cssValue);
aOutArrayOfCSSProperty.AppendElement(GetCSSPropertyAtom(cssProperty));
aOutArrayOfCSSValue.AppendElement(cssValue);
}
index++;
cssProperty = aEquivTable[index].cssProperty;
}
}
// Populate cssPropertyArray and cssValueArray with the declarations equivalent
// to aHTMLProperty/aAttribute/aValue for the node aNode
// Populate aOutArrayOfCSSProperty and aOutArrayOfCSSValue with the declarations
// equivalent to aHTMLProperty/aAttribute/aValue for the node aNode
// static
void CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
Element* aElement, nsAtom* aHTMLProperty, nsAtom* aAttribute,
const nsAString* aValue, nsTArray<nsAtom*>& cssPropertyArray,
nsTArray<nsString>& cssValueArray, bool aGetOrRemoveRequest) {
MOZ_ASSERT(aElement);
Element& aElement, nsAtom* aHTMLProperty, nsAtom* aAttribute,
const nsAString* aValue, nsTArray<nsStaticAtom*>& aOutArrayOfCSSProperty,
nsTArray<nsString>& aOutArrayOfCSSValue, bool aGetOrRemoveRequest) {
const CSSEditUtils::CSSEquivTable* equivTable = nullptr;
if (nsGkAtoms::b == aHTMLProperty) {
@ -801,12 +778,12 @@ void CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
} else if (aAttribute == nsGkAtoms::border) {
equivTable = borderEquivTable;
} else if (aAttribute == nsGkAtoms::align) {
if (aElement->IsHTMLElement(nsGkAtoms::table)) {
if (aElement.IsHTMLElement(nsGkAtoms::table)) {
equivTable = tableAlignEquivTable;
} else if (aElement->IsHTMLElement(nsGkAtoms::hr)) {
} else if (aElement.IsHTMLElement(nsGkAtoms::hr)) {
equivTable = hrAlignEquivTable;
} else if (aElement->IsAnyOfHTMLElements(nsGkAtoms::legend,
nsGkAtoms::caption)) {
} else if (aElement.IsAnyOfHTMLElements(nsGkAtoms::legend,
nsGkAtoms::caption)) {
equivTable = captionAlignEquivTable;
} else {
equivTable = textAlignEquivTable;
@ -818,18 +795,18 @@ void CSSEditUtils::GenerateCSSDeclarationsFromHTMLStyle(
} else if (aAttribute == nsGkAtoms::width) {
equivTable = widthEquivTable;
} else if (aAttribute == nsGkAtoms::height ||
(aElement->IsHTMLElement(nsGkAtoms::hr) &&
(aElement.IsHTMLElement(nsGkAtoms::hr) &&
aAttribute == nsGkAtoms::size)) {
equivTable = heightEquivTable;
} else if (aAttribute == nsGkAtoms::type &&
aElement->IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul,
nsGkAtoms::li)) {
aElement.IsAnyOfHTMLElements(nsGkAtoms::ol, nsGkAtoms::ul,
nsGkAtoms::li)) {
equivTable = listStyleTypeEquivTable;
}
}
if (equivTable) {
BuildCSSDeclarations(cssPropertyArray, cssValueArray, equivTable, aValue,
aGetOrRemoveRequest);
BuildCSSDeclarations(aOutArrayOfCSSProperty, aOutArrayOfCSSValue,
equivTable, aValue, aGetOrRemoveRequest);
}
}
@ -851,9 +828,9 @@ int32_t CSSEditUtils::SetCSSEquivalentToHTMLStyle(Element* aElement,
// an equivalence for the requested HTML style in this implementation
// Find the CSS equivalence to the HTML style
nsTArray<nsAtom*> cssPropertyArray;
nsTArray<nsStaticAtom*> cssPropertyArray;
nsTArray<nsString> cssValueArray;
GenerateCSSDeclarationsFromHTMLStyle(aElement, aHTMLProperty, aAttribute,
GenerateCSSDeclarationsFromHTMLStyle(*aElement, aHTMLProperty, aAttribute,
aValue, cssPropertyArray, cssValueArray,
false);
@ -888,9 +865,9 @@ nsresult CSSEditUtils::RemoveCSSEquivalentToHTMLStyle(
// an equivalence for the requested HTML style in this implementation
// Find the CSS equivalence to the HTML style
nsTArray<nsAtom*> cssPropertyArray;
nsTArray<nsStaticAtom*> cssPropertyArray;
nsTArray<nsString> cssValueArray;
GenerateCSSDeclarationsFromHTMLStyle(aElement, aHTMLProperty, aAttribute,
GenerateCSSDeclarationsFromHTMLStyle(*aElement, aHTMLProperty, aAttribute,
aValue, cssPropertyArray, cssValueArray,
true);
@ -931,11 +908,11 @@ nsresult CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSetInternal(
}
// Yes, the requested HTML style has a CSS equivalence in this implementation
nsTArray<nsAtom*> cssPropertyArray;
nsTArray<nsStaticAtom*> cssPropertyArray;
nsTArray<nsString> cssValueArray;
// get the CSS equivalence with last param true indicating we want only the
// "gettable" properties
GenerateCSSDeclarationsFromHTMLStyle(theElement, aHTMLProperty, aAttribute,
GenerateCSSDeclarationsFromHTMLStyle(*theElement, aHTMLProperty, aAttribute,
nullptr, cssPropertyArray, cssValueArray,
true);
int32_t count = cssPropertyArray.Length();
@ -944,7 +921,7 @@ nsresult CSSEditUtils::GetCSSEquivalentToHTMLInlineStyleSetInternal(
// retrieve the specified/computed value of the property
if (aStyleType == StyleType::Computed) {
nsresult rv = GetComputedCSSInlinePropertyBase(
*theElement, *cssPropertyArray[index], valueString);
*theElement, MOZ_KnownLive(*cssPropertyArray[index]), valueString);
if (NS_FAILED(rv)) {
NS_WARNING("CSSEditUtils::GetComputedCSSInlinePropertyBase() failed");
return rv;

View File

@ -17,6 +17,7 @@ class nsAtom;
class nsIContent;
class nsICSSDeclaration;
class nsINode;
class nsStaticAtom;
namespace mozilla {
@ -115,8 +116,9 @@ class CSSEditUtils final {
*/
static nsresult GetSpecifiedProperty(nsIContent& aContent,
nsAtom& aCSSProperty, nsAString& aValue);
static nsresult GetComputedProperty(nsIContent& aContent,
nsAtom& aCSSProperty, nsAString& aValue);
MOZ_CAN_RUN_SCRIPT static nsresult GetComputedProperty(nsIContent& aContent,
nsAtom& aCSSProperty,
nsAString& aValue);
/**
* Removes a CSS property from the specified declarations in STYLE attribute
@ -169,9 +171,11 @@ class CSSEditUtils final {
* irrelevant.
* @param aValueString [OUT] The list of CSS values.
*/
static nsresult GetComputedCSSEquivalentToHTMLInlineStyleSet(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
nsAString& aValue) {
MOZ_CAN_RUN_SCRIPT static nsresult
GetComputedCSSEquivalentToHTMLInlineStyleSet(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute,
nsAString& aValue) {
return GetCSSEquivalentToHTMLInlineStyleSetInternal(
aContent, aHTMLProperty, aAttribute, aValue, StyleType::Computed);
}
@ -189,17 +193,18 @@ class CSSEditUtils final {
* @return A boolean being true if the css properties are
* not same as initial value.
*/
static bool IsComputedCSSEquivalentToHTMLInlineStyleSet(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute,
nsAString& aValue) {
MOZ_CAN_RUN_SCRIPT static bool IsComputedCSSEquivalentToHTMLInlineStyleSet(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
nsAString& aValue) {
MOZ_ASSERT(aHTMLProperty || aAttribute);
return IsCSSEquivalentToHTMLInlineStyleSetInternal(
aContent, aHTMLProperty, aAttribute, aValue, StyleType::Computed);
}
static bool IsSpecifiedCSSEquivalentToHTMLInlineStyleSet(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
nsAString& aValue) {
MOZ_CAN_RUN_SCRIPT_BOUNDARY static bool
IsSpecifiedCSSEquivalentToHTMLInlineStyleSet(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute,
nsAString& aValue) {
MOZ_ASSERT(aHTMLProperty || aAttribute);
return IsCSSEquivalentToHTMLInlineStyleSetInternal(
aContent, aHTMLProperty, aAttribute, aValue, StyleType::Specified);
@ -221,16 +226,14 @@ class CSSEditUtils final {
* @return A boolean being true if the css properties are
* not set.
*/
static bool HaveComputedCSSEquivalentStyles(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute) {
MOZ_CAN_RUN_SCRIPT static bool HaveComputedCSSEquivalentStyles(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute) {
MOZ_ASSERT(aHTMLProperty || aAttribute);
return HaveCSSEquivalentStylesInternal(aContent, aHTMLProperty, aAttribute,
StyleType::Computed);
}
static bool HaveSpecifiedCSSEquivalentStyles(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute) {
MOZ_CAN_RUN_SCRIPT_BOUNDARY static bool HaveSpecifiedCSSEquivalentStyles(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute) {
MOZ_ASSERT(aHTMLProperty || aAttribute);
return HaveCSSEquivalentStylesInternal(aContent, aHTMLProperty, aAttribute,
StyleType::Specified);
@ -334,53 +337,52 @@ class CSSEditUtils final {
/**
* Retrieves the CSS property atom from an enum.
*
* @param aProperty [IN] The enum value for the property.
* @param aAtom [OUT] The corresponding atom.
* @param aProperty The enum value for the property.
* @return The corresponding atom.
*/
static void GetCSSPropertyAtom(nsCSSEditableProperty aProperty,
nsAtom** aAtom);
static nsStaticAtom* GetCSSPropertyAtom(nsCSSEditableProperty aProperty);
/**
* 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
* Get*CSSEquivalentToHTMLInlineStyleSet() or
* RemoveCSSEquivalentToHTMLInlineStyleSet().
* @param aOutArrayOfCSSProperty [OUT] The array of css properties.
* @param aOutArrayOfCSSValue [OUT] The array of values for the CSS
* properties above.
* @param aEquivTable The equivalence table.
* @param aValue The HTML style value.
* @param aGetOrRemoveRequest A boolean value being true if the call to
* the current method is made for
* Get*CSSEquivalentToHTMLInlineStyleSet()
* or
* RemoveCSSEquivalentToHTMLInlineStyleSet().
*/
static void BuildCSSDeclarations(nsTArray<nsAtom*>& aPropertyArray,
nsTArray<nsString>& cssValueArray,
const CSSEquivTable* aEquivTable,
const nsAString* aValue,
bool aGetOrRemoveRequest);
static void BuildCSSDeclarations(
nsTArray<nsStaticAtom*>& aOutArrayOfCSSProperty,
nsTArray<nsString>& aOutArrayOfCSSValue, 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] An atom to an attribute name or nullptr
* @param aElement The DOM node.
* @param aHTMLProperty An atom containing an HTML property.
* @param aAttribute An atom 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
* Get*CSSEquivalentToHTMLInlineStyleSet() or
* RemoveCSSEquivalentToHTMLInlineStyleSet().
* @param aValue The attribute value.
* @param aOutArrayOfCSSProperty [OUT] The array of CSS properties.
* @param aOutArrayOfCSSValue [OUT] The array of values for the CSS
* properties above.
* @param aGetOrRemoveRequest A boolean value being true if the call to
* the current method is made for
* Get*CSSEquivalentToHTMLInlineStyleSet() or
* RemoveCSSEquivalentToHTMLInlineStyleSet().
*/
static void GenerateCSSDeclarationsFromHTMLStyle(
dom::Element* aNode, nsAtom* aHTMLProperty, nsAtom* aAttribute,
const nsAString* aValue, nsTArray<nsAtom*>& aPropertyArray,
nsTArray<nsString>& aValueArray, bool aGetOrRemoveRequest);
dom::Element& aElement, nsAtom* aHTMLProperty, nsAtom* aAttribute,
const nsAString* aValue, nsTArray<nsStaticAtom*>& aOutArrayOfCSSProperty,
nsTArray<nsString>& aOutArrayOfCSSValue, bool aGetOrRemoveRequest);
/**
* Back-end for GetSpecifiedProperty and GetComputedProperty.
@ -389,9 +391,8 @@ class CSSEditUtils final {
* @param aProperty [IN] A CSS property.
* @param aValue [OUT] The retrieved value for this property.
*/
static nsresult GetComputedCSSInlinePropertyBase(nsIContent& aContent,
nsAtom& aCSSProperty,
nsAString& aValue);
MOZ_CAN_RUN_SCRIPT static nsresult GetComputedCSSInlinePropertyBase(
nsIContent& aContent, nsAtom& aCSSProperty, nsAString& aValue);
static nsresult GetSpecifiedCSSInlinePropertyBase(nsIContent& aContent,
nsAtom& aCSSProperty,
nsAString& aValue);
@ -400,19 +401,20 @@ class CSSEditUtils final {
* Those methods are wrapped with corresponding methods which do not have
* "Internal" in their names. Don't use these methods directly even if
* you want to use one of them in this class.
* Note that these methods may run scrip only when StyleType is Computed.
*/
static nsresult GetCSSEquivalentToHTMLInlineStyleSetInternal(
MOZ_CAN_RUN_SCRIPT static nsresult
GetCSSEquivalentToHTMLInlineStyleSetInternal(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute,
nsAString& aValue,
StyleType aStyleType);
MOZ_CAN_RUN_SCRIPT static bool IsCSSEquivalentToHTMLInlineStyleSetInternal(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
nsAString& aValue, StyleType aStyleType);
static bool IsCSSEquivalentToHTMLInlineStyleSetInternal(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute,
nsAString& aValue,
StyleType aStyleType);
static bool HaveCSSEquivalentStylesInternal(nsIContent& aContent,
nsAtom* aHTMLProperty,
nsAtom* aAttribute,
StyleType aStyleType);
MOZ_CAN_RUN_SCRIPT static bool HaveCSSEquivalentStylesInternal(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute,
StyleType aStyleType);
private:
HTMLEditor* mHTMLEditor;

View File

@ -20,6 +20,7 @@ class nsCommandParams;
class nsICommandParams;
class nsIEditingSession;
class nsITransferable;
class nsStaticAtom;
namespace mozilla {
@ -579,10 +580,10 @@ class StateUpdatingCommandBase : public EditorCommand {
// add/remove the style
MOZ_CAN_RUN_SCRIPT virtual nsresult ToggleState(
nsAtom* aTagName, HTMLEditor* aHTMLEditor,
nsStaticAtom& aTagName, HTMLEditor& aHTMLEditor,
nsIPrincipal* aPrincipal) const = 0;
static nsAtom* GetTagName(Command aCommand) {
static nsStaticAtom* GetTagName(Command aCommand) {
switch (aCommand) {
case Command::FormatBold:
return nsGkAtoms::b;
@ -651,8 +652,8 @@ class StyleUpdatingCommand final : public StateUpdatingCommandBase {
nsCommandParams& aParams) const final;
// add/remove the style
MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsAtom* aTagName,
HTMLEditor* aHTMLEditor,
MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsStaticAtom& aTagName,
HTMLEditor& aHTMLEditor,
nsIPrincipal* aPrincipal) const final;
};
@ -697,8 +698,8 @@ class ListCommand final : public StateUpdatingCommandBase {
nsCommandParams& aParams) const final;
// add/remove the style
MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsAtom* aTagName,
HTMLEditor* aHTMLEditor,
MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsStaticAtom& aTagName,
HTMLEditor& aHTMLEditor,
nsIPrincipal* aPrincipal) const final;
};
@ -716,8 +717,8 @@ class ListItemCommand final : public StateUpdatingCommandBase {
nsCommandParams& aParams) const final;
// add/remove the style
MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsAtom* aTagName,
HTMLEditor* aHTMLEditor,
MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsStaticAtom& aTagName,
HTMLEditor& aHTMLEditor,
nsIPrincipal* aPrincipal) const final;
};
@ -856,8 +857,8 @@ class AbsolutePositioningCommand final : public StateUpdatingCommandBase {
MOZ_CAN_RUN_SCRIPT nsresult
GetCurrentState(nsAtom* aTagName, HTMLEditor* aHTMLEditor,
nsCommandParams& aParams) const final;
MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsAtom* aTagName,
HTMLEditor* aHTMLEditor,
MOZ_CAN_RUN_SCRIPT nsresult ToggleState(nsStaticAtom& aTagName,
HTMLEditor& aHTMLEditor,
nsIPrincipal* aPrincipal) const final;
};

View File

@ -14,12 +14,13 @@
#include "mozilla/RangeBoundary.h"
#include "mozilla/dom/Selection.h"
#include "mozilla/dom/StaticRange.h"
#include "nsAtom.h"
#include "nscore.h"
#include "nsCOMPtr.h"
#include "nsDebug.h"
#include "nsRange.h"
#include "nscore.h"
#include "nsString.h"
class nsAtom;
class nsISimpleEnumerator;
class nsITransferable;
@ -802,6 +803,13 @@ class EditorUtils final {
static void MaskString(nsString& aString, dom::Text* aText,
uint32_t aStartOffsetInString,
uint32_t aStartOffsetInText);
static nsStaticAtom* GetAttributeAtom(const nsAString& aAttribute) {
if (aAttribute.IsEmpty()) {
return nullptr; // Don't use nsGkAtoms::_empty for attribute.
}
return NS_GetStaticAtom(aAttribute);
}
};
} // namespace mozilla

View File

@ -2,7 +2,7 @@
* 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/. */
#include "mozilla/HTMLEditor.h"
#include "HTMLEditor.h"
#include <math.h>
@ -78,24 +78,35 @@ HTMLEditor::GetAbsolutelyPositionedSelectionContainer() const {
return nullptr;
}
nsAutoString positionValue;
AutoTArray<RefPtr<Element>, 24> arrayOfParentElements;
for (Element* element :
InclusiveAncestorsOfType<Element>(*selectionContainerElement)) {
arrayOfParentElements.AppendElement(element);
}
nsAutoString positionValue;
for (RefPtr<Element> element = selectionContainerElement; element;
element = element->GetParentElement()) {
if (element->IsHTMLElement(nsGkAtoms::html)) {
NS_WARNING(
"HTMLEditor::GetAbsolutelyPositionedSelectionContainer() reached "
"<html> element");
return nullptr;
}
nsCOMPtr<nsINode> parentNode = element->GetParentNode();
nsresult rv = CSSEditUtils::GetComputedProperty(
*element, *nsGkAtoms::position, positionValue);
MOZ_KnownLive(*element), *nsGkAtoms::position, positionValue);
if (NS_FAILED(rv)) {
NS_WARNING(
"CSSEditUtils::GetComputedProperty(nsGkAtoms::position) failed");
return nullptr;
}
if (NS_WARN_IF(Destroyed()) ||
NS_WARN_IF(parentNode != element->GetParentNode())) {
return nullptr;
}
if (positionValue.EqualsLiteral("absolute")) {
return do_AddRef(element);
return element.forget();
}
}
return nullptr;
@ -123,11 +134,14 @@ nsresult HTMLEditor::RelativeChangeElementZIndex(Element& aElement,
}
int32_t zIndex = GetZIndex(aElement);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
zIndex = std::max(zIndex + aChange, 0);
SetZIndex(aElement, zIndex);
*aReturn = zIndex;
return NS_OK;
return NS_WARN_IF(Destroyed()) ? NS_ERROR_EDITOR_DESTROYED : NS_OK;
}
void HTMLEditor::SetZIndex(Element& aElement, int32_t aZIndex) {
@ -182,11 +196,12 @@ int32_t HTMLEditor::GetZIndex(Element& aElement) {
// we have to look at the positioned ancestors
// cf. CSS 2 spec section 9.9.1
nsAutoString positionValue;
for (Element* element :
InclusiveAncestorsOfType<Element>(*aElement.GetParentElement())) {
for (RefPtr<Element> element = aElement.GetParentElement(); element;
element = element->GetParentElement()) {
if (element->IsHTMLElement(nsGkAtoms::body)) {
return 0;
}
nsCOMPtr<nsINode> parentNode = element->GetParentElement();
nsresult rv = CSSEditUtils::GetComputedProperty(
*element, *nsGkAtoms::position, positionValue);
if (NS_FAILED(rv)) {
@ -194,6 +209,10 @@ int32_t HTMLEditor::GetZIndex(Element& aElement) {
"CSSEditUtils::GetComputedProperty(nsGkAtoms::position) failed");
return 0;
}
if (NS_WARN_IF(Destroyed()) ||
NS_WARN_IF(parentNode != element->GetParentNode())) {
return 0;
}
if (!positionValue.EqualsLiteral("absolute")) {
continue;
}
@ -206,6 +225,10 @@ int32_t HTMLEditor::GetZIndex(Element& aElement) {
"CSSEditUtils::GetComputedProperty(nsGkAtoms::z_index) failed");
return 0;
}
if (NS_WARN_IF(Destroyed()) ||
NS_WARN_IF(parentNode != element->GetParentNode())) {
return 0;
}
if (!zIndexValue.EqualsLiteral("auto")) {
break;
}
@ -269,8 +292,10 @@ nsresult HTMLEditor::RefreshGrabberInternal() {
if (!mAbsolutelyPositionedObject) {
return NS_OK;
}
OwningNonNull<Element> absolutelyPositionedObject =
*mAbsolutelyPositionedObject;
nsresult rv = GetPositionAndDimensions(
*mAbsolutelyPositionedObject, mPositionedObjectX, mPositionedObjectY,
absolutelyPositionedObject, mPositionedObjectX, mPositionedObjectY,
mPositionedObjectWidth, mPositionedObjectHeight,
mPositionedObjectBorderLeft, mPositionedObjectBorderTop,
mPositionedObjectMarginLeft, mPositionedObjectMarginTop);
@ -278,11 +303,20 @@ nsresult HTMLEditor::RefreshGrabberInternal() {
NS_WARNING("HTMLEditor::GetPositionAndDimensions() failed");
return rv;
}
if (NS_WARN_IF(absolutelyPositionedObject != mAbsolutelyPositionedObject)) {
return NS_ERROR_FAILURE;
}
RefPtr<Element> grabber = mGrabber.get();
MOZ_ASSERT(grabber);
SetAnonymousElementPosition(mPositionedObjectX + 12, mPositionedObjectY - 14,
grabber);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(grabber != mGrabber.get())) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
@ -724,6 +758,9 @@ nsresult HTMLEditor::GetTemporaryStyleForFocusedPositionedElement(
RefPtr<ComputedStyle> style =
nsComputedDOMStyle::GetComputedStyle(&aElement, nullptr);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (!style) {
NS_WARNING("nsComputedDOMStyle::GetComputedStyle() failed");
return NS_ERROR_FAILURE;

View File

@ -2,7 +2,7 @@
* 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/. */
#include "mozilla/HTMLEditor.h"
#include "HTMLEditor.h"
#include "mozilla/Attributes.h"
#include "mozilla/PresShell.h"
@ -361,6 +361,9 @@ nsresult HTMLEditor::RefreshEditingUI() {
// Absolute Positioning support is enabled, is the selection contained
// in an absolutely positioned element ?
absPosElement = GetAbsolutelyPositionedSelectionContainer();
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
}
RefPtr<Element> cellElement;
@ -505,6 +508,9 @@ nsresult HTMLEditor::GetPositionAndDimensions(Element& aElement, int32_t& aX,
nsAutoString positionValue;
DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetComputedProperty(
aElement, *nsGkAtoms::position, positionValue);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"CSSEditUtils::GetComputedProperty(nsGkAtoms::"
"position) failed, but ignored");

View File

@ -4,11 +4,12 @@
* 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/. */
#include "HTMLEditor.h"
#include <algorithm>
#include <utility>
#include "HTMLEditUtils.h"
#include "HTMLEditor.h"
#include "WSRunObject.h"
#include "mozilla/Assertions.h"
#include "mozilla/CSSEditUtils.h"
@ -948,7 +949,8 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
editTargetContent = arrayOfContents[0];
}
Element* blockElementAtEditTarget = HTMLEditor::GetBlock(*editTargetContent);
RefPtr<Element> blockElementAtEditTarget =
HTMLEditor::GetBlock(*editTargetContent);
if (NS_WARN_IF(!blockElementAtEditTarget)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
@ -963,6 +965,10 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
DebugOnly<nsresult> rvIgnored =
CSSEditUtils::GetComputedCSSEquivalentToHTMLInlineStyleSet(
*blockElementAtEditTarget, nullptr, nsGkAtoms::align, value);
if (NS_WARN_IF(aHTMLEditor.Destroyed())) {
aRv.Throw(NS_ERROR_EDITOR_DESTROYED);
return;
}
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
"CSSEditUtils::GetComputedCSSEquivalentToHTMLInlineStyleSet(nsGkAtoms::"
@ -1057,7 +1063,8 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
}
}
static nsStaticAtom& MarginPropertyAtomForIndent(nsIContent& aContent) {
MOZ_CAN_RUN_SCRIPT static nsStaticAtom& MarginPropertyAtomForIndent(
nsIContent& aContent) {
nsAutoString direction;
DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetComputedProperty(
aContent, *nsGkAtoms::direction, direction);
@ -5995,7 +6002,7 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() {
RefPtr<Element> indentedParentElement;
nsCOMPtr<nsIContent> firstContentToBeOutdented, lastContentToBeOutdented;
BlockIndentedWith indentedParentIndentedWith = BlockIndentedWith::HTML;
for (auto& content : arrayOfContents) {
for (OwningNonNull<nsIContent>& content : arrayOfContents) {
// Here's where we actually figure out what to do
EditorDOMPoint atContent(content);
if (!atContent.IsSet()) {
@ -6038,7 +6045,11 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() {
// If we're using CSS and the node is a block element, check its start
// margin whether it's indented with CSS.
if (useCSS && HTMLEditor::NodeIsBlockStatic(content)) {
nsStaticAtom& marginProperty = MarginPropertyAtomForIndent(content);
nsStaticAtom& marginProperty =
MarginPropertyAtomForIndent(MOZ_KnownLive(content));
if (NS_WARN_IF(Destroyed())) {
return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED);
}
nsAutoString value;
DebugOnly<nsresult> rvIgnored =
CSSEditUtils::GetSpecifiedProperty(content, marginProperty, value);
@ -6149,7 +6160,15 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() {
continue;
}
nsStaticAtom& marginProperty = MarginPropertyAtomForIndent(content);
nsCOMPtr<nsINode> grandParentNode = parentContent->GetParentNode();
nsStaticAtom& marginProperty =
MarginPropertyAtomForIndent(MOZ_KnownLive(content));
if (NS_WARN_IF(Destroyed())) {
return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_DESTROYED);
}
if (NS_WARN_IF(grandParentNode != parentContent->GetParentNode())) {
return SplitRangeOffFromNodeResult(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
}
nsAutoString value;
DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetSpecifiedProperty(
*parentContent, marginProperty, value);
@ -9862,7 +9881,7 @@ nsresult HTMLEditor::GetInlineStyles(nsIContent& aContent,
&value);
} else {
isSet = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
aContent, tag, attribute, value);
aContent, MOZ_KnownLive(tag), MOZ_KnownLive(attribute), value);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
@ -9918,8 +9937,8 @@ nsresult HTMLEditor::ReapplyCachedStyles() {
if (useCSS) {
// check computed style first in css case
isAny = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
*startContainerContent, styleCacheBeforeEdit.Tag(),
styleCacheBeforeEdit.GetAttribute(), currentValue);
*startContainerContent, MOZ_KnownLive(styleCacheBeforeEdit.Tag()),
MOZ_KnownLive(styleCacheBeforeEdit.GetAttribute()), currentValue);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
@ -9927,12 +9946,10 @@ nsresult HTMLEditor::ReapplyCachedStyles() {
if (!isAny) {
// then check typeinstate and html style
nsresult rv = GetInlinePropertyBase(
*styleCacheBeforeEdit.Tag(), styleCacheBeforeEdit.GetAttribute(),
MOZ_KnownLive(*styleCacheBeforeEdit.Tag()),
MOZ_KnownLive(styleCacheBeforeEdit.GetAttribute()),
&styleCacheBeforeEdit.Value(), &isFirst, &isAny, &isAll,
&currentValue);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_FAILED(rv)) {
NS_WARNING("HTMLEditor::GetInlinePropertyBase() failed");
return rv;
@ -11065,6 +11082,9 @@ nsresult HTMLEditor::ChangeMarginStart(Element& aElement,
MOZ_ASSERT(IsEditActionDataAvailable());
nsStaticAtom& marginProperty = MarginPropertyAtomForIndent(aElement);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
nsAutoString value;
DebugOnly<nsresult> rvIgnored =
CSSEditUtils::GetSpecifiedProperty(aElement, marginProperty, value);
@ -11580,6 +11600,9 @@ EditActionResult HTMLEditor::SetSelectionToStaticAsSubAction() {
RefPtr<Element> element = GetAbsolutelyPositionedSelectionContainer();
if (!element) {
if (NS_WARN_IF(Destroyed())) {
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
}
NS_WARNING(
"HTMLEditor::GetAbsolutelyPositionedSelectionContainer() returned "
"nullptr");
@ -11658,6 +11681,9 @@ EditActionResult HTMLEditor::AddZIndexAsSubAction(int32_t aChange) {
RefPtr<Element> absolutelyPositionedElement =
GetAbsolutelyPositionedSelectionContainer();
if (!absolutelyPositionedElement) {
if (NS_WARN_IF(Destroyed())) {
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
}
NS_WARNING(
"HTMLEditor::GetAbsolutelyPositionedSelectionContainer() returned "
"nullptr");
@ -11670,9 +11696,6 @@ EditActionResult HTMLEditor::AddZIndexAsSubAction(int32_t aChange) {
int32_t zIndex;
nsresult rv = RelativeChangeElementZIndex(*absolutelyPositionedElement,
aChange, &zIndex);
if (NS_WARN_IF(Destroyed())) {
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
}
if (NS_FAILED(rv)) {
NS_WARNING("HTMLEditor::RelativeChangeElementZIndex() failed");
return EditActionHandled(rv);

View File

@ -3,7 +3,7 @@
* 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/. */
#include "mozilla/HTMLEditor.h"
#include "HTMLEditor.h"
#include "mozilla/ComposerCommandsUpdater.h"
#include "mozilla/ContentIterator.h"
@ -2049,13 +2049,13 @@ nsresult HTMLEditor::GetBackgroundColorState(bool* aMixed,
nsresult rv = GetCSSBackgroundColorState(aMixed, aOutColor, true);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::GetCSSBackgroundColorState() failed");
return rv;
return EditorBase::ToGenericNSResult(rv);
}
// in HTML mode, we look only at page's background
nsresult rv = GetHTMLBackgroundColorState(aMixed, aOutColor);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::GetCSSBackgroundColorState() failed");
return rv;
return EditorBase::ToGenericNSResult(rv);
}
NS_IMETHODIMP HTMLEditor::GetHighlightColorState(bool* aMixed,
@ -2108,7 +2108,7 @@ nsresult HTMLEditor::GetCSSBackgroundColorState(bool* aMixed,
}
// is the selection collapsed?
nsCOMPtr<nsIContent> contentToExamine;
nsIContent* contentToExamine;
if (SelectionRefPtr()->IsCollapsed() || IsTextNode(startContainer)) {
// we want to look at the startContainer and ancestors
contentToExamine = startContainer->AsContent();
@ -2126,20 +2126,33 @@ nsresult HTMLEditor::GetCSSBackgroundColorState(bool* aMixed,
if (aBlockLevel) {
// we are querying the block background (and not the text background), let's
// climb to the block container
nsCOMPtr<Element> blockParent = GetBlock(*contentToExamine);
Element* blockParent = GetBlock(*contentToExamine);
if (NS_WARN_IF(!blockParent)) {
return NS_OK;
}
// Make sure to not walk off onto the Document node
do {
for (RefPtr<Element> element = blockParent; element;
element = element->GetParentElement()) {
nsCOMPtr<nsINode> parentNode = element->GetParentNode();
// retrieve the computed style of background-color for blockParent
CSSEditUtils::GetComputedProperty(*blockParent,
*nsGkAtoms::backgroundColor, aOutColor);
blockParent = blockParent->GetParentElement();
DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetComputedProperty(
*element, *nsGkAtoms::backgroundColor, aOutColor);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(parentNode != element->GetParentNode())) {
return NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"CSSEditUtils::GetComputedProperty(nsGkAtoms::"
"backgroundColor) failed, but ignored");
// look at parent if the queried color is transparent and if the node to
// examine is not the root of the document
} while (aOutColor.EqualsLiteral("transparent") && blockParent);
if (!aOutColor.EqualsLiteral("transparent")) {
break;
}
}
if (aOutColor.EqualsLiteral("transparent")) {
// we have hit the root of the document and the color is still transparent
// ! Grumble... Let's look at the default background color because that's
@ -2156,24 +2169,36 @@ nsresult HTMLEditor::GetCSSBackgroundColorState(bool* aMixed,
if (!contentToExamine) {
return NS_OK;
}
do {
for (RefPtr<Element> element =
contentToExamine->GetAsElementOrParentElement();
element; element = element->GetParentElement()) {
// is the node to examine a block ?
if (HTMLEditor::NodeIsBlockStatic(*contentToExamine)) {
if (HTMLEditor::NodeIsBlockStatic(*element)) {
// yes it is a block; in that case, the text background color is
// transparent
aOutColor.AssignLiteral("transparent");
break;
} else {
// no, it's not; let's retrieve the computed style of background-color
// for the node to examine
CSSEditUtils::GetComputedProperty(
*contentToExamine, *nsGkAtoms::backgroundColor, aOutColor);
if (!aOutColor.EqualsLiteral("transparent")) {
break;
}
}
contentToExamine = contentToExamine->GetParent();
} while (aOutColor.EqualsLiteral("transparent") && contentToExamine);
// no, it's not; let's retrieve the computed style of background-color
// for the node to examine
nsCOMPtr<nsINode> parentNode = element->GetParentNode();
DebugOnly<nsresult> rvIgnored = CSSEditUtils::GetComputedProperty(
*element, *nsGkAtoms::backgroundColor, aOutColor);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(parentNode != element->GetParentNode())) {
return NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"CSSEditUtils::GetComputedProperty(nsGkAtoms::"
"backgroundColor) failed, but ignored");
if (!aOutColor.EqualsLiteral("transparent")) {
break;
}
}
}
return NS_OK;
}

View File

@ -36,8 +36,9 @@ class nsDocumentFragment;
class nsHTMLDocument;
class nsITransferable;
class nsIClipboard;
class nsTableWrapperFrame;
class nsRange;
class nsStaticAtom;
class nsTableWrapperFrame;
namespace mozilla {
class AlignStateAtSelection;
@ -182,7 +183,8 @@ class HTMLEditor final : public TextEditor,
* @param aMixed true if there is more than one font color
* @param aOutColor Color string. "" is returned for none.
*/
nsresult GetBackgroundColorState(bool* aMixed, nsAString& aOutColor);
MOZ_CAN_RUN_SCRIPT nsresult GetBackgroundColorState(bool* aMixed,
nsAString& aOutColor);
/**
* PasteNoFormatting() pastes content in clipboard without any style
@ -416,7 +418,8 @@ class HTMLEditor final : public TextEditor,
* returns the deepest absolutely positioned container of the selection
* if it exists or null.
*/
already_AddRefed<Element> GetAbsolutelyPositionedSelectionContainer() const;
MOZ_CAN_RUN_SCRIPT already_AddRefed<Element>
GetAbsolutelyPositionedSelectionContainer() const;
Element* GetPositionedElement() const { return mAbsolutelyPositionedObject; }
@ -438,7 +441,7 @@ class HTMLEditor final : public TextEditor,
* @return the z-index of the element
* @param aElement [IN] the element.
*/
int32_t GetZIndex(Element& aElement);
MOZ_CAN_RUN_SCRIPT int32_t GetZIndex(Element& aElement);
/**
* adds aChange to the z-index of the currently positioned element.
@ -468,34 +471,33 @@ class HTMLEditor final : public TextEditor,
nsAtom& aProperty, nsAtom* aAttribute, const nsAString& aValue,
nsIPrincipal* aPrincipal = nullptr);
nsresult GetInlineProperty(nsAtom* aProperty, nsAtom* aAttribute,
const nsAString& aValue, bool* aFirst, bool* aAny,
bool* aAll) const;
nsresult GetInlinePropertyWithAttrValue(nsAtom* aProperty, nsAtom* aAttr,
const nsAString& aValue, bool* aFirst,
bool* aAny, bool* aAll,
nsAString& outValue);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult GetInlineProperty(
nsAtom* aHTMLProperty, nsAtom* aAttribute, const nsAString& aValue,
bool* aFirst, bool* aAny, bool* aAll) const;
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult GetInlinePropertyWithAttrValue(
nsAtom* aHTMLProperty, nsAtom* aAttribute, const nsAString& aValue,
bool* aFirst, bool* aAny, bool* aAll, nsAString& outValue);
/**
* RemoveInlinePropertyAsAction() removes a property which changes inline
* style of text. E.g., bold, italic, super and sub.
*
* @param aProperty Tag name whcih represents the inline style you want to
* remove. E.g., nsGkAtoms::strong, nsGkAtoms::b, etc.
* If nsGkAtoms::href, <a> element which has href
* attribute will be removed.
* If nsGkAtoms::name, <a> element which has non-empty
* name attribute will be removed.
* @param aAttribute If aProperty is nsGkAtoms::font, aAttribute should be
* nsGkAtoms::fase, nsGkAtoms::size, nsGkAtoms::color or
* nsGkAtoms::bgcolor. Otherwise, set nullptr.
* @param aHTMLProperty Tag name whcih represents the inline style you want
* to remove. E.g., nsGkAtoms::strong, nsGkAtoms::b,
* etc. If nsGkAtoms::href, <a> element which has
* href attribute will be removed.
* If nsGkAtoms::name, <a> element which has non-empty
* name attribute will be removed.
* @param aAttribute If aHTMLProperty is nsGkAtoms::font, aAttribute should
* be nsGkAtoms::fase, nsGkAtoms::size, nsGkAtoms::color
* or nsGkAtoms::bgcolor. Otherwise, set nullptr.
* Must not use nsGkAtoms::_empty here.
* @param aPrincipal Set subject principal if it may be called by JS. If
* set to nullptr, will be treated as called by system.
*/
MOZ_CAN_RUN_SCRIPT nsresult
RemoveInlinePropertyAsAction(nsAtom& aProperty, nsAtom* aAttribute,
nsIPrincipal* aPrincipal = nullptr);
MOZ_CAN_RUN_SCRIPT nsresult RemoveInlinePropertyAsAction(
nsStaticAtom& aHTMLProperty, nsStaticAtom* aAttribute,
nsIPrincipal* aPrincipal = nullptr);
MOZ_CAN_RUN_SCRIPT nsresult
RemoveAllInlinePropertiesAsAction(nsIPrincipal* aPrincipal = nullptr);
@ -531,7 +533,8 @@ class HTMLEditor final : public TextEditor,
* Selection instance has gone, first range
* Selection is broken.
*/
nsresult GetFontColorState(bool* aIsMixed, nsAString& aColor);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
GetFontColorState(bool* aIsMixed, nsAString& aColor);
/**
* SetComposerCommandsUpdater() sets or unsets mComposerCommandsUpdater.
@ -889,9 +892,8 @@ class HTMLEditor final : public TextEditor,
* the element
* @param aReturn [OUT] the new z-index of the element
*/
MOZ_CAN_RUN_SCRIPT nsresult RelativeChangeElementZIndex(Element& aElement,
int32_t aChange,
int32_t* aReturn);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult RelativeChangeElementZIndex(
Element& aElement, int32_t aChange, int32_t* aReturn);
virtual bool IsBlockNode(nsINode* aNode) const override;
using EditorBase::IsBlockNode;
@ -1199,10 +1201,9 @@ class HTMLEditor final : public TextEditor,
nsIContent* GetFirstEditableLeaf(nsINode& aNode);
nsIContent* GetLastEditableLeaf(nsINode& aNode);
nsresult GetInlinePropertyBase(nsAtom& aProperty, nsAtom* aAttribute,
const nsAString* aValue, bool* aFirst,
bool* aAny, bool* aAll,
nsAString* outValue) const;
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult GetInlinePropertyBase(
nsAtom& aHTMLProperty, nsAtom* aAttribute, const nsAString* aValue,
bool* aFirst, bool* aAny, bool* aAll, nsAString* outValue) const;
/**
* ClearStyleAt() splits parent elements to remove the specified style.
@ -3427,21 +3428,21 @@ class HTMLEditor final : public TextEditor,
* RemoveInlinePropertyInternal() removes specified style from `mTypeInState`
* if `Selection` is collapsed. Otherwise, removing the style.
*
* @param aProperty nullptr if you want to remove all inline styles.
* @param aHTMLProperty nullptr if you want to remove all inline styles.
* Otherwise, one of the presentation tag names
* which we support in style editor.
* @param aAttribute For some aProperty values, need to be set to
* @param aAttribute For some aHTMLProperty values, need to be set to
* its attribute name. Otherwise, nullptr.
* @param aRemoveRelatedElements If Yes, this method removes different
* name's elements in the block if
* necessary. For example, if aProperty
* is nsGkAtoms::b, `<strong>` elements
* are also removed.
* necessary. For example, if
* aHTMLProperty is nsGkAtoms::b,
* `<strong>` elements are also removed.
*/
enum class RemoveRelatedElements { Yes, No };
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
RemoveInlinePropertyInternal(nsAtom* aProperty, nsAtom* aAttribute,
RemoveRelatedElements aRemoveRelatedElements);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult RemoveInlinePropertyInternal(
nsStaticAtom* aHTMLProperty, nsStaticAtom* aAttribute,
RemoveRelatedElements aRemoveRelatedElements);
/**
* ReplaceHeadContentsWithSourceWithTransaction() replaces all children of
@ -3453,8 +3454,8 @@ class HTMLEditor final : public TextEditor,
MOZ_CAN_RUN_SCRIPT nsresult ReplaceHeadContentsWithSourceWithTransaction(
const nsAString& aSourceToInsert);
nsresult GetCSSBackgroundColorState(bool* aMixed, nsAString& aOutColor,
bool aBlockLevel);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult GetCSSBackgroundColorState(
bool* aMixed, nsAString& aOutColor, bool aBlockLevel);
nsresult GetHTMLBackgroundColorState(bool* aMixed, nsAString& outColor);
nsresult GetLastCellInRow(nsINode* aRowNode, nsINode** aCellNode);
@ -4125,10 +4126,14 @@ class HTMLEditor final : public TextEditor,
* aProperty/aAttribute of parent block can be removed from aContent with
* creating `<span>` element. Note that this does NOT check whether the
* specified style comes from parent block or not.
* XXX This may destroy the editor, but using `Result<bool, nsresult>`
* is not reasonable because code for accessing the result becomes
* messy. However, anybody must forget to check `Destroyed()` after
* calling this. Which is the way to smart to make every caller
* must check the editor state?
*/
static bool IsRemovableParentStyleWithNewSpanElement(nsIContent& aContent,
nsAtom* aProperty,
nsAtom* aAttribute);
MOZ_CAN_RUN_SCRIPT bool IsRemovableParentStyleWithNewSpanElement(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute) const;
/**
* XXX These methods seem odd and except the only caller,
@ -4222,10 +4227,10 @@ class HTMLEditor final : public TextEditor,
* Returns the offset of an element's frame to its absolute containing block.
*/
nsresult GetElementOrigin(Element& aElement, int32_t& aX, int32_t& aY);
nsresult GetPositionAndDimensions(Element& aElement, int32_t& aX, int32_t& aY,
int32_t& aW, int32_t& aH,
int32_t& aBorderLeft, int32_t& aBorderTop,
int32_t& aMarginLeft, int32_t& aMarginTop);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult GetPositionAndDimensions(
Element& aElement, int32_t& aX, int32_t& aY, int32_t& aW, int32_t& aH,
int32_t& aBorderLeft, int32_t& aBorderTop, int32_t& aMarginLeft,
int32_t& aMarginTop);
bool IsInObservedSubtree(nsIContent* aChild);
@ -4237,7 +4242,7 @@ class HTMLEditor final : public TextEditor,
* while this is running, this returns error. So, callers shouldn't
* keep handling the resizers if this returns error.
*/
MOZ_CAN_RUN_SCRIPT nsresult SetAllResizersPosition();
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult SetAllResizersPosition();
/**
* Shows active resizers around an element's frame
@ -4272,10 +4277,9 @@ class HTMLEditor final : public TextEditor,
* @param aElementX Left of aElement.
* @param aElementY Top of aElement.
*/
MOZ_CAN_RUN_SCRIPT nsresult SetShadowPosition(Element& aShadowElement,
Element& aElement,
int32_t aElementLeft,
int32_t aElementTop);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
SetShadowPosition(Element& aShadowElement, Element& aElement,
int32_t aElementLeft, int32_t aElementTop);
ManualNACPtr CreateResizingInfo(nsIContent& aParentContent);
MOZ_CAN_RUN_SCRIPT nsresult SetResizingInfoPosition(int32_t aX, int32_t aY,
@ -4354,8 +4358,9 @@ class HTMLEditor final : public TextEditor,
void SnapToGrid(int32_t& newX, int32_t& newY);
nsresult GrabberClicked();
MOZ_CAN_RUN_SCRIPT nsresult EndMoving();
nsresult GetTemporaryStyleForFocusedPositionedElement(Element& aElement,
nsAString& aReturn);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
GetTemporaryStyleForFocusedPositionedElement(Element& aElement,
nsAString& aReturn);
/**
* Shows inline table editing UI around a <table> element which contains
@ -4654,7 +4659,8 @@ class MOZ_STACK_CLASS ListItemElementSelectionState final {
class MOZ_STACK_CLASS AlignStateAtSelection final {
public:
AlignStateAtSelection() = delete;
AlignStateAtSelection(HTMLEditor& aHTMLEditor, ErrorResult& aRv);
MOZ_CAN_RUN_SCRIPT AlignStateAtSelection(HTMLEditor& aHTMLEditor,
ErrorResult& aRv);
nsIHTMLEditor::EAlignment AlignmentAtSelectionStart() const {
return mFirstAlign;

View File

@ -71,11 +71,11 @@ nsresult StateUpdatingCommandBase::DoCommand(Command aCommand,
if (NS_WARN_IF(!htmlEditor)) {
return NS_ERROR_FAILURE;
}
nsAtom* tagName = GetTagName(aCommand);
nsStaticAtom* tagName = GetTagName(aCommand);
if (NS_WARN_IF(!tagName)) {
return NS_ERROR_UNEXPECTED;
}
nsresult rv = ToggleState(MOZ_KnownLive(tagName), MOZ_KnownLive(htmlEditor),
nsresult rv = ToggleState(MOZ_KnownLive(*tagName), MOZ_KnownLive(*htmlEditor),
aPrincipal);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"StateUpdatingCommandBase::ToggleState() failed");
@ -176,24 +176,20 @@ nsresult StyleUpdatingCommand::GetCurrentState(nsAtom* aTagName,
return NS_OK;
}
nsresult StyleUpdatingCommand::ToggleState(nsAtom* aTagName,
HTMLEditor* aHTMLEditor,
nsresult StyleUpdatingCommand::ToggleState(nsStaticAtom& aTagName,
HTMLEditor& aHTMLEditor,
nsIPrincipal* aPrincipal) const {
if (NS_WARN_IF(!aTagName) || NS_WARN_IF(!aHTMLEditor)) {
return NS_ERROR_INVALID_ARG;
}
RefPtr<nsCommandParams> params = new nsCommandParams();
// tags "href" and "name" are special cases in the core editor
// they are used to remove named anchor/link and shouldn't be used for
// insertion
bool doTagRemoval;
if (aTagName == nsGkAtoms::href || aTagName == nsGkAtoms::name) {
if (&aTagName == nsGkAtoms::href || &aTagName == nsGkAtoms::name) {
doTagRemoval = true;
} else {
// check current selection; set doTagRemoval if formatting should be removed
nsresult rv = GetCurrentState(aTagName, aHTMLEditor, *params);
nsresult rv = GetCurrentState(&aTagName, &aHTMLEditor, *params);
if (NS_FAILED(rv)) {
NS_WARNING("StyleUpdatingCommand::GetCurrentState() failed");
return rv;
@ -206,15 +202,15 @@ nsresult StyleUpdatingCommand::ToggleState(nsAtom* aTagName,
}
if (doTagRemoval) {
nsresult rv = aHTMLEditor->RemoveInlinePropertyAsAction(*aTagName, nullptr,
aPrincipal);
nsresult rv =
aHTMLEditor.RemoveInlinePropertyAsAction(aTagName, nullptr, aPrincipal);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::RemoveInlinePropertyAsAction() failed");
return rv;
}
nsresult rv = aHTMLEditor->SetInlinePropertyAsAction(
*aTagName, nullptr, EmptyString(), aPrincipal);
nsresult rv = aHTMLEditor.SetInlinePropertyAsAction(
aTagName, nullptr, EmptyString(), aPrincipal);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::SetInlinePropertyAsAction() failed");
return rv;
@ -247,14 +243,11 @@ nsresult ListCommand::GetCurrentState(nsAtom* aTagName, HTMLEditor* aHTMLEditor,
return NS_OK;
}
nsresult ListCommand::ToggleState(nsAtom* aTagName, HTMLEditor* aHTMLEditor,
nsresult ListCommand::ToggleState(nsStaticAtom& aTagName,
HTMLEditor& aHTMLEditor,
nsIPrincipal* aPrincipal) const {
if (NS_WARN_IF(!aTagName) || NS_WARN_IF(!aHTMLEditor)) {
return NS_ERROR_INVALID_ARG;
}
RefPtr<nsCommandParams> params = new nsCommandParams();
nsresult rv = GetCurrentState(aTagName, aHTMLEditor, *params);
nsresult rv = GetCurrentState(&aTagName, &aHTMLEditor, *params);
if (NS_FAILED(rv)) {
NS_WARNING("ListCommand::GetCurrentState() failed");
return rv;
@ -266,16 +259,16 @@ nsresult ListCommand::ToggleState(nsAtom* aTagName, HTMLEditor* aHTMLEditor,
return error.StealNSResult();
}
nsDependentAtomString listType(aTagName);
nsDependentAtomString listType(&aTagName);
if (inList) {
rv = aHTMLEditor->RemoveListAsAction(listType, aPrincipal);
nsresult rv = aHTMLEditor.RemoveListAsAction(listType, aPrincipal);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::RemoveListAsAction() failed");
return rv;
}
rv = aHTMLEditor->MakeOrChangeListAsAction(
*aTagName, EmptyString(), HTMLEditor::SelectAllOfCurrentList::No,
rv = aHTMLEditor.MakeOrChangeListAsAction(
aTagName, EmptyString(), HTMLEditor::SelectAllOfCurrentList::No,
aPrincipal);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::MakeOrChangeListAsAction() failed");
@ -321,15 +314,12 @@ nsresult ListItemCommand::GetCurrentState(nsAtom* aTagName,
return NS_OK;
}
nsresult ListItemCommand::ToggleState(nsAtom* aTagName, HTMLEditor* aHTMLEditor,
nsresult ListItemCommand::ToggleState(nsStaticAtom& aTagName,
HTMLEditor& aHTMLEditor,
nsIPrincipal* aPrincipal) const {
if (NS_WARN_IF(!aTagName) || NS_WARN_IF(!aHTMLEditor)) {
return NS_ERROR_INVALID_ARG;
}
// Need to use aTagName????
RefPtr<nsCommandParams> params = new nsCommandParams();
GetCurrentState(aTagName, aHTMLEditor, *params);
GetCurrentState(&aTagName, &aHTMLEditor, *params);
ErrorResult error;
bool inList = params->GetBool(STATE_ALL, error);
if (NS_WARN_IF(error.Failed())) {
@ -340,7 +330,7 @@ nsresult ListItemCommand::ToggleState(nsAtom* aTagName, HTMLEditor* aHTMLEditor,
// To remove a list, first get what kind of list we're in
bool bMixed;
nsAutoString localName;
nsresult rv = GetListState(aHTMLEditor, &bMixed, localName);
nsresult rv = GetListState(&aHTMLEditor, &bMixed, localName);
if (NS_FAILED(rv)) {
NS_WARNING("GetListState() failed");
return rv;
@ -348,7 +338,7 @@ nsresult ListItemCommand::ToggleState(nsAtom* aTagName, HTMLEditor* aHTMLEditor,
if (localName.IsEmpty() || bMixed) {
return NS_OK;
}
rv = aHTMLEditor->RemoveListAsAction(localName, aPrincipal);
rv = aHTMLEditor.RemoveListAsAction(localName, aPrincipal);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::RemoveListAsAction() failed");
return rv;
@ -358,8 +348,8 @@ nsresult ListItemCommand::ToggleState(nsAtom* aTagName, HTMLEditor* aHTMLEditor,
// XXX Note: This actually doesn't work for "LI",
// but we currently don't use this for non DL lists anyway.
// Problem: won't this replace any current block paragraph style?
nsresult rv = aHTMLEditor->SetParagraphFormatAsAction(
nsDependentAtomString(aTagName), aPrincipal);
nsresult rv = aHTMLEditor.SetParagraphFormatAsAction(
nsDependentAtomString(&aTagName), aPrincipal);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::SetParagraphFormatAsAction() failed");
return rv;
@ -934,15 +924,12 @@ nsresult AbsolutePositioningCommand::GetCurrentState(
}
nsresult AbsolutePositioningCommand::ToggleState(
nsAtom* aTagName, HTMLEditor* aHTMLEditor, nsIPrincipal* aPrincipal) const {
if (NS_WARN_IF(!aHTMLEditor)) {
return NS_ERROR_INVALID_ARG;
}
nsStaticAtom& aTagName, HTMLEditor& aHTMLEditor,
nsIPrincipal* aPrincipal) const {
RefPtr<Element> container =
aHTMLEditor->GetAbsolutelyPositionedSelectionContainer();
nsresult rv = aHTMLEditor->SetSelectionToAbsoluteOrStaticAsAction(!container,
aPrincipal);
aHTMLEditor.GetAbsolutelyPositionedSelectionContainer();
nsresult rv = aHTMLEditor.SetSelectionToAbsoluteOrStaticAsAction(!container,
aPrincipal);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv),
"HTMLEditor::SetSelectionToAbsoluteOrStaticAsAction() failed");
@ -960,7 +947,7 @@ bool DecreaseZIndexCommand::IsCommandEnabled(Command aCommand,
if (!aTextEditor) {
return false;
}
HTMLEditor* htmlEditor = aTextEditor->AsHTMLEditor();
RefPtr<HTMLEditor> htmlEditor = aTextEditor->AsHTMLEditor();
if (!htmlEditor) {
return false;
}

View File

@ -3,7 +3,7 @@
* 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/. */
#include "mozilla/HTMLEditor.h"
#include "HTMLEditor.h"
#include "HTMLEditorEventListener.h"
#include "HTMLEditUtils.h"
@ -141,13 +141,28 @@ nsresult HTMLEditor::SetAllResizersPosition() {
float resizerWidth, resizerHeight;
RefPtr<nsAtom> dummyUnit;
DebugOnly<nsresult> rvIgnored = NS_OK;
rvIgnored = CSSEditUtils::GetComputedProperty(*mTopLeftHandle,
OwningNonNull<Element> topLeftHandle = *mTopLeftHandle.get();
// XXX Do we really need to computed value rather than specified value?
// Because it's an anonymous node.
rvIgnored = CSSEditUtils::GetComputedProperty(*topLeftHandle,
*nsGkAtoms::width, value);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) {
return NS_ERROR_FAILURE;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"CSSEditUtils::GetComputedProperty(nsGkAtoms::width) "
"failed, but ignored");
rvIgnored = CSSEditUtils::GetComputedProperty(*mTopLeftHandle,
rvIgnored = CSSEditUtils::GetComputedProperty(*topLeftHandle,
*nsGkAtoms::height, value);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) {
return NS_ERROR_FAILURE;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"CSSEditUtils::GetComputedProperty(nsGkAtoms::height) "
"failed, but ignored");
@ -164,46 +179,69 @@ nsresult HTMLEditor::SetAllResizersPosition() {
// FYI: Note that only checking if mTopLeftHandle is replaced is enough.
// We're may be in hot path if user resizes an element a lot. So,
// we should just add-ref mTopLeftHandle.
RefPtr<Element> topLeftHandle = mTopLeftHandle.get();
SetAnonymousElementPosition(x - rw, y - rh, topLeftHandle);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) {
return NS_ERROR_FAILURE;
}
RefPtr<Element> topHandle = mTopHandle.get();
SetAnonymousElementPosition(x + w / 2 - rw, y - rh, topHandle);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) {
return NS_ERROR_FAILURE;
}
RefPtr<Element> topRightHandle = mTopRightHandle.get();
SetAnonymousElementPosition(x + w - rw - 1, y - rh, topRightHandle);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) {
return NS_ERROR_FAILURE;
}
RefPtr<Element> leftHandle = mLeftHandle.get();
SetAnonymousElementPosition(x - rw, y + h / 2 - rh, leftHandle);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) {
return NS_ERROR_FAILURE;
}
RefPtr<Element> rightHandle = mRightHandle.get();
SetAnonymousElementPosition(x + w - rw - 1, y + h / 2 - rh, rightHandle);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) {
return NS_ERROR_FAILURE;
}
RefPtr<Element> bottomLeftHandle = mBottomLeftHandle.get();
SetAnonymousElementPosition(x - rw, y + h - rh - 1, bottomLeftHandle);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) {
return NS_ERROR_FAILURE;
}
RefPtr<Element> bottomHandle = mBottomHandle.get();
SetAnonymousElementPosition(x + w / 2 - rw, y + h - rh - 1, bottomHandle);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) {
return NS_ERROR_FAILURE;
}
RefPtr<Element> bottomRightHandle = mBottomRightHandle.get();
SetAnonymousElementPosition(x + w - rw - 1, y + h - rh - 1,
bottomRightHandle);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(topLeftHandle != mTopLeftHandle)) {
return NS_ERROR_FAILURE;
}
@ -231,28 +269,37 @@ nsresult HTMLEditor::RefreshResizersInternal() {
return NS_OK;
}
OwningNonNull<Element> resizedObject = *mResizedObject;
nsresult rv = GetPositionAndDimensions(
*mResizedObject, mResizedObjectX, mResizedObjectY, mResizedObjectWidth,
resizedObject, mResizedObjectX, mResizedObjectY, mResizedObjectWidth,
mResizedObjectHeight, mResizedObjectBorderLeft, mResizedObjectBorderTop,
mResizedObjectMarginLeft, mResizedObjectMarginTop);
if (NS_FAILED(rv)) {
NS_WARNING("HTMLEditor::GetPositionAndDimensions() failed");
return rv;
}
if (NS_WARN_IF(resizedObject != mResizedObject)) {
return NS_ERROR_FAILURE;
}
rv = SetAllResizersPosition();
if (NS_FAILED(rv)) {
NS_WARNING("HTMLEditor::SetAllResizersPosition() failed");
return rv;
}
if (NS_WARN_IF(resizedObject != mResizedObject)) {
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(
mResizingShadow,
"SetAllResizersPosition() should return error if resizers are hidden");
RefPtr<Element> resizingShadow = mResizingShadow.get();
RefPtr<Element> resizedObject = mResizedObject;
rv = SetShadowPosition(*resizingShadow, *resizedObject, mResizedObjectX,
rv = SetShadowPosition(*resizingShadow, resizedObject, mResizedObjectX,
mResizedObjectY);
if (NS_WARN_IF(resizedObject != mResizedObject)) {
return NS_ERROR_FAILURE;
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::SetShadowPosition() failed");
return rv;
@ -898,6 +945,9 @@ nsresult HTMLEditor::SetShadowPosition(Element& aShadowElement,
: mPositioningShadow.get();
SetAnonymousElementPosition(aElementX, aElementY, &aShadowElement);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(&aShadowElement != handlingShadowElement)) {
return NS_ERROR_FAILURE;
}
@ -910,6 +960,9 @@ nsresult HTMLEditor::SetShadowPosition(Element& aShadowElement,
aElement.GetAttr(kNameSpaceID_None, nsGkAtoms::src, imageSource);
nsresult rv = aShadowElement.SetAttr(kNameSpaceID_None, nsGkAtoms::src,
imageSource, true);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_FAILED(rv)) {
NS_WARNING("Element::SetAttr(nsGkAtoms::src) failed");
return NS_ERROR_FAILURE;

View File

@ -3,7 +3,7 @@
* 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/. */
#include "mozilla/HTMLEditor.h"
#include "HTMLEditor.h"
#include "HTMLEditUtils.h"
#include "TypeInState.h"
@ -46,13 +46,6 @@ namespace mozilla {
using namespace dom;
static already_AddRefed<nsAtom> AtomizeAttribute(const nsAString& aAttribute) {
if (aAttribute.IsEmpty()) {
return nullptr; // Don't use nsGkAtoms::_empty for attribute.
}
return NS_Atomize(aAttribute);
}
nsresult HTMLEditor::SetInlinePropertyAsAction(nsAtom& aProperty,
nsAtom* aAttribute,
const nsAString& aValue,
@ -144,7 +137,7 @@ NS_IMETHODIMP HTMLEditor::SetInlineProperty(const nsAString& aProperty,
if (NS_WARN_IF(!property)) {
return NS_ERROR_INVALID_ARG;
}
RefPtr<nsAtom> attribute = AtomizeAttribute(aAttribute);
nsStaticAtom* attribute = EditorUtils::GetAttributeAtom(aAttribute);
AutoEditActionDataSetter editActionData(
*this,
HTMLEditUtils::GetEditActionForFormatText(*property, attribute, true));
@ -167,7 +160,7 @@ NS_IMETHODIMP HTMLEditor::SetInlineProperty(const nsAString& aProperty,
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
return EditorBase::ToGenericNSResult(rv);
}
rv = SetInlinePropertyInternal(*property, attribute, aValue);
rv = SetInlinePropertyInternal(*property, MOZ_KnownLive(attribute), aValue);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::SetInlinePropertyInternal() failed");
return EditorBase::ToGenericNSResult(rv);
@ -1310,7 +1303,7 @@ bool HTMLEditor::IsEndOfContainerOrEqualsOrAfterLastEditableChild(
return EditorRawDOMPoint(lastEditableChild).Offset() < aPoint.Offset();
}
nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aProperty,
nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aHTMLProperty,
nsAtom* aAttribute,
const nsAString* aValue,
bool* aFirst, bool* aAny, bool* aAll,
@ -1338,13 +1331,13 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aProperty,
bool isSet, theSetting;
nsString tOutString;
if (aAttribute) {
mTypeInState->GetTypingState(isSet, theSetting, &aProperty, aAttribute,
&tOutString);
mTypeInState->GetTypingState(isSet, theSetting, &aHTMLProperty,
aAttribute, &tOutString);
if (outValue) {
outValue->Assign(tOutString);
}
} else {
mTypeInState->GetTypingState(isSet, theSetting, &aProperty);
mTypeInState->GetTypingState(isSet, theSetting, &aHTMLProperty);
}
if (isSet) {
*aFirst = *aAny = *aAll = theSetting;
@ -1352,23 +1345,26 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aProperty,
}
if (collapsedNode->IsContent() &&
CSSEditUtils::IsCSSEditableProperty(collapsedNode, &aProperty,
CSSEditUtils::IsCSSEditableProperty(collapsedNode, &aHTMLProperty,
aAttribute)) {
if (aValue) {
tOutString.Assign(*aValue);
}
*aFirst = *aAny = *aAll =
CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
*collapsedNode->AsContent(), &aProperty, aAttribute,
tOutString);
MOZ_KnownLive(*collapsedNode->AsContent()), &aHTMLProperty,
aAttribute, tOutString);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (outValue) {
outValue->Assign(tOutString);
}
return NS_OK;
}
isSet = IsTextPropertySetByContent(collapsedNode, &aProperty, aAttribute,
aValue, outValue);
isSet = IsTextPropertySetByContent(collapsedNode, &aHTMLProperty,
aAttribute, aValue, outValue);
*aFirst = *aAny = *aAll = isSet;
return NS_OK;
}
@ -1416,21 +1412,24 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aProperty,
bool isSet = false;
bool useTextDecoration =
&aProperty == nsGkAtoms::u || &aProperty == nsGkAtoms::strike;
&aHTMLProperty == nsGkAtoms::u || &aHTMLProperty == nsGkAtoms::strike;
if (first) {
if (CSSEditUtils::IsCSSEditableProperty(content, &aProperty,
if (CSSEditUtils::IsCSSEditableProperty(content, &aHTMLProperty,
aAttribute)) {
// The HTML styles defined by aProperty/aAttribute have a CSS
// The HTML styles defined by aHTMLProperty/aAttribute have a CSS
// equivalence in this implementation for node; let's check if it
// carries those CSS styles
if (aValue) {
firstValue.Assign(*aValue);
}
isSet = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
*content, &aProperty, aAttribute, firstValue);
*content, &aHTMLProperty, aAttribute, firstValue);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
} else {
isSet = IsTextPropertySetByContent(content, &aProperty, aAttribute,
aValue, &firstValue);
isSet = IsTextPropertySetByContent(content, &aHTMLProperty,
aAttribute, aValue, &firstValue);
}
*aFirst = isSet;
first = false;
@ -1438,19 +1437,22 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aProperty,
*outValue = firstValue;
}
} else {
if (CSSEditUtils::IsCSSEditableProperty(content, &aProperty,
if (CSSEditUtils::IsCSSEditableProperty(content, &aHTMLProperty,
aAttribute)) {
// The HTML styles defined by aProperty/aAttribute have a CSS
// The HTML styles defined by aHTMLProperty/aAttribute have a CSS
// equivalence in this implementation for node; let's check if it
// carries those CSS styles
if (aValue) {
theValue.Assign(*aValue);
}
isSet = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
*content, &aProperty, aAttribute, theValue);
*content, &aHTMLProperty, aAttribute, theValue);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
} else {
isSet = IsTextPropertySetByContent(content, &aProperty, aAttribute,
aValue, &theValue);
isSet = IsTextPropertySetByContent(content, &aHTMLProperty,
aAttribute, aValue, &theValue);
}
if (firstValue != theValue &&
@ -1489,24 +1491,25 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aProperty,
return NS_OK;
}
NS_IMETHODIMP HTMLEditor::GetInlineProperty(const nsAString& aProperty,
NS_IMETHODIMP HTMLEditor::GetInlineProperty(const nsAString& aHTMLProperty,
const nsAString& aAttribute,
const nsAString& aValue,
bool* aFirst, bool* aAny,
bool* aAll) {
RefPtr<nsAtom> property = NS_Atomize(aProperty);
RefPtr<nsAtom> attribute = AtomizeAttribute(aAttribute);
nsresult rv =
GetInlineProperty(property, attribute, aValue, aFirst, aAny, aAll);
RefPtr<nsAtom> property = NS_Atomize(aHTMLProperty);
nsStaticAtom* attribute = EditorUtils::GetAttributeAtom(aAttribute);
nsresult rv = GetInlineProperty(property, MOZ_KnownLive(attribute), aValue,
aFirst, aAny, aAll);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::GetInlineProperty() failed");
return rv;
}
nsresult HTMLEditor::GetInlineProperty(nsAtom* aProperty, nsAtom* aAttribute,
nsresult HTMLEditor::GetInlineProperty(nsAtom* aHTMLProperty,
nsAtom* aAttribute,
const nsAString& aValue, bool* aFirst,
bool* aAny, bool* aAll) const {
if (NS_WARN_IF(!aProperty) || NS_WARN_IF(!aFirst) || NS_WARN_IF(!aAny) ||
if (NS_WARN_IF(!aHTMLProperty) || NS_WARN_IF(!aFirst) || NS_WARN_IF(!aAny) ||
NS_WARN_IF(!aAll)) {
return NS_ERROR_INVALID_ARG;
}
@ -1517,30 +1520,30 @@ nsresult HTMLEditor::GetInlineProperty(nsAtom* aProperty, nsAtom* aAttribute,
}
const nsAString* val = !aValue.IsEmpty() ? &aValue : nullptr;
nsresult rv = GetInlinePropertyBase(*aProperty, aAttribute, val, aFirst, aAny,
aAll, nullptr);
nsresult rv = GetInlinePropertyBase(*aHTMLProperty, aAttribute, val, aFirst,
aAny, aAll, nullptr);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::GetInlinePropertyBase() failed");
return EditorBase::ToGenericNSResult(rv);
}
NS_IMETHODIMP HTMLEditor::GetInlinePropertyWithAttrValue(
const nsAString& aProperty, const nsAString& aAttribute,
const nsAString& aHTMLProperty, const nsAString& aAttribute,
const nsAString& aValue, bool* aFirst, bool* aAny, bool* aAll,
nsAString& outValue) {
RefPtr<nsAtom> property = NS_Atomize(aProperty);
RefPtr<nsAtom> attribute = AtomizeAttribute(aAttribute);
nsresult rv = GetInlinePropertyWithAttrValue(property, attribute, aValue,
aFirst, aAny, aAll, outValue);
RefPtr<nsAtom> property = NS_Atomize(aHTMLProperty);
nsStaticAtom* attribute = EditorUtils::GetAttributeAtom(aAttribute);
nsresult rv = GetInlinePropertyWithAttrValue(
property, MOZ_KnownLive(attribute), aValue, aFirst, aAny, aAll, outValue);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::GetInlinePropertyWithAttrValue() failed");
return rv;
}
nsresult HTMLEditor::GetInlinePropertyWithAttrValue(
nsAtom* aProperty, nsAtom* aAttribute, const nsAString& aValue,
nsAtom* aHTMLProperty, nsAtom* aAttribute, const nsAString& aValue,
bool* aFirst, bool* aAny, bool* aAll, nsAString& outValue) {
if (NS_WARN_IF(!aProperty) || NS_WARN_IF(!aFirst) || NS_WARN_IF(!aAny) ||
if (NS_WARN_IF(!aHTMLProperty) || NS_WARN_IF(!aFirst) || NS_WARN_IF(!aAny) ||
NS_WARN_IF(!aAll)) {
return NS_ERROR_INVALID_ARG;
}
@ -1551,8 +1554,8 @@ nsresult HTMLEditor::GetInlinePropertyWithAttrValue(
}
const nsAString* val = !aValue.IsEmpty() ? &aValue : nullptr;
nsresult rv = GetInlinePropertyBase(*aProperty, aAttribute, val, aFirst, aAny,
aAll, &outValue);
nsresult rv = GetInlinePropertyBase(*aHTMLProperty, aAttribute, val, aFirst,
aAny, aAll, &outValue);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::GetInlinePropertyBase() failed");
return EditorBase::ToGenericNSResult(rv);
@ -1589,12 +1592,13 @@ nsresult HTMLEditor::RemoveAllInlinePropertiesAsAction(
return EditorBase::ToGenericNSResult(rv);
}
nsresult HTMLEditor::RemoveInlinePropertyAsAction(nsAtom& aProperty,
nsAtom* aAttribute,
nsresult HTMLEditor::RemoveInlinePropertyAsAction(nsStaticAtom& aHTMLProperty,
nsStaticAtom* aAttribute,
nsIPrincipal* aPrincipal) {
AutoEditActionDataSetter editActionData(
*this,
HTMLEditUtils::GetEditActionForFormatText(aProperty, aAttribute, false),
HTMLEditUtils::GetEditActionForFormatText(aHTMLProperty, aAttribute,
false),
aPrincipal);
switch (editActionData.GetEditAction()) {
case EditAction::eRemoveFontFamilyProperty:
@ -1615,7 +1619,7 @@ nsresult HTMLEditor::RemoveInlinePropertyAsAction(nsAtom& aProperty,
return EditorBase::ToGenericNSResult(rv);
}
rv = RemoveInlinePropertyInternal(&aProperty, aAttribute,
rv = RemoveInlinePropertyInternal(&aHTMLProperty, aAttribute,
RemoveRelatedElements::Yes);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::RemoveInlinePropertyInternal("
@ -1625,8 +1629,8 @@ nsresult HTMLEditor::RemoveInlinePropertyAsAction(nsAtom& aProperty,
NS_IMETHODIMP HTMLEditor::RemoveInlineProperty(const nsAString& aProperty,
const nsAString& aAttribute) {
RefPtr<nsAtom> property = NS_Atomize(aProperty);
RefPtr<nsAtom> attribute = AtomizeAttribute(aAttribute);
nsStaticAtom* property = NS_GetStaticAtom(aProperty);
nsStaticAtom* attribute = EditorUtils::GetAttributeAtom(aAttribute);
AutoEditActionDataSetter editActionData(
*this,
@ -1650,7 +1654,8 @@ NS_IMETHODIMP HTMLEditor::RemoveInlineProperty(const nsAString& aProperty,
return EditorBase::ToGenericNSResult(rv);
}
rv = RemoveInlinePropertyInternal(property, attribute,
rv = RemoveInlinePropertyInternal(MOZ_KnownLive(property),
MOZ_KnownLive(attribute),
RemoveRelatedElements::No);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::RemoveInlinePropertyInternal("
@ -1659,7 +1664,7 @@ NS_IMETHODIMP HTMLEditor::RemoveInlineProperty(const nsAString& aProperty,
}
nsresult HTMLEditor::RemoveInlinePropertyInternal(
nsAtom* aProperty, nsAtom* aAttribute,
nsStaticAtom* aProperty, nsStaticAtom* aAttribute,
RemoveRelatedElements aRemoveRelatedElements) {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(aAttribute != nsGkAtoms::_empty);
@ -1675,11 +1680,12 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal(
// Also remove equivalent properties (bug 317093)
struct HTMLStyle final {
// HTML tag name or nsGkAtoms::href or nsGkAtoms::name.
nsAtom* mProperty = nullptr;
nsStaticAtom* mProperty = nullptr;
// HTML attribute like nsGkAtom::color for nsGkAtoms::font.
nsAtom* mAttribute = nullptr;
nsStaticAtom* mAttribute = nullptr;
explicit HTMLStyle(nsAtom* aProperty, nsAtom* aAttribute = nullptr)
explicit HTMLStyle(nsStaticAtom* aProperty,
nsStaticAtom* aAttribute = nullptr)
: mProperty(aProperty), mAttribute(aAttribute) {}
};
AutoTArray<HTMLStyle, 3> removeStyles;
@ -1868,7 +1874,7 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal(
}
}
for (auto& content : arrayOfContents) {
for (OwningNonNull<nsIContent>& content : arrayOfContents) {
if (content->IsElement()) {
nsresult rv =
RemoveStyleInside(MOZ_KnownLive(*content->AsElement()),
@ -1880,8 +1886,13 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal(
}
}
if (!HTMLEditor::IsRemovableParentStyleWithNewSpanElement(
content, style.mProperty, style.mAttribute)) {
bool isRemovable = IsRemovableParentStyleWithNewSpanElement(
MOZ_KnownLive(content), MOZ_KnownLive(style.mProperty),
MOZ_KnownLive(style.mAttribute));
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (!isRemovable) {
continue;
}
@ -1934,15 +1945,20 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal(
// Finally, we should remove the style from all leaf text nodes if
// they still have the style.
AutoTArray<OwningNonNull<Text>, 32> leafTextNodes;
for (auto& content : arrayOfContents) {
for (OwningNonNull<nsIContent>& content : arrayOfContents) {
if (content->IsElement()) {
CollectEditableLeafTextNodes(*content->AsElement(),
leafTextNodes);
}
}
for (auto& textNode : leafTextNodes) {
if (!HTMLEditor::IsRemovableParentStyleWithNewSpanElement(
textNode, style.mProperty, style.mAttribute)) {
for (OwningNonNull<Text>& textNode : leafTextNodes) {
bool isRemovable = IsRemovableParentStyleWithNewSpanElement(
MOZ_KnownLive(textNode), MOZ_KnownLive(style.mProperty),
MOZ_KnownLive(style.mAttribute));
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (!isRemovable) {
continue;
}
// MOZ_KnownLive because 'leafTextNodes' is guaranteed to
@ -1968,24 +1984,23 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal(
return NS_WARN_IF(Destroyed()) ? NS_ERROR_EDITOR_DESTROYED : NS_OK;
}
// static
bool HTMLEditor::IsRemovableParentStyleWithNewSpanElement(nsIContent& aContent,
nsAtom* aProperty,
nsAtom* aAttribute) {
bool HTMLEditor::IsRemovableParentStyleWithNewSpanElement(
nsIContent& aContent, nsAtom* aHTMLProperty, nsAtom* aAttribute) const {
// We don't support to remove all inline styles with this path.
if (!aProperty) {
if (!aHTMLProperty) {
return false;
}
// First check whether the style is invertible since this is the fastest
// check.
if (!CSSEditUtils::IsCSSInvertible(*aProperty, aAttribute)) {
if (!CSSEditUtils::IsCSSInvertible(*aHTMLProperty, aAttribute)) {
return false;
}
// If parent block has the removing style, we should create `<span>`
// element to remove the style even in HTML mode since Chrome does it.
if (!CSSEditUtils::IsCSSEditableProperty(&aContent, aProperty, aAttribute)) {
if (!CSSEditUtils::IsCSSEditableProperty(&aContent, aHTMLProperty,
aAttribute)) {
return false;
}
@ -1995,8 +2010,9 @@ bool HTMLEditor::IsRemovableParentStyleWithNewSpanElement(nsIContent& aContent,
// assume it comes from a rule and let's try to insert a span
// "inverting" the style
nsAutoString emptyString;
return CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
aContent, aProperty, aAttribute, emptyString);
bool isSet = CSSEditUtils::IsComputedCSSEquivalentToHTMLInlineStyleSet(
aContent, aHTMLProperty, aAttribute, emptyString);
return NS_WARN_IF(Destroyed()) ? false : isSet;
}
void HTMLEditor::CollectEditableLeafTextNodes(
@ -2480,7 +2496,10 @@ nsresult HTMLEditor::GetFontColorState(bool* aMixed, nsAString& aOutColor) {
bool first, any, all;
nsresult rv = GetInlinePropertyBase(*nsGkAtoms::font, nsGkAtoms::color,
nullptr, &first, &any, &all, &aOutColor);
if (NS_WARN_IF(NS_FAILED(rv))) {
if (NS_FAILED(rv)) {
NS_WARNING(
"HTMLEditor::GetInlinePropertyBase(nsGkAtoms::font, nsGkAtoms::color) "
"failed");
return EditorBase::ToGenericNSResult(rv);
}

View File

@ -66,6 +66,7 @@ interface nsIHTMLEditor : nsISupports
* @param aAll [OUT] PR_TRUE if all of the text nodes in the
* selection have the property
*/
[can_run_script]
void getInlineProperty(in AString aProperty,
in AString aAttribute,
in AString aValue,
@ -73,6 +74,7 @@ interface nsIHTMLEditor : nsISupports
out boolean aAny,
out boolean aAll);
[can_run_script]
AString getInlinePropertyWithAttrValue(in AString aProperty,
in AString aAttribute,
in AString aValue,
@ -196,6 +198,7 @@ interface nsIHTMLEditor : nsISupports
* @return Name of face. Note: "tt" is returned for
* tt tag. "" is returned for none.
*/
[can_run_script]
AString getFontFaceState(out boolean aMixed);
/**
@ -203,6 +206,7 @@ interface nsIHTMLEditor : nsISupports
* @param aMixed True if there is more than one font color
* @return Color string. "" is returned for none.
*/
[can_run_script]
AString getHighlightColorState(out boolean aMixed);
/**
@ -237,6 +241,7 @@ interface nsIHTMLEditor : nsISupports
* @param aAlign enum value for first encountered alignment
* (left/center/right)
*/
[can_run_script]
void getAlignment(out boolean aMixed, out short aAlign);
/**