зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1272623) for negative-leaking
Backed out changeset 063782053b4a (bug 1272623) Backed out changeset e2e4ab888d78 (bug 1272623) Backed out changeset bf6b592e0700 (bug 1272623)
This commit is contained in:
Родитель
0a9fd95b42
Коммит
f0cfa5aa83
|
@ -185,54 +185,26 @@ HTMLEditRules::InitFields()
|
|||
mJoinOffset = 0;
|
||||
mNewBlock = nullptr;
|
||||
mRangeItem = new RangeItem();
|
||||
|
||||
InitStyleCacheArray(mCachedStyles);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLEditRules::InitStyleCacheArray(nsTArray<StyleCache>& aStyleCache)
|
||||
{
|
||||
aStyleCache.Clear();
|
||||
aStyleCache.SetCapacity(SIZE_STYLE_TABLE);
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::b, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::i, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::u, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::font, NS_LITERAL_STRING("face"), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::font, NS_LITERAL_STRING("size"), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::font, NS_LITERAL_STRING("color"), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::tt, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::em, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::strong, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::dfn, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::code, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::samp, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::var, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::cite, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::abbr, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::acronym, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::backgroundColor, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::sub, EmptyString(), EmptyString()));
|
||||
aStyleCache.AppendElement(
|
||||
StyleCache(nsGkAtoms::sup, EmptyString(), EmptyString()));
|
||||
MOZ_ASSERT(aStyleCache.Length() == SIZE_STYLE_TABLE);
|
||||
// populate mCachedStyles
|
||||
mCachedStyles[0] = StyleCache(nsGkAtoms::b, EmptyString(), EmptyString());
|
||||
mCachedStyles[1] = StyleCache(nsGkAtoms::i, EmptyString(), EmptyString());
|
||||
mCachedStyles[2] = StyleCache(nsGkAtoms::u, EmptyString(), EmptyString());
|
||||
mCachedStyles[3] = StyleCache(nsGkAtoms::font, NS_LITERAL_STRING("face"), EmptyString());
|
||||
mCachedStyles[4] = StyleCache(nsGkAtoms::font, NS_LITERAL_STRING("size"), EmptyString());
|
||||
mCachedStyles[5] = StyleCache(nsGkAtoms::font, NS_LITERAL_STRING("color"), EmptyString());
|
||||
mCachedStyles[6] = StyleCache(nsGkAtoms::tt, EmptyString(), EmptyString());
|
||||
mCachedStyles[7] = StyleCache(nsGkAtoms::em, EmptyString(), EmptyString());
|
||||
mCachedStyles[8] = StyleCache(nsGkAtoms::strong, EmptyString(), EmptyString());
|
||||
mCachedStyles[9] = StyleCache(nsGkAtoms::dfn, EmptyString(), EmptyString());
|
||||
mCachedStyles[10] = StyleCache(nsGkAtoms::code, EmptyString(), EmptyString());
|
||||
mCachedStyles[11] = StyleCache(nsGkAtoms::samp, EmptyString(), EmptyString());
|
||||
mCachedStyles[12] = StyleCache(nsGkAtoms::var, EmptyString(), EmptyString());
|
||||
mCachedStyles[13] = StyleCache(nsGkAtoms::cite, EmptyString(), EmptyString());
|
||||
mCachedStyles[14] = StyleCache(nsGkAtoms::abbr, EmptyString(), EmptyString());
|
||||
mCachedStyles[15] = StyleCache(nsGkAtoms::acronym, EmptyString(), EmptyString());
|
||||
mCachedStyles[16] = StyleCache(nsGkAtoms::backgroundColor, EmptyString(), EmptyString());
|
||||
mCachedStyles[17] = StyleCache(nsGkAtoms::sub, EmptyString(), EmptyString());
|
||||
mCachedStyles[18] = StyleCache(nsGkAtoms::sup, EmptyString(), EmptyString());
|
||||
}
|
||||
|
||||
HTMLEditRules::~HTMLEditRules()
|
||||
|
@ -7092,31 +7064,16 @@ HTMLEditRules::CacheInlineStyles(nsIDOMNode* aNode)
|
|||
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
|
||||
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
|
||||
nsresult rv = GetInlineStyles(aNode, mCachedStyles);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLEditRules::GetInlineStyles(nsIDOMNode* aNode,
|
||||
nsTArray<StyleCache>& aStyleCache)
|
||||
{
|
||||
MOZ_ASSERT(aNode);
|
||||
MOZ_ASSERT(mHTMLEditor);
|
||||
|
||||
bool useCSS = mHTMLEditor->IsCSSEnabled();
|
||||
|
||||
for (size_t j = 0; j < aStyleCache.Length(); ++j) {
|
||||
for (int32_t j = 0; j < SIZE_STYLE_TABLE; ++j) {
|
||||
// If type-in state is set, don't intervene
|
||||
bool typeInSet, unused;
|
||||
if (NS_WARN_IF(!mHTMLEditor)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
mHTMLEditor->mTypeInState->GetTypingState(typeInSet, unused,
|
||||
aStyleCache[j].tag, aStyleCache[j].attr, nullptr);
|
||||
mCachedStyles[j].tag, mCachedStyles[j].attr, nullptr);
|
||||
if (typeInSet) {
|
||||
continue;
|
||||
}
|
||||
|
@ -7124,21 +7081,21 @@ HTMLEditRules::GetInlineStyles(nsIDOMNode* aNode,
|
|||
bool isSet = false;
|
||||
nsAutoString outValue;
|
||||
// Don't use CSS for <font size>, we don't support it usefully (bug 780035)
|
||||
if (!useCSS || (aStyleCache[j].tag == nsGkAtoms::font &&
|
||||
aStyleCache[j].attr.EqualsLiteral("size"))) {
|
||||
if (!useCSS || (mCachedStyles[j].tag == nsGkAtoms::font &&
|
||||
mCachedStyles[j].attr.EqualsLiteral("size"))) {
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
mHTMLEditor->IsTextPropertySetByContent(aNode, aStyleCache[j].tag,
|
||||
&(aStyleCache[j].attr), nullptr,
|
||||
mHTMLEditor->IsTextPropertySetByContent(aNode, mCachedStyles[j].tag,
|
||||
&(mCachedStyles[j].attr), nullptr,
|
||||
isSet, &outValue);
|
||||
} else {
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
isSet = mHTMLEditor->mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
|
||||
aNode, aStyleCache[j].tag, &(aStyleCache[j].attr), outValue,
|
||||
aNode, mCachedStyles[j].tag, &(mCachedStyles[j].attr), outValue,
|
||||
CSSEditUtils::eComputed);
|
||||
}
|
||||
if (isSet) {
|
||||
aStyleCache[j].mPresent = true;
|
||||
aStyleCache[j].value.Assign(outValue);
|
||||
mCachedStyles[j].mPresent = true;
|
||||
mCachedStyles[j].value.Assign(outValue);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -7175,17 +7132,7 @@ HTMLEditRules::ReapplyCachedStyles()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
AutoTArray<StyleCache, SIZE_STYLE_TABLE> styleAtInsertionPoint;
|
||||
InitStyleCacheArray(styleAtInsertionPoint);
|
||||
MOZ_ASSERT(styleAtInsertionPoint.Length() == mCachedStyles.Length());
|
||||
nsCOMPtr<nsIDOMNode> selDOMNode = do_QueryInterface(selNode);
|
||||
MOZ_ASSERT(selDOMNode);
|
||||
nsresult rv = GetInlineStyles(selDOMNode, styleAtInsertionPoint);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < mCachedStyles.Length(); ++i) {
|
||||
for (int32_t i = 0; i < SIZE_STYLE_TABLE; ++i) {
|
||||
if (mCachedStyles[i].mPresent) {
|
||||
bool bFirst, bAny, bAll;
|
||||
bFirst = bAny = bAll = false;
|
||||
|
@ -7209,11 +7156,8 @@ HTMLEditRules::ReapplyCachedStyles()
|
|||
&curValue, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
// This style has disappeared through deletion. Let's add the styles to
|
||||
// mTypeInState when same style isn't applied to the node already.
|
||||
if ((!bAny || IsStyleCachePreservingAction(mTheAction)) &&
|
||||
(!styleAtInsertionPoint[i].mPresent ||
|
||||
styleAtInsertionPoint[i].value != mCachedStyles[i].value)) {
|
||||
// this style has disappeared through deletion. Add to our typeinstate:
|
||||
if (!bAny || IsStyleCachePreservingAction(mTheAction)) {
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
mHTMLEditor->mTypeInState->SetProp(mCachedStyles[i].tag,
|
||||
mCachedStyles[i].attr,
|
||||
|
|
|
@ -405,19 +405,6 @@ protected:
|
|||
nsresult ChangeIndentation(Element& aElement, Change aChange);
|
||||
void DocumentModifiedWorker();
|
||||
|
||||
/**
|
||||
* InitStyleCacheArray() initializes aStyleCache for usable with
|
||||
* GetInlineStyles().
|
||||
*/
|
||||
void InitStyleCacheArray(nsTArray<StyleCache>& aStyleCache);
|
||||
|
||||
/**
|
||||
* GetInlineStyles() retrieves the style of aNode and modifies each item of
|
||||
* aStyleCache.
|
||||
*/
|
||||
nsresult GetInlineStyles(nsIDOMNode* aNode,
|
||||
nsTArray<StyleCache>& aStyleCache);
|
||||
|
||||
protected:
|
||||
HTMLEditor* mHTMLEditor;
|
||||
RefPtr<nsRange> mDocChangeRange;
|
||||
|
@ -431,12 +418,7 @@ protected:
|
|||
uint32_t mJoinOffset;
|
||||
nsCOMPtr<Element> mNewBlock;
|
||||
RefPtr<RangeItem> mRangeItem;
|
||||
|
||||
// XXX In strict speaking, mCachedStyles isn't enough to cache inline styles
|
||||
// because inline style can be specified with "style" attribute and/or
|
||||
// CSS in <style> elements or CSS files. So, we need to look for better
|
||||
// implementation about this.
|
||||
nsTArray<StyleCache> mCachedStyles;
|
||||
StyleCache mCachedStyles[SIZE_STYLE_TABLE];
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -226,7 +226,6 @@ skip-if = toolkit == 'android' # bug 1054087
|
|||
[test_dom_input_event_on_texteditor.html]
|
||||
[test_dragdrop.html]
|
||||
skip-if = os == 'android'
|
||||
[test_inline_style_cache.html]
|
||||
[test_inlineTableEditing.html]
|
||||
[test_keypress_untrusted_event.html]
|
||||
[test_objectResizing.html]
|
||||
|
|
|
@ -1,276 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Tests for inline style cache</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none;">
|
||||
|
||||
</div>
|
||||
|
||||
<div id="editor" contenteditable></div>
|
||||
<pre id="test">
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(function() {
|
||||
var editor = document.getElementById("editor");
|
||||
editor.focus();
|
||||
|
||||
var selection = window.getSelection();
|
||||
|
||||
// #01-01 Typing something after setting some styles should insert some nodes to insert text.
|
||||
editor.innerHTML = "beforeafter";
|
||||
selection.collapse(editor.firstChild, "before".length);
|
||||
document.execCommand("bold");
|
||||
document.execCommand("italic");
|
||||
document.execCommand("strikethrough");
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "before<strike><i><b>test</b></i></strike>after",
|
||||
"#01-01 At typing something after setting some styles, should cause inserting some nodes to apply the style");
|
||||
|
||||
// #01-02 Typing something after removing some characters after setting some styles should work as without removing some character.
|
||||
// XXX This behavior is different from Chromium.
|
||||
editor.innerHTML = "beforeafter";
|
||||
selection.collapse(editor.firstChild, "before".length);
|
||||
document.execCommand("bold");
|
||||
document.execCommand("italic");
|
||||
document.execCommand("strikethrough");
|
||||
synthesizeKey("KEY_Delete", { code: "Delete" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "before<strike><i><b>test</b></i></strike>fter",
|
||||
"#01-02-1 At typing something after Delete after setting style, should cause inserting some nodes to apply the style");
|
||||
|
||||
editor.innerHTML = "beforeafter";
|
||||
selection.collapse(editor.firstChild, "before".length);
|
||||
document.execCommand("bold");
|
||||
document.execCommand("italic");
|
||||
document.execCommand("strikethrough");
|
||||
synthesizeKey("KEY_Backspace", { code: "Backspace" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "befor<strike><i><b>test</b></i></strike>after",
|
||||
"#01-02-2 At typing something after Backspace after setting style, should cause inserting some nodes to apply the style");
|
||||
|
||||
// #01-03 Typing Enter after setting some styles should not ignore the styles.
|
||||
editor.innerHTML = "beforeafter";
|
||||
selection.collapse(editor.firstChild, "before".length);
|
||||
document.execCommand("bold");
|
||||
document.execCommand("italic");
|
||||
document.execCommand("strikethrough");
|
||||
synthesizeKey("KEY_Enter", { code: "Enter" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "before<br><strike><i><b>test</b></i></strike>after",
|
||||
"#01-03-1 Typing Enter after setting style should not ignore the styles");
|
||||
|
||||
editor.innerHTML = "<p>beforeafter</p>";
|
||||
selection.collapse(editor.firstChild.firstChild, "before".length);
|
||||
document.execCommand("bold");
|
||||
document.execCommand("italic");
|
||||
document.execCommand("strikethrough");
|
||||
synthesizeKey("KEY_Enter", { code: "Enter" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "<p>before</p><p><strike><i><b>test</b></i></strike>after</p>",
|
||||
"#01-03-2 Typing Enter after setting style should not ignore the styles");
|
||||
|
||||
// #02-01 Replacing text with typing some text after setting some styles should work as just inserting text.
|
||||
// XXX Chromium works as expected.
|
||||
editor.innerHTML = "beforeselectionafter";
|
||||
selection.collapse(editor.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild, "beforeselection".length);
|
||||
document.execCommand("bold");
|
||||
document.execCommand("italic");
|
||||
document.execCommand("strikethrough");
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
// XXX <strike> is not handled correctly in this case.
|
||||
todo_is(editor.innerHTML, "before<strike><i><b>test</b></i></strike>after",
|
||||
"#02-01 At replacing \"selection\" after setting some styles, should keep the styles at inserting text");
|
||||
// XXX For testing current (buggy) behavior for now.
|
||||
is(editor.innerHTML, "before<i><b>test</b></i><strike><i><b></b></i></strike>after",
|
||||
"#02-01 At replacing \"selection\" after setting some styles, should keep the styles");
|
||||
|
||||
// #02-02 Inserting text after removing selected text after setting some styles should not keep the styles.
|
||||
// XXX Chromium keeps the style.
|
||||
editor.innerHTML = "beforeselectionafter";
|
||||
selection.collapse(editor.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild, "beforeselection".length);
|
||||
document.execCommand("bold");
|
||||
document.execCommand("italic");
|
||||
document.execCommand("strikethrough");
|
||||
synthesizeKey("KEY_Backspace", { code: "Backspace" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "beforetestafter",
|
||||
"#02-02 After removing \"selection\" after setting some styles, should not keep the styles");
|
||||
|
||||
// #02-03 Inserting text after replacing selected text after setting some styles should keep the styles.
|
||||
editor.innerHTML = "beforeselectionafter";
|
||||
selection.collapse(editor.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild, "beforeselection".length);
|
||||
document.execCommand("bold");
|
||||
document.execCommand("italic");
|
||||
document.execCommand("strikethrough");
|
||||
synthesizeKey("KEY_Enter", { code: "Enter" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
// XXX <strike> is not handled correctly in this case.
|
||||
todo_is(editor.innerHTML, "before<br><strike><i><b>test</b></i></strike>after",
|
||||
"#02-03-1 Typing Enter after setting style to selected text should keep the styles");
|
||||
// XXX For testing current (buggy) behavior for now.
|
||||
is(editor.innerHTML, "before<br><i><b>test</b></i><strike><i><b></b></i></strike>after",
|
||||
"#02-03-1 Typing Enter after setting style to selected text should keep the styles");
|
||||
|
||||
editor.innerHTML = "<p>beforeselectionafter</p>";
|
||||
selection.collapse(editor.firstChild.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild.firstChild, "beforeselection".length);
|
||||
document.execCommand("bold");
|
||||
document.execCommand("italic");
|
||||
document.execCommand("strikethrough");
|
||||
synthesizeKey("KEY_Enter", { code: "Enter" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "<p>before</p><p><strike><i><b>test</b></i></strike>after</p>",
|
||||
"#02-03-2 Typing Enter after setting style to selected text should keep the styles");
|
||||
|
||||
// #03-01 Replacing in <b style="font-weight: normal;"> shouldn't cause new <b>.
|
||||
editor.innerHTML = "<b style=\"font-weight: normal;\">beforeselectionafter</b>";
|
||||
selection.collapse(editor.firstChild.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild.firstChild, "beforeselection".length);
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "<b style=\"font-weight: normal;\">beforetestafter</b>",
|
||||
"#03-01 Replacing text in styled inline elements should respect the styles");
|
||||
|
||||
// #03-02 Typing something after removing selected text in <b style="font-weight: normal;"> shouldn't cause new <b>.
|
||||
editor.innerHTML = "<b style=\"font-weight: normal;\">beforeselectionafter</b>";
|
||||
selection.collapse(editor.firstChild.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild.firstChild, "beforeselection".length);
|
||||
synthesizeKey("KEY_Backspace", { code: "Backspace" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "<b style=\"font-weight: normal;\">beforetestafter</b>",
|
||||
"#03-02 Inserting text after removing text in styled inline elements should respect the styles");
|
||||
|
||||
// #03-03 Typing something after typing Enter at selected text in <b style="font-weight: normal;"> shouldn't cause new <b>.
|
||||
editor.innerHTML = "<b style=\"font-weight: normal;\">beforeselectionafter</b>";
|
||||
selection.collapse(editor.firstChild.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild.firstChild, "beforeselection".length);
|
||||
synthesizeKey("KEY_Enter", { code: "Enter" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "<b style=\"font-weight: normal;\">before<br>testafter</b>",
|
||||
"#03-03-1 Inserting text after typing Enter at selected text in styled inline elements should respect the styles");
|
||||
|
||||
editor.innerHTML = "<p><b style=\"font-weight: normal;\">beforeselectionafter</b></p>";
|
||||
selection.collapse(editor.firstChild.firstChild.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild.firstChild.firstChild, "beforeselection".length);
|
||||
synthesizeKey("KEY_Enter", { code: "Enter" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "<p><b style=\"font-weight: normal;\">before</b></p><p><b style=\"font-weight: normal;\">testafter</b></p>",
|
||||
"#03-03-2 Inserting text after typing Enter at selected text in styled inline elements should respect the styles");
|
||||
|
||||
// #04-01 Replacing in some styled inline elements shouldn't cause new same elements.
|
||||
editor.innerHTML = "<strike style=\"text-decoration: none;\"><i style=\"font-style: normal;\"><b style=\"font-weight: normal;\">beforeselectionafter</b></i></strike>";
|
||||
selection.collapse(editor.firstChild.firstChild.firstChild.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild.firstChild.firstChild.firstChild, "beforeselection".length);
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "<strike style=\"text-decoration: none;\"><i style=\"font-style: normal;\"><b style=\"font-weight: normal;\">beforetestafter</b></i></strike>",
|
||||
"#04-01 Replacing text in styled inline elements should respect the styles");
|
||||
|
||||
// #04-02 Typing something after removing selected text in some styled inline elements shouldn't cause new same elements.
|
||||
editor.innerHTML = "<strike style=\"text-decoration: none;\"><i style=\"font-style: normal;\"><b style=\"font-weight: normal;\">beforeselectionafter</b>";
|
||||
selection.collapse(editor.firstChild.firstChild.firstChild.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild.firstChild.firstChild.firstChild, "beforeselection".length);
|
||||
synthesizeKey("KEY_Backspace", { code: "Backspace" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "<strike style=\"text-decoration: none;\"><i style=\"font-style: normal;\"><b style=\"font-weight: normal;\">beforetestafter</b></i></strike>",
|
||||
"#04-02 Inserting text after removing text in styled inline elements should respect the styles");
|
||||
|
||||
// #04-03 Typing something after typing Enter at selected text in some styled inline elements shouldn't cause new same elements.
|
||||
editor.innerHTML = "<strike style=\"text-decoration: none;\"><i style=\"font-style: normal;\"><b style=\"font-weight: normal;\">beforeselectionafter</b>";
|
||||
selection.collapse(editor.firstChild.firstChild.firstChild.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild.firstChild.firstChild.firstChild, "beforeselection".length);
|
||||
synthesizeKey("KEY_Enter", { code: "Enter" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "<strike style=\"text-decoration: none;\"><i style=\"font-style: normal;\"><b style=\"font-weight: normal;\">before<br>testafter</b></i></strike>",
|
||||
"#04-03-1 Inserting text after typing Enter at selected text in styled inline elements should respect the styles");
|
||||
|
||||
editor.innerHTML = "<p><strike style=\"text-decoration: none;\"><i style=\"font-style: normal;\"><b style=\"font-weight: normal;\">beforeselectionafter</b></p>";
|
||||
selection.collapse(editor.firstChild.firstChild.firstChild.firstChild.firstChild, "before".length);
|
||||
selection.extend(editor.firstChild.firstChild.firstChild.firstChild.firstChild, "beforeselection".length);
|
||||
synthesizeKey("KEY_Enter", { code: "Enter" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
synthesizeKey("e", { code: "KeyE" });
|
||||
synthesizeKey("s", { code: "KeyS" });
|
||||
synthesizeKey("t", { code: "KeyT" });
|
||||
|
||||
is(editor.innerHTML, "<p><strike style=\"text-decoration: none;\"><i style=\"font-style: normal;\"><b style=\"font-weight: normal;\">before</b></i></strike></p><p><strike style=\"text-decoration: none;\"><i style=\"font-style: normal;\"><b style=\"font-weight: normal;\">testafter</b></i></strike></p>",
|
||||
"#04-03-2 Inserting text after typing Enter at selected text in styled inline elements should respect the styles");
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -969,6 +969,7 @@ mozInlineSpellChecker::ReplaceWord(nsIDOMNode *aNode, int32_t aOffset,
|
|||
NS_ENSURE_SUCCESS(res, res);
|
||||
selection->RemoveAllRanges();
|
||||
selection->AddRange(editorRange);
|
||||
editor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
|
||||
|
||||
nsCOMPtr<nsIPlaintextEditor> textEditor(do_QueryReferent(mEditor));
|
||||
if (textEditor)
|
||||
|
|
|
@ -4,5 +4,3 @@ skip-if = os == 'android'
|
|||
[test_bug1170484.html]
|
||||
support-files = helper_bug1170484.js
|
||||
skip-if = os == 'linux' #Bug 1202570
|
||||
|
||||
[test_bug1272623.html]
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1272623
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1272623</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script src="/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1272623">Mozilla Bug 1272623</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<div id="area" contenteditable="true"><b style="font-weight:normal;">testing <span id="misspelled">spellechek</span></b></div>
|
||||
<div id="area2" contenteditable="true">testing <span id="misspelled2" style="font-weight:bold;">spellechek</span></div>
|
||||
</pre>
|
||||
<script>
|
||||
|
||||
/** Test for Bug 1272623 **/
|
||||
|
||||
function *performCorrection(misspelled, area) {
|
||||
synthesizeMouseAtCenter($(misspelled), {}, window);
|
||||
yield new Promise(resolve => onSpellCheck($(area), resolve));
|
||||
synthesizeMouseAtCenter($(misspelled), {type: 'contextmenu'}, window);
|
||||
|
||||
// Perform the spelling correction
|
||||
let mm = SpecialPowers.loadChromeScript(function() {
|
||||
let Cu = Components.utils;
|
||||
let Ci = Components.interfaces;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Chrome scripts are run with synchronous messages, so make sure we're completely
|
||||
// decoupled from the content process before doing this work.
|
||||
Cu.dispatch(function() {
|
||||
let chromeWin = Services.ww.activeWindow.QueryInterface(Ci.nsIDOMChromeWindow);
|
||||
contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
|
||||
let suggestion = contextMenu.querySelector(".spell-suggestion");
|
||||
suggestion.doCommand();
|
||||
contextMenu.hidePopup();
|
||||
sendAsyncMessage("spellingCorrected");
|
||||
});
|
||||
});
|
||||
info("Loaded chrome script");
|
||||
yield new Promise(resolve => mm.addMessageListener('spellingCorrected', resolve));
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
SpecialPowers.Cu.import("resource://gre/modules/AsyncSpellCheckTestHelper.jsm", window);
|
||||
|
||||
// Wait for the page to be ready
|
||||
yield new Promise(resolve => SimpleTest.waitForFocus(() => SimpleTest.executeSoon(resolve), window));
|
||||
|
||||
// Check that <b> tags aren't inserted inside of other <b> tags when it would change the style
|
||||
yield* performCorrection('misspelled', 'area');
|
||||
is($('area').innerHTML, "<b style=\"font-weight:normal;\">testing <span id=\"misspelled\">spellcheck</span></b>");
|
||||
is($('area').textContent, 'testing spellcheck', "Spelling corrected properly");
|
||||
|
||||
// Check that nodes aren't removed when the entire text inside of them is spelling-corrected
|
||||
yield* performCorrection('misspelled2', 'area2');
|
||||
is($('area2').innerHTML, "testing <span id=\"misspelled2\" style=\"font-weight:bold;\">spellcheck</span>");
|
||||
is($('area2').textContent, 'testing spellcheck', "Spelling corrected properly");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -282,6 +282,9 @@
|
|||
[[["stylewithcss","false"\],["inserttext","a"\]\] "<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz\]</span>quz" compare innerHTML]
|
||||
expected: FAIL
|
||||
|
||||
[[["inserttext","a"\]\] "foo<font color=brown><a href=http://www.google.com>[bar\]</a></font>baz" compare innerHTML]
|
||||
expected: FAIL
|
||||
|
||||
[[["stylewithcss","true"\],["inserttext","a"\]\] "[foo<b>bar\]</b>baz" compare innerHTML]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче