Bug 1511563 - Don't make NAC editable by default. r=masayuki
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 14 Jan 2019 17:03:55 +0100
changeset 513909 1285bd13257d9ff5fe1e71bfd4b1632dc0965ff9
parent 513908 efcdc02cdf58d06110612cdd6a765fd828180bf2
child 513910 b52da9b4235b6574b986418985144a9237bba180
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1511563
milestone66.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 1511563 - Don't make NAC editable by default. r=masayuki I think this is a more consistent fix for the issue. Differential Revision: https://phabricator.services.mozilla.com/D16521
dom/base/Element.cpp
dom/base/nsIContentInlines.h
layout/base/crashtests/1511563.html
layout/base/crashtests/crashtests.list
widget/tests/test_imestate.html
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -277,51 +277,30 @@ void Element::UpdateState(bool aNotify) 
     }
   }
 }
 
 }  // namespace dom
 }  // namespace mozilla
 
 void nsIContent::UpdateEditableState(bool aNotify) {
-  // Guaranteed to be non-element content
-  NS_ASSERTION(!IsElement(), "What happened here?");
   nsIContent* parent = GetParent();
 
-  // Skip over unknown native anonymous content to avoid setting a flag we
-  // can't clear later
-  bool isUnknownNativeAnon = false;
-  if (IsInNativeAnonymousSubtree()) {
-    isUnknownNativeAnon = true;
-    nsCOMPtr<nsIContent> root = this;
-    while (root && !root->IsRootOfNativeAnonymousSubtree()) {
-      root = root->GetParent();
-    }
-    // root should always be true here, but isn't -- bug 999416
-    if (root) {
-      nsIFrame* rootFrame = root->GetPrimaryFrame();
-      if (rootFrame) {
-        nsContainerFrame* parentFrame = rootFrame->GetParent();
-        nsITextControlFrame* textCtrl = do_QueryFrame(parentFrame);
-        isUnknownNativeAnon = !textCtrl;
-      }
-    }
-  }
-
+  // Don't implicitly set the flag on the root of a native anonymous subtree.
+  // This needs to be set explicitly, see for example
+  // nsTextControlFrame::CreateRootNode().
   SetEditableFlag(parent && parent->HasFlag(NODE_IS_EDITABLE) &&
-                  !isUnknownNativeAnon);
+                  !IsRootOfNativeAnonymousSubtree());
 }
 
 namespace mozilla {
 namespace dom {
 
 void Element::UpdateEditableState(bool aNotify) {
-  nsIContent* parent = GetParent();
-
-  SetEditableFlag(parent && parent->HasFlag(NODE_IS_EDITABLE));
+  nsIContent::UpdateEditableState(aNotify);
   if (aNotify) {
     UpdateState(aNotify);
   } else {
     // Avoid calling UpdateState in this very common case, because
     // this gets called for pretty much every single element on
     // insertion into the document and UpdateState can be slow for
     // some kinds of elements even when not notifying.
     if (IsEditable()) {
--- a/dom/base/nsIContentInlines.h
+++ b/dom/base/nsIContentInlines.h
@@ -148,19 +148,24 @@ inline bool nsINode::NodeOrAncestorHasDi
 }
 
 inline bool nsINode::IsEditable() const {
   if (HasFlag(NODE_IS_EDITABLE)) {
     // The node is in an editable contentEditable subtree.
     return true;
   }
 
-  Document* doc = GetUncomposedDoc();
+  // All editable anonymous content should be made explicitly editable via the
+  // NODE_IS_EDITABLE flag.
+  if (IsInNativeAnonymousSubtree()) {
+    return false;
+  }
 
   // Check if the node is in a document and the document is in designMode.
+  Document* doc = GetUncomposedDoc();
   return doc && doc->HasFlag(NODE_IS_EDITABLE);
 }
 
 inline bool nsIContent::IsActiveChildrenElement() const {
   if (!mNodeInfo->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
     return false;
   }
 
new file mode 100644
--- /dev/null
+++ b/layout/base/crashtests/1511563.html
@@ -0,0 +1,8 @@
+<script>
+document.addEventListener("DOMContentLoaded", function(){
+  document.designMode='on'
+  window.getSelection().modify('move', 'right', 'line')
+})
+</script>
+<br>
+<keygen>
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -551,8 +551,9 @@ load 1494030.html
 load 1505420.html
 pref(layout.css.column-span.enabled,true) load 1506163.html
 pref(layout.css.column-span.enabled,true) load 1506204.html
 pref(layout.css.column-span.enabled,true) load 1506314.html
 pref(layout.css.column-span.enabled,true) load 1507244.html
 load 1510080.html
 load 1510485.html
 pref(layout.css.column-span.enabled,true) load 1511535.html
+load 1511563.html
--- a/widget/tests/test_imestate.html
+++ b/widget/tests/test_imestate.html
@@ -401,17 +401,17 @@ function runBasicTest(aIsEditable, aInDe
     { id: "reset",
       description: "input[type=reset]",
       focusable: !aInDesignMode,
       expectedEnabled: kEnabledStateOnNonEditableElement },
     { id: "file",
       description: "input[type=file]",
       focusable: !aInDesignMode,
       focusEventNotFired: aIsEditable && !aInDesignMode,
-      expectedEnabled: kEnabledStateOnNonEditableElement },
+      expectedEnabled: kEnabledStateOnReadonlyField },
     { id: "button",
       description: "input[type=button]",
       focusable: !aInDesignMode,
       expectedEnabled: kEnabledStateOnNonEditableElement },
     { id: "image",
       description: "input[type=image]",
       focusable: !aInDesignMode,
       expectedEnabled: kEnabledStateOnNonEditableElement },