зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1510183 - Make HTMLEditor treat empty string attribute of style as nullptr of nsAtom rather than nsGkAtoms::_empty r=m_kato
After fixing bug 1427060, HTMLEditor treats attribute of style as nullptr. However, if empty string is used to call NS_Atomize(), it returns nsGkAtoms::_empty. Therefore, HTMLEditor fails to check whether attribute is specified or not with nullptr check since some root callers sets nsGkAtoms::_empty instead of nullptr. This patch makes HTMLEditor always use nullptr for empty string of attribute of style with wrapping NS_Atomize() with AtomzieAttribute(). Additionally, for safer change, this patch makes PropItem and TypeInState treat nsGkAtom::_empty as nullptr. Differential Revision: https://phabricator.services.mozilla.com/D13203 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
4d4e348fc8
Коммит
7348477018
|
@ -376,6 +376,17 @@ public:
|
|||
/**
|
||||
* 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.
|
||||
* Must not use nsGkAtoms::_empty here.
|
||||
*/
|
||||
nsresult RemoveInlinePropertyAsAction(nsAtom& aProperty,
|
||||
nsAtom* aAttribute);
|
||||
|
|
|
@ -45,6 +45,15 @@ 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);
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLEditor::IsEmptyTextNode(nsINode& aNode)
|
||||
{
|
||||
|
@ -97,7 +106,7 @@ HTMLEditor::SetInlineProperty(const nsAString& aProperty,
|
|||
if (NS_WARN_IF(!property)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
|
||||
RefPtr<nsAtom> attribute = AtomizeAttribute(aAttribute);
|
||||
AutoEditActionDataSetter editActionData(
|
||||
*this,
|
||||
HTMLEditUtils::GetEditActionForFormatText(*property, attribute, true));
|
||||
|
@ -1210,7 +1219,7 @@ HTMLEditor::GetInlineProperty(const nsAString& aProperty,
|
|||
bool* aAll)
|
||||
{
|
||||
RefPtr<nsAtom> property = NS_Atomize(aProperty);
|
||||
RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
|
||||
RefPtr<nsAtom> attribute = AtomizeAttribute(aAttribute);
|
||||
return GetInlineProperty(property, attribute, aValue, aFirst, aAny, aAll);
|
||||
}
|
||||
|
||||
|
@ -1251,7 +1260,7 @@ HTMLEditor::GetInlinePropertyWithAttrValue(const nsAString& aProperty,
|
|||
nsAString& outValue)
|
||||
{
|
||||
RefPtr<nsAtom> property = NS_Atomize(aProperty);
|
||||
RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
|
||||
RefPtr<nsAtom> attribute = AtomizeAttribute(aAttribute);
|
||||
return GetInlinePropertyWithAttrValue(property, attribute, aValue, aFirst,
|
||||
aAny, aAll, outValue);
|
||||
}
|
||||
|
@ -1326,7 +1335,7 @@ HTMLEditor::RemoveInlineProperty(const nsAString& aProperty,
|
|||
const nsAString& aAttribute)
|
||||
{
|
||||
RefPtr<nsAtom> property = NS_Atomize(aProperty);
|
||||
RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
|
||||
RefPtr<nsAtom> attribute = AtomizeAttribute(aAttribute);
|
||||
|
||||
AutoEditActionDataSetter editActionData(
|
||||
*this,
|
||||
|
@ -1343,6 +1352,7 @@ HTMLEditor::RemoveInlinePropertyInternal(nsAtom* aProperty,
|
|||
nsAtom* aAttribute)
|
||||
{
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(aAttribute != nsGkAtoms::_empty);
|
||||
|
||||
if (NS_WARN_IF(!mRules)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
|
|
@ -299,6 +299,9 @@ TypeInState::IsPropSet(nsAtom* aProp,
|
|||
nsAString* outValue,
|
||||
int32_t& outIndex)
|
||||
{
|
||||
if (aAttr == nsGkAtoms::_empty) {
|
||||
aAttr = nullptr;
|
||||
}
|
||||
// linear search. list should be short.
|
||||
size_t count = mSetArray.Length();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
|
@ -347,6 +350,9 @@ TypeInState::FindPropInList(nsAtom* aProp,
|
|||
nsTArray<PropItem*>& aList,
|
||||
int32_t& outIndex)
|
||||
{
|
||||
if (aAttr == nsGkAtoms::_empty) {
|
||||
aAttr = nullptr;
|
||||
}
|
||||
// linear search. list should be short.
|
||||
size_t count = aList.Length();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
|
@ -377,7 +383,7 @@ PropItem::PropItem(nsAtom* aTag,
|
|||
nsAtom* aAttr,
|
||||
const nsAString &aValue)
|
||||
: tag(aTag)
|
||||
, attr(aAttr)
|
||||
, attr(aAttr != nsGkAtoms::_empty ? aAttr : nullptr)
|
||||
, value(aValue)
|
||||
{
|
||||
MOZ_COUNT_CTOR(PropItem);
|
||||
|
|
|
@ -285,6 +285,7 @@ subsuite = clipboard
|
|||
skip-if = android_version == '24'
|
||||
[test_nsIEditorMailSupport_insertAsCitedQuotation.html]
|
||||
[test_nsIHTMLEditor_getSelectedElement.html]
|
||||
[test_nsIHTMLEditor_removeInlineProperty.html]
|
||||
[test_nsIHTMLEditor_selectElement.html]
|
||||
[test_nsIHTMLEditor_setCaretAfterElement.html]
|
||||
[test_nsIHTMLObjectResizer_hideResizers.html]
|
||||
|
|
|
@ -0,0 +1,334 @@
|
|||
<!DOCTYPE>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for nsIHTMLEditor.removeInlineProperty()</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="display">
|
||||
</div>
|
||||
<div id="content" contenteditable></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(function() {
|
||||
let editor = document.getElementById("content");
|
||||
let selection = window.getSelection();
|
||||
let description, condition;
|
||||
let inputEvents = [];
|
||||
function onInput(aEvent) {
|
||||
inputEvents.push(aEvent);
|
||||
}
|
||||
editor.addEventListener("input", onInput);
|
||||
|
||||
function checkInputEvent(aEvent, aDescription) {
|
||||
if (aEvent.type != "input") {
|
||||
return;
|
||||
}
|
||||
ok(aEvent instanceof InputEvent, `${aDescription}"input" event should be dispatched with InputEvent interface`);
|
||||
is(aEvent.cancelable, false, `${aDescription}"input" event should be never cancelable`);
|
||||
is(aEvent.bubbles, true, `${aDescription}"input" event should always bubble`);
|
||||
}
|
||||
|
||||
function selectFromTextSiblings(aNode) {
|
||||
condition = "selecting the node from end of previous text to start of next text node";
|
||||
selection.setBaseAndExtent(aNode.previousSibling, aNode.previousSibling.length,
|
||||
aNode.nextSibling, 0);
|
||||
}
|
||||
function selectNode(aNode) {
|
||||
condition = "selecting the node";
|
||||
let range = document.createRange();
|
||||
range.selectNode(aNode);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
function selectAllChildren(aNode) {
|
||||
condition = "selecting all children of the node";
|
||||
selection.selectAllChildren(aNode);
|
||||
}
|
||||
function selectChildContents(aNode) {
|
||||
condition = "selecting all contents of its child";
|
||||
let range = document.createRange();
|
||||
range.selectNodeContents(aNode.firstChild);
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
}
|
||||
|
||||
description = "When there is a <b> element and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = "<p>test: <b>here</b> is bolden text</p>";
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("b", "");
|
||||
is(editor.innerHTML, "<p>test: here is bolden text</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should remove the <b> element');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
description = "When there is a <b> element which has style attribute and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = '<p>test: <b style="font-style: italic">here</b> is bolden text</p>';
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("b", "");
|
||||
is(editor.innerHTML, '<p>test: <span style="font-style: italic">here</span> is bolden text</p>',
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should replace the <b> element with <span> element to keep the style');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
description = "When there is a <b> element which has class attribute and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = '<p>test: <b class="foo">here</b> is bolden text</p>';
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("b", "");
|
||||
is(editor.innerHTML, '<p>test: <span class="foo">here</span> is bolden text</p>',
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should replace the <b> element with <span> element to keep the class');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
description = "When there is a <b> element which has an <i> element and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = "<p>test: <b><i>here</i></b> is bolden and italic text</p>";
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("b", "");
|
||||
is(editor.innerHTML, "<p>test: <i>here</i> is bolden and italic text</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should remove only the <b> element');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
description = "When there is a <b> element which has an <i> element and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = "<p>test: <b><i>here</i></b> is bolden and italic text</p>";
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("i", "");
|
||||
is(editor.innerHTML, "<p>test: <b>here</b> is bolden and italic text</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("i", "") should remove only the <i> element');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("i", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
description = "When there is an <i> element in a <b> element and ";
|
||||
for (let prepare of [selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = "<p>test: <b><i>here</i></b> is bolden and italic text</p>";
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling.firstChild);
|
||||
getHTMLEditor().removeInlineProperty("b", "");
|
||||
is(editor.innerHTML, "<p>test: <i>here</i> is bolden and italic text</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should remove only the <b> element');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
description = "When there is an <i> element in a <b> element and ";
|
||||
for (let prepare of [selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = "<p>test: <b><i>here</i></b> is bolden and italic text</p>";
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling.firstChild);
|
||||
getHTMLEditor().removeInlineProperty("i", "");
|
||||
is(editor.innerHTML, "<p>test: <b>here</b> is bolden and italic text</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("i", "") should remove only the <i> element');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("i", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
description = "When there is an <i> element between text nodes in a <b> element and ";
|
||||
for (let prepare of [selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = "<p>test: <b>h<i>e</i>re</b> is bolden and italic text</p>";
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("i", "");
|
||||
is(editor.innerHTML, "<p>test: <b>here</b> is bolden and italic text</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("i", "") should remove only the <i> element');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("i", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
description = "When there is an <i> element between text nodes in a <b> element and ";
|
||||
for (let prepare of [selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = "<p>test: <b>h<i>e</i>re</b> is bolden and italic text</p>";
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("b", "");
|
||||
is(editor.innerHTML, "<p>test: <b>h</b><i>e</i><b>re</b> is bolden and italic text</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should split the <b> element');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("b", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
description = "When there is an <a> element whose href attribute is not empty and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = '<p>test: <a href="about:blank">here</a> is a link</p>';
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("href", "");
|
||||
is(editor.innerHTML, "<p>test: here is a link</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("href", "") should remove the <a> element');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("href", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX In the case of "name", removeInlineProperty() does not the <a> element when name attribute is empty.
|
||||
description = "When there is an <a> element whose href attribute is empty and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = '<p>test: <a href="">here</a> is a link</p>';
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("href", "");
|
||||
is(editor.innerHTML, "<p>test: here is a link</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("href", "") should remove the <a> element');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("href", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
description = "When there is an <a> element which does not have href attribute and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = "<p>test: <a>here</a> is an anchor</p>";
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("href", "");
|
||||
is(editor.innerHTML, "<p>test: <a>here</a> is an anchor</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("href", "") should NOT remove the <a> element');
|
||||
is(inputEvents.length, 0,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("href", "") should NOT cause an "input" event');
|
||||
}
|
||||
|
||||
description = "When there is an <a> element whose name attribute is not empty and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = '<p>test: <a name="foo">here</a> is a named anchor</p>';
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("href", "");
|
||||
is(editor.innerHTML, '<p>test: <a name="foo">here</a> is a named anchor</p>',
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("href", "") should NOT remove the <a> element');
|
||||
is(inputEvents.length, 0,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("href", "") should NOT cause an "input" event');
|
||||
}
|
||||
|
||||
description = "When there is an <a> element whose name attribute is not empty and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = '<p>test: <a name="foo">here</a> is a named anchor</p>';
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("name", "");
|
||||
is(editor.innerHTML, "<p>test: here is a named anchor</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("name", "") should remove the <a> element');
|
||||
is(inputEvents.length, 1,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("name", "") should cause an "input" event');
|
||||
if (inputEvents.length > 0) {
|
||||
checkInputEvent(inputEvents[0], description);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX In the case of "href", removeInlineProperty() removes the <a> element when href attribute is empty.
|
||||
description = "When there is an <a> element whose name attribute is empty and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = '<p>test: <a name="">here</a> is a named anchor</p>';
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("name", "");
|
||||
is(editor.innerHTML, '<p>test: <a name="">here</a> is a named anchor</p>',
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("name", "") should NOT remove the <a> element');
|
||||
is(inputEvents.length, 0,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("name", "") should NOT cause an "input" event');
|
||||
}
|
||||
|
||||
description = "When there is an <a> element which does not have name attribute and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = "<p>test: <a>here</a> is an anchor</p>";
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("name", "");
|
||||
is(editor.innerHTML, "<p>test: <a>here</a> is an anchor</p>",
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("name", "") should NOT remove the <a> element');
|
||||
is(inputEvents.length, 0,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("name", "") should NOT cause an "input" event');
|
||||
}
|
||||
|
||||
description = "When there is an <a> element whose href attribute is not empty and ";
|
||||
for (let prepare of [selectFromTextSiblings, selectNode, selectAllChildren, selectChildContents]) {
|
||||
editor.innerHTML = '<p>test: <a href="about:blank">here</a> is a link</p>';
|
||||
editor.focus();
|
||||
inputEvents = [];
|
||||
prepare(editor.firstChild.firstChild.nextSibling);
|
||||
getHTMLEditor().removeInlineProperty("name", "");
|
||||
is(editor.innerHTML, '<p>test: <a href="about:blank">here</a> is a link</p>',
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("name", "") should NOT remove the <a> element');
|
||||
is(inputEvents.length, 0,
|
||||
description + condition + ': nsIHTMLEditor.removeInlineProperty("name", "") should NOT cause an "input" event');
|
||||
}
|
||||
|
||||
editor.removeEventListener("input", onInput);
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
function getHTMLEditor() {
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var editingSession = SpecialPowers.wrap(window).docShell.editingSession;
|
||||
return editingSession.getEditorForWindow(window).QueryInterface(Ci.nsIHTMLEditor);
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -88,21 +88,17 @@ interface nsIHTMLEditor : nsISupports
|
|||
|
||||
|
||||
/**
|
||||
* removeInlineProperty() deletes the properties from all text in the current
|
||||
* selection. If aProperty is not set on the selection, nothing is done.
|
||||
* removeInlineProperty() removes a property which changes inline style of
|
||||
* text. E.g., bold, italic, super and sub.
|
||||
*
|
||||
* @param aProperty the property to remove from the selection
|
||||
* All atoms are for normal HTML tags (e.g.:
|
||||
* nsIEditorProperty::font) except when you want to
|
||||
* remove just links and not named anchors.
|
||||
* For that, use nsIEditorProperty::href
|
||||
* @param aAttribute the attribute of the property, if applicable.
|
||||
* May be null.
|
||||
* Example: aProperty=nsIEditorProptery::font,
|
||||
* aAttribute="color"
|
||||
* nsIEditProperty::allAttributes is special.
|
||||
* It indicates that all content-based text properties
|
||||
* are to be removed from the selection.
|
||||
* @param aProperty Tag name whcih represents the inline style you want to
|
||||
* remove. E.g., "strong", "b", etc.
|
||||
* If "href", <a> element which has href attribute will be
|
||||
* removed.
|
||||
* If "name", <a> element which has non-empty name
|
||||
* attribute will be removed.
|
||||
* @param aAttribute If aProperty is "font", aAttribute should be "face",
|
||||
* "size", "color" or "bgcolor".
|
||||
*/
|
||||
void removeInlineProperty(in AString aProperty, in AString aAttribute);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче