Bug 1394758 - Part 1. non-editable text node should be treated as WSType::special, not WSType::text. r=masayuki
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Mon, 11 Sep 2017 15:52:05 +0900
changeset 429512 adcfea5cd531baec52c58f8659c35fe02ac2a56c
parent 429511 109e5bafd7a34423f6ed3ae03fcd277004fa41a5
child 429513 c65dfa68df8da69f30e8f58715383de179a51397
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1394758
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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>