Bug 1231923 - Enable selection events for documents with the System Principal, r=ehsan
authorMichael Layzell <michael@thelayzells.com>
Tue, 27 Sep 2016 16:05:43 -0400
changeset 424970 c9d87bca44d8a62e5ed2682bc53c2328da74e211
parent 424969 b62b2d88fd0320fc05e32952c0ffd411ea738011
child 424971 b9b472734bfa43b19779fb9cb984292956534a94
push id32314
push userbmo:hiikezoe@mozilla-japan.org
push dateFri, 14 Oct 2016 00:31:54 +0000
reviewersehsan
bugs1231923
milestone52.0a1
Bug 1231923 - Enable selection events for documents with the System Principal, r=ehsan MozReview-Commit-ID: J9UoI9Pdu48
layout/generic/nsFrameSelection.h
layout/generic/nsSelection.cpp
--- a/layout/generic/nsFrameSelection.h
+++ b/layout/generic/nsFrameSelection.h
@@ -162,16 +162,17 @@ struct nsPrevNextBidiLevels
   nsIFrame* mFrameAfter;
   nsBidiLevel mLevelBefore;
   nsBidiLevel mLevelAfter;
 };
 
 namespace mozilla {
 namespace dom {
 class Selection;
+class SelectionChangeListener;
 } // namespace dom
 } // namespace mozilla
 class nsIScrollableFrame;
 
 /**
  * Methods which are marked with *unsafe* should be handled with special care.
  * They may cause nsFrameSelection to be deleted, if strong pointer isn't used,
  * or they may cause other objects to be deleted.
@@ -646,16 +647,17 @@ private:
             (nsISelectionListener::DRAG_REASON |
              nsISelectionListener::MOUSEDOWN_REASON |
              nsISelectionListener::MOUSEUP_REASON |
              nsISelectionListener::KEYPRESS_REASON)) !=
            nsISelectionListener::NO_REASON;
   }
 
   friend class mozilla::dom::Selection;
+  friend class mozilla::dom::SelectionChangeListener;
   friend struct mozilla::AutoPrepareFocusRange;
 #ifdef DEBUG
   void printSelection();       // for debugging
 #endif /* DEBUG */
 
   void ResizeBuffer(uint32_t aNewBufSize);
 
 /*HELPER METHODS*/
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -28,16 +28,17 @@
 #include "nsTableWrapperFrame.h"
 #include "nsTableCellFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsIContentIterator.h"
 #include "nsIDocumentEncoder.h"
 #include "nsTextFragment.h"
 #include <algorithm>
+#include "nsContentUtils.h"
 
 #include "nsGkAtoms.h"
 #include "nsIFrameTraversal.h"
 #include "nsLayoutUtils.h"
 #include "nsLayoutCID.h"
 #include "nsBidiPresUtils.h"
 static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
 #include "nsTextFrame.h"
@@ -929,17 +930,19 @@ nsFrameSelection::Init(nsIPresShell *aSh
   RefPtr<AccessibleCaretEventHub> eventHub = mShell->GetAccessibleCaretEventHub();
   if (eventHub) {
     int8_t index = GetIndexFromSelectionType(SelectionType::eNormal);
     if (mDomSelections[index]) {
       mDomSelections[index]->AddSelectionListener(eventHub);
     }
   }
 
-  if (sSelectionEventsEnabled) {
+  nsIDocument* doc = aShell->GetDocument();
+  if (sSelectionEventsEnabled ||
+      (doc && nsContentUtils::IsSystemPrincipal(doc->NodePrincipal()))) {
     int8_t index = GetIndexFromSelectionType(SelectionType::eNormal);
     if (mDomSelections[index]) {
       // The Selection instance will hold a strong reference to its selectionchangelistener
       // so we don't have to worry about that!
       RefPtr<SelectionChangeListener> listener = new SelectionChangeListener;
       mDomSelections[index]->AddSelectionListener(listener);
     }
   }
@@ -3827,19 +3830,24 @@ Selection::AddItem(nsRange* aItem, int32
     return NS_ERROR_UNEXPECTED;
 
   NS_ASSERTION(aOutIndex, "aOutIndex can't be null");
 
   if (mUserInitiated) {
     AutoTArray<RefPtr<nsRange>, 4> rangesToAdd;
     *aOutIndex = -1;
 
+    nsIDocument* doc = GetParentObject();
+    bool selectEventsEnabled =
+      nsFrameSelection::sSelectionEventsEnabled ||
+      (doc && nsContentUtils::IsSystemPrincipal(doc->NodePrincipal()));
+
     if (!aNoStartSelect &&
         mSelectionType == SelectionType::eNormal &&
-        nsFrameSelection::sSelectionEventsEnabled && Collapsed() &&
+        selectEventsEnabled && Collapsed() &&
         !IsBlockingSelectionChangeEvents()) {
       // First, we generate the ranges to add with a scratch range, which is a
       // clone of the original range passed in. We do this seperately, because the
       // selectstart event could have caused the world to change, and required
       // ranges to be re-generated
       RefPtr<nsRange> scratchRange = aItem->CloneRange();
       UserSelectRangesToAdd(scratchRange, rangesToAdd);
       bool newRangesNonEmpty = rangesToAdd.Length() > 1 ||
@@ -6671,16 +6679,22 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(Selectio
 NS_IMPL_CYCLE_COLLECTING_RELEASE(SelectionChangeListener)
 
 NS_IMETHODIMP
 SelectionChangeListener::NotifySelectionChanged(nsIDOMDocument* aDoc,
                                                 nsISelection* aSel, int16_t aReason)
 {
   RefPtr<Selection> sel = aSel->AsSelection();
 
+  nsIDocument* doc = sel->GetParentObject();
+  if (!(doc && nsContentUtils::IsSystemPrincipal(doc->NodePrincipal())) &&
+      !nsFrameSelection::sSelectionEventsEnabled) {
+    return NS_OK;
+  }
+
   // Check if the ranges have actually changed
   // Don't bother checking this if we are hiding changes.
   if (mOldRanges.Length() == sel->RangeCount() && !sel->IsBlockingSelectionChangeEvents()) {
     bool changed = false;
 
     for (size_t i = 0; i < mOldRanges.Length(); i++) {
       if (!mOldRanges[i].Equals(sel->GetRangeAt(i))) {
         changed = true;