Bug 1394758 - Part 1. non-editable text node should be treated as WSType::special, not WSType::text. r=masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Mon, 11 Sep 2017 15:52:05 +0900
changeset 662204 e5fff30a2710c2021d59ce88bf2698ce4ebe2dfc
parent 662089 a5f163da8a9be5d2e86138c57d59be69723b5457
child 662205 2d0ae7c47c6187e56d6c29e8eb48974f7ab7ff72
push id78991
push userbmo:m_kato@ga2.so-net.ne.jp
push dateMon, 11 Sep 2017 07:01:16 +0000
reviewersmasayuki
bugs1394758
milestone57.0a1
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
editor/libeditor/WSRunObject.cpp
editor/libeditor/tests/mochitest.ini
editor/libeditor/tests/test_bug1394758.html
--- 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>