mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
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:
parent
0a9fd95b42
commit
f0cfa5aa83
@ -185,54 +185,26 @@ HTMLEditRules::InitFields()
|
|||||||
mJoinOffset = 0;
|
mJoinOffset = 0;
|
||||||
mNewBlock = nullptr;
|
mNewBlock = nullptr;
|
||||||
mRangeItem = new RangeItem();
|
mRangeItem = new RangeItem();
|
||||||
|
// populate mCachedStyles
|
||||||
InitStyleCacheArray(mCachedStyles);
|
mCachedStyles[0] = StyleCache(nsGkAtoms::b, EmptyString(), EmptyString());
|
||||||
}
|
mCachedStyles[1] = StyleCache(nsGkAtoms::i, EmptyString(), EmptyString());
|
||||||
|
mCachedStyles[2] = StyleCache(nsGkAtoms::u, EmptyString(), EmptyString());
|
||||||
void
|
mCachedStyles[3] = StyleCache(nsGkAtoms::font, NS_LITERAL_STRING("face"), EmptyString());
|
||||||
HTMLEditRules::InitStyleCacheArray(nsTArray<StyleCache>& aStyleCache)
|
mCachedStyles[4] = StyleCache(nsGkAtoms::font, NS_LITERAL_STRING("size"), EmptyString());
|
||||||
{
|
mCachedStyles[5] = StyleCache(nsGkAtoms::font, NS_LITERAL_STRING("color"), EmptyString());
|
||||||
aStyleCache.Clear();
|
mCachedStyles[6] = StyleCache(nsGkAtoms::tt, EmptyString(), EmptyString());
|
||||||
aStyleCache.SetCapacity(SIZE_STYLE_TABLE);
|
mCachedStyles[7] = StyleCache(nsGkAtoms::em, EmptyString(), EmptyString());
|
||||||
aStyleCache.AppendElement(
|
mCachedStyles[8] = StyleCache(nsGkAtoms::strong, EmptyString(), EmptyString());
|
||||||
StyleCache(nsGkAtoms::b, EmptyString(), EmptyString()));
|
mCachedStyles[9] = StyleCache(nsGkAtoms::dfn, EmptyString(), EmptyString());
|
||||||
aStyleCache.AppendElement(
|
mCachedStyles[10] = StyleCache(nsGkAtoms::code, EmptyString(), EmptyString());
|
||||||
StyleCache(nsGkAtoms::i, EmptyString(), EmptyString()));
|
mCachedStyles[11] = StyleCache(nsGkAtoms::samp, EmptyString(), EmptyString());
|
||||||
aStyleCache.AppendElement(
|
mCachedStyles[12] = StyleCache(nsGkAtoms::var, EmptyString(), EmptyString());
|
||||||
StyleCache(nsGkAtoms::u, EmptyString(), EmptyString()));
|
mCachedStyles[13] = StyleCache(nsGkAtoms::cite, EmptyString(), EmptyString());
|
||||||
aStyleCache.AppendElement(
|
mCachedStyles[14] = StyleCache(nsGkAtoms::abbr, EmptyString(), EmptyString());
|
||||||
StyleCache(nsGkAtoms::font, NS_LITERAL_STRING("face"), EmptyString()));
|
mCachedStyles[15] = StyleCache(nsGkAtoms::acronym, EmptyString(), EmptyString());
|
||||||
aStyleCache.AppendElement(
|
mCachedStyles[16] = StyleCache(nsGkAtoms::backgroundColor, EmptyString(), EmptyString());
|
||||||
StyleCache(nsGkAtoms::font, NS_LITERAL_STRING("size"), EmptyString()));
|
mCachedStyles[17] = StyleCache(nsGkAtoms::sub, EmptyString(), EmptyString());
|
||||||
aStyleCache.AppendElement(
|
mCachedStyles[18] = StyleCache(nsGkAtoms::sup, EmptyString(), EmptyString());
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HTMLEditRules::~HTMLEditRules()
|
HTMLEditRules::~HTMLEditRules()
|
||||||
@ -7092,31 +7064,16 @@ HTMLEditRules::CacheInlineStyles(nsIDOMNode* aNode)
|
|||||||
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
|
||||||
|
|
||||||
NS_ENSURE_STATE(mHTMLEditor);
|
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();
|
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
|
// If type-in state is set, don't intervene
|
||||||
bool typeInSet, unused;
|
bool typeInSet, unused;
|
||||||
if (NS_WARN_IF(!mHTMLEditor)) {
|
if (NS_WARN_IF(!mHTMLEditor)) {
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
mHTMLEditor->mTypeInState->GetTypingState(typeInSet, unused,
|
mHTMLEditor->mTypeInState->GetTypingState(typeInSet, unused,
|
||||||
aStyleCache[j].tag, aStyleCache[j].attr, nullptr);
|
mCachedStyles[j].tag, mCachedStyles[j].attr, nullptr);
|
||||||
if (typeInSet) {
|
if (typeInSet) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -7124,21 +7081,21 @@ HTMLEditRules::GetInlineStyles(nsIDOMNode* aNode,
|
|||||||
bool isSet = false;
|
bool isSet = false;
|
||||||
nsAutoString outValue;
|
nsAutoString outValue;
|
||||||
// Don't use CSS for <font size>, we don't support it usefully (bug 780035)
|
// Don't use CSS for <font size>, we don't support it usefully (bug 780035)
|
||||||
if (!useCSS || (aStyleCache[j].tag == nsGkAtoms::font &&
|
if (!useCSS || (mCachedStyles[j].tag == nsGkAtoms::font &&
|
||||||
aStyleCache[j].attr.EqualsLiteral("size"))) {
|
mCachedStyles[j].attr.EqualsLiteral("size"))) {
|
||||||
NS_ENSURE_STATE(mHTMLEditor);
|
NS_ENSURE_STATE(mHTMLEditor);
|
||||||
mHTMLEditor->IsTextPropertySetByContent(aNode, aStyleCache[j].tag,
|
mHTMLEditor->IsTextPropertySetByContent(aNode, mCachedStyles[j].tag,
|
||||||
&(aStyleCache[j].attr), nullptr,
|
&(mCachedStyles[j].attr), nullptr,
|
||||||
isSet, &outValue);
|
isSet, &outValue);
|
||||||
} else {
|
} else {
|
||||||
NS_ENSURE_STATE(mHTMLEditor);
|
NS_ENSURE_STATE(mHTMLEditor);
|
||||||
isSet = mHTMLEditor->mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
|
isSet = mHTMLEditor->mCSSEditUtils->IsCSSEquivalentToHTMLInlineStyleSet(
|
||||||
aNode, aStyleCache[j].tag, &(aStyleCache[j].attr), outValue,
|
aNode, mCachedStyles[j].tag, &(mCachedStyles[j].attr), outValue,
|
||||||
CSSEditUtils::eComputed);
|
CSSEditUtils::eComputed);
|
||||||
}
|
}
|
||||||
if (isSet) {
|
if (isSet) {
|
||||||
aStyleCache[j].mPresent = true;
|
mCachedStyles[j].mPresent = true;
|
||||||
aStyleCache[j].value.Assign(outValue);
|
mCachedStyles[j].value.Assign(outValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -7175,17 +7132,7 @@ HTMLEditRules::ReapplyCachedStyles()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoTArray<StyleCache, SIZE_STYLE_TABLE> styleAtInsertionPoint;
|
for (int32_t i = 0; i < SIZE_STYLE_TABLE; ++i) {
|
||||||
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) {
|
|
||||||
if (mCachedStyles[i].mPresent) {
|
if (mCachedStyles[i].mPresent) {
|
||||||
bool bFirst, bAny, bAll;
|
bool bFirst, bAny, bAll;
|
||||||
bFirst = bAny = bAll = false;
|
bFirst = bAny = bAll = false;
|
||||||
@ -7209,11 +7156,8 @@ HTMLEditRules::ReapplyCachedStyles()
|
|||||||
&curValue, false);
|
&curValue, false);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
// This style has disappeared through deletion. Let's add the styles to
|
// this style has disappeared through deletion. Add to our typeinstate:
|
||||||
// mTypeInState when same style isn't applied to the node already.
|
if (!bAny || IsStyleCachePreservingAction(mTheAction)) {
|
||||||
if ((!bAny || IsStyleCachePreservingAction(mTheAction)) &&
|
|
||||||
(!styleAtInsertionPoint[i].mPresent ||
|
|
||||||
styleAtInsertionPoint[i].value != mCachedStyles[i].value)) {
|
|
||||||
NS_ENSURE_STATE(mHTMLEditor);
|
NS_ENSURE_STATE(mHTMLEditor);
|
||||||
mHTMLEditor->mTypeInState->SetProp(mCachedStyles[i].tag,
|
mHTMLEditor->mTypeInState->SetProp(mCachedStyles[i].tag,
|
||||||
mCachedStyles[i].attr,
|
mCachedStyles[i].attr,
|
||||||
|
@ -405,19 +405,6 @@ protected:
|
|||||||
nsresult ChangeIndentation(Element& aElement, Change aChange);
|
nsresult ChangeIndentation(Element& aElement, Change aChange);
|
||||||
void DocumentModifiedWorker();
|
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:
|
protected:
|
||||||
HTMLEditor* mHTMLEditor;
|
HTMLEditor* mHTMLEditor;
|
||||||
RefPtr<nsRange> mDocChangeRange;
|
RefPtr<nsRange> mDocChangeRange;
|
||||||
@ -431,12 +418,7 @@ protected:
|
|||||||
uint32_t mJoinOffset;
|
uint32_t mJoinOffset;
|
||||||
nsCOMPtr<Element> mNewBlock;
|
nsCOMPtr<Element> mNewBlock;
|
||||||
RefPtr<RangeItem> mRangeItem;
|
RefPtr<RangeItem> mRangeItem;
|
||||||
|
StyleCache mCachedStyles[SIZE_STYLE_TABLE];
|
||||||
// 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -226,7 +226,6 @@ skip-if = toolkit == 'android' # bug 1054087
|
|||||||
[test_dom_input_event_on_texteditor.html]
|
[test_dom_input_event_on_texteditor.html]
|
||||||
[test_dragdrop.html]
|
[test_dragdrop.html]
|
||||||
skip-if = os == 'android'
|
skip-if = os == 'android'
|
||||||
[test_inline_style_cache.html]
|
|
||||||
[test_inlineTableEditing.html]
|
[test_inlineTableEditing.html]
|
||||||
[test_keypress_untrusted_event.html]
|
[test_keypress_untrusted_event.html]
|
||||||
[test_objectResizing.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);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
selection->RemoveAllRanges();
|
selection->RemoveAllRanges();
|
||||||
selection->AddRange(editorRange);
|
selection->AddRange(editorRange);
|
||||||
|
editor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
|
||||||
|
|
||||||
nsCOMPtr<nsIPlaintextEditor> textEditor(do_QueryReferent(mEditor));
|
nsCOMPtr<nsIPlaintextEditor> textEditor(do_QueryReferent(mEditor));
|
||||||
if (textEditor)
|
if (textEditor)
|
||||||
|
@ -4,5 +4,3 @@ skip-if = os == 'android'
|
|||||||
[test_bug1170484.html]
|
[test_bug1170484.html]
|
||||||
support-files = helper_bug1170484.js
|
support-files = helper_bug1170484.js
|
||||||
skip-if = os == 'linux' #Bug 1202570
|
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]
|
[[["stylewithcss","false"\],["inserttext","a"\]\] "<p>foo<span style=color:#aBcDeF>[bar</span><span style=color:#fEdCbA>baz\]</span>quz" compare innerHTML]
|
||||||
expected: FAIL
|
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]
|
[[["stylewithcss","true"\],["inserttext","a"\]\] "[foo<b>bar\]</b>baz" compare innerHTML]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user