Bug 1314442 - Limit editor's editability to the right subtree. r=masayuki, a=ritu
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Tue, 29 Nov 2016 17:07:27 -0500
changeset 352782 6ae1e6a5259fd2159192811e65ec9157a0247474
parent 352781 f97d858f6835a36c22aeb846e394bd5044f5494a
child 352783 7d172a5a5da1b8a0b9a3b4f8ecd9bb98c7fd1cfa
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki, ritu
bugs1314442
milestone52.0a2
Bug 1314442 - Limit editor's editability to the right subtree. r=masayuki, a=ritu
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditor.h
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -3230,24 +3230,45 @@ HTMLEditor::ContentInserted(nsIDocument*
                             nsIContent* aContainer,
                             nsIContent* aChild,
                             int32_t aIndexInContainer)
 {
   DoContentInserted(aDocument, aContainer, aChild, aIndexInContainer,
                     eInserted);
 }
 
+bool
+HTMLEditor::IsInObservedSubtree(nsIDocument* aDocument,
+                                nsIContent* aContainer,
+                                nsIContent* aChild)
+{
+  if (!aChild) {
+    return false;
+  }
+
+  Element* root = GetRoot();
+  // To be super safe here, check both ChromeOnlyAccess and GetBindingParent.
+  // That catches (also unbound) native anonymous content, XBL and ShadowDOM.
+  if (root &&
+      (root->ChromeOnlyAccess() != aChild->ChromeOnlyAccess() ||
+       root->GetBindingParent() != aChild->GetBindingParent())) {
+    return false;
+  }
+
+  return !aChild->ChromeOnlyAccess() && !aChild->GetBindingParent();
+}
+
 void
 HTMLEditor::DoContentInserted(nsIDocument* aDocument,
                               nsIContent* aContainer,
                               nsIContent* aChild,
                               int32_t aIndexInContainer,
                               InsertedOrAppended aInsertedOrAppended)
 {
-  if (!aChild) {
+  if (!IsInObservedSubtree(aDocument, aContainer, aChild)) {
     return;
   }
 
   nsCOMPtr<nsIHTMLEditor> kungFuDeathGrip(this);
 
   if (ShouldReplaceRootElement()) {
     nsContentUtils::AddScriptRunner(NewRunnableMethod(
       this, &HTMLEditor::ResetRootElementAndEventTarget));
@@ -3285,16 +3306,20 @@ HTMLEditor::DoContentInserted(nsIDocumen
 
 void
 HTMLEditor::ContentRemoved(nsIDocument* aDocument,
                            nsIContent* aContainer,
                            nsIContent* aChild,
                            int32_t aIndexInContainer,
                            nsIContent* aPreviousSibling)
 {
+  if (!IsInObservedSubtree(aDocument, aContainer, aChild)) {
+    return;
+  }
+
   nsCOMPtr<nsIHTMLEditor> kungFuDeathGrip(this);
 
   if (SameCOMIdentity(aChild, mRootElement)) {
     nsContentUtils::AddScriptRunner(NewRunnableMethod(
       this, &HTMLEditor::ResetRootElementAndEventTarget));
   }
   // We don't need to handle our own modifications
   else if (!mAction && (aContainer ? aContainer->IsEditable() : aDocument->IsEditable())) {
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -935,16 +935,20 @@ protected:
   nsresult GetPositionAndDimensions(nsIDOMElement* aElement,
                                     int32_t& aX, int32_t& aY,
                                     int32_t& aW, int32_t& aH,
                                     int32_t& aBorderLeft,
                                     int32_t& aBorderTop,
                                     int32_t& aMarginLeft,
                                     int32_t& aMarginTop);
 
+  bool IsInObservedSubtree(nsIDocument* aDocument,
+                           nsIContent* aContainer,
+                           nsIContent* aChild);
+
   // resizing
   bool mIsObjectResizingEnabled;
   bool mIsResizing;
   bool mPreserveRatio;
   bool mResizedObjectIsAnImage;
 
   // absolute positioning
   bool mIsAbsolutelyPositioningEnabled;