Bug 1394758 - Part 1. non-editable text node should be treated as WSType::special, not WSType::text. r=masayuki
This bug occurs that WSRunObject::PrepareToDeleteRangePriv() calls WSRunObject::ConvertToNBSP for non-editable text node.
Actually, even if text node isn't editable, WSFragment::mType becomes WSType::text now. So, whitespace only node at the end of contenteditable=false is treated as WSType::normalWS, i.e., treated as editable.
So text node in contenteditable=false should treated as WSType::special which means a non-editable inline object. Then, WSRunObject won't create object chunk of WSType::normalWS for text node in contenteditable=false.
MozReview-Commit-ID: GOjxax8KvDD
--- a/editor/libeditor/WSRunObject.cpp
+++ b/editor/libeditor/WSRunObject.cpp
@@ -638,17 +638,19 @@ WSRunObject::GetWSNodes()
// we haven't found the start of ws yet. Keep looking
nsCOMPtr<nsIContent> priorNode = GetPreviousWSNode(start, wsBoundingParent);
if (priorNode) {
if (IsBlockNode(priorNode)) {
mStartNode = start.node;
mStartOffset = start.offset;
mStartReason = WSType::otherBlock;
mStartReasonNode = priorNode;
- } else if (RefPtr<Text> textNode = priorNode->GetAsText()) {
+ } else if (priorNode->IsNodeOfType(nsINode::eTEXT) &&
+ priorNode->IsEditable()) {
+ RefPtr<Text> textNode = priorNode->GetAsText();
mNodeArray.InsertElementAt(0, textNode);
const nsTextFragment *textFrag;
if (!textNode || !(textFrag = textNode->GetText())) {
return NS_ERROR_NULL_POINTER;
}
uint32_t len = textNode->TextLength();
if (len < 1) {
@@ -745,17 +747,19 @@ WSRunObject::GetWSNodes()
nsCOMPtr<nsIContent> nextNode = GetNextWSNode(end, wsBoundingParent);
if (nextNode) {
if (IsBlockNode(nextNode)) {
// we encountered a new block. therefore no more ws.
mEndNode = end.node;
mEndOffset = end.offset;
mEndReason = WSType::otherBlock;
mEndReasonNode = nextNode;
- } else if (RefPtr<Text> textNode = nextNode->GetAsText()) {
+ } else if (nextNode->IsNodeOfType(nsINode::eTEXT) &&
+ nextNode->IsEditable()) {
+ RefPtr<Text> textNode = nextNode->GetAsText();
mNodeArray.AppendElement(textNode);
const nsTextFragment *textFrag;
if (!textNode || !(textFrag = textNode->GetText())) {
return NS_ERROR_NULL_POINTER;
}
uint32_t len = textNode->TextLength();
if (len < 1) {
--- a/editor/libeditor/tests/mochitest.ini
+++ b/editor/libeditor/tests/mochitest.ini
@@ -247,16 +247,17 @@ skip-if = toolkit == 'android' # bug 131
[test_bug1330796.html]
[test_bug1332876.html]
[test_bug1352799.html]
[test_bug1355792.html]
[test_bug1358025.html]
[test_bug1361008.html]
[test_bug1368544.html]
[test_bug1385905.html]
+[test_bug1394758.html]
[test_CF_HTML_clipboard.html]
subsuite = clipboard
[test_composition_event_created_in_chrome.html]
[test_contenteditable_focus.html]
[test_documentCharacterSet.html]
[test_dom_input_event_on_htmleditor.html]
skip-if = toolkit == 'android' # bug 1054087
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/tests/test_bug1394758.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1394758
+-->
+<head>
+ <title>Test for Bug1394758</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>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1394758">Mozilla Bug 1394758</a>
+<p id="display"></p>
+<div id="content">
+<div id="editable" contenteditable="true">
+ <span id="span" contenteditable="false">
+ Hello
+ </span>
+ World
+</div>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 611182 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+ var editable = document.getElementById('editable');
+ var span = document.getElementById('span');
+ var beforeSpan = span.textContent;
+
+ editable.focus();
+ window.getSelection().collapse(span.nextSibling, 0);
+
+ synthesizeKey("KEY_ArrowRight", {});
+ synthesizeKey("KEY_ArrowRight", {});
+ synthesizeKey("KEY_ArrowRight", {});
+ synthesizeKey("KEY_Backspace", {});
+ synthesizeKey("KEY_Backspace", {});
+
+ is(span.textContent, beforeSpan,
+ "VK_BACK_SPACE should not modify non-editable area");
+ is(span.nextSibling.textContent.trim(), "rld",
+ "VK_BACK_SPACE should delete first 2 characters");
+
+ synthesizeKey("KEY_Delete", {});
+
+ is(span.textContent, beforeSpan,
+ "VK_DELETE should not modify non-editable area");
+ is(span.nextSibling.textContent.trim(), "ld",
+ "VK_DELETE should delete first character");
+
+ SimpleTest.finish();
+});
+
+</script>
+</pre>
+</body>
+</html>