Bug 1473108 - Part 2: Make PresShell not point to unbound NAC in event content stack; r=smaug
authorEdgar Chen <echen@mozilla.com>
Tue, 09 Oct 2018 12:16:15 +0000
changeset 495980 ecce651fad51ab1a5718b6e6f208093ec075612d
parent 495979 b38223cb4fd1a8084343a76cd5c4cf02c6c35086
child 495981 7b218b6df4207d8b4338ab682bc2c09f3d8eaadb
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1473108
milestone64.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 1473108 - Part 2: Make PresShell not point to unbound NAC in event content stack; r=smaug Differential Revision: https://phabricator.services.mozilla.com/D8042
gfx/layers/apz/test/mochitest/helper_bug1473108.html
gfx/layers/apz/test/mochitest/test_group_touchevents-3.html
layout/base/PresShell.cpp
layout/base/nsIPresShell.h
layout/generic/nsFrame.cpp
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_bug1473108.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1473108
+-->
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width; initial-scale=1.0">
+  <title>Test for Bug 1473108</title>
+  <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
+  <script type="application/javascript" src="apz_test_utils.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+  <style>
+  .a {
+    background: green;
+    height: 64px;
+    width: 32px;
+    display: block;
+  }
+  span::before {
+    content: "";
+    background: red;
+    height: 32px;
+    width: 32px;
+    display: block;
+  }
+  span:active::after {
+    content: "";
+  }
+</style>
+</head>
+
+<body>
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1473108">Mozilla Bug 1473108</a>
+  <a class="a" id="event"><span id="target"></span></a>
+
+  <script type="application/javascript">
+
+  waitUntilApzStable().then(() => {
+    let target = document.getElementById("target");
+    target.addEventListener('click', function(e) {
+      is(e.target, target, `Clicked on at (${e.clientX}, ${e.clientY})`);
+      subtestDone();
+    });
+    synthesizeNativeTap(target, 5, 5);
+  });
+
+</script>
+</body>
+</html>
--- a/gfx/layers/apz/test/mochitest/test_group_touchevents-3.html
+++ b/gfx/layers/apz/test/mochitest/test_group_touchevents-3.html
@@ -18,16 +18,18 @@ var touch_action_prefs = [
 var subtests = [
   // Simple test to exercise touch-action CSS property
   {'file': 'helper_touch_action.html', 'prefs': touch_action_prefs},
   // More complex touch-action tests, with overlapping regions and such
   {'file': 'helper_touch_action_complex.html', 'prefs': touch_action_prefs},
   // Tests that touch-action CSS properties are handled in APZ without waiting
   // on the main-thread, when possible
   {'file': 'helper_touch_action_regions.html', 'prefs': touch_action_prefs},
+  // touch-action tests with :active::after CSS property
+  {'file': 'helper_bug1473108.html'},
   // Add new subtests here. If this starts timing out because it's taking too
   // long, create a test_group_touchevents-4.html file. Refer to 1423011#c57
   // for more details.
 ];
 
 if (isApzEnabled()) {
   ok(window.TouchEvent, "Check if TouchEvent is supported (it should be, the test harness forces it on everywhere)");
   if (getPlatform() == "android") {
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -2090,16 +2090,32 @@ PresShell::FireResizeEvent()
   nsEventStatus status = nsEventStatus_eIgnore;
 
   if (nsPIDOMWindowOuter* window = mDocument->GetWindow()) {
     EventDispatcher::Dispatch(window, mPresContext, &event, nullptr, &status);
   }
 }
 
 void
+nsIPresShell::NativeAnonymousContentRemoved(nsIContent* aAnonContent)
+{
+  if (aAnonContent == mCurrentEventContent) {
+    mCurrentEventContent = aAnonContent->GetFlattenedTreeParent();
+    mCurrentEventFrame = nullptr;
+  }
+
+  for (unsigned int i = 0; i < mCurrentEventContentStack.Length(); i++) {
+    if (aAnonContent == mCurrentEventContentStack.ElementAt(i)) {
+      mCurrentEventContentStack.ReplaceObjectAt(aAnonContent->GetFlattenedTreeParent(), i);
+      mCurrentEventFrameStack[i] = nullptr;
+    }
+  }
+}
+
+void
 PresShell::SetIgnoreFrameDestruction(bool aIgnore)
 {
   if (mDocument) {
     // We need to tell the ImageLoader to drop all its references to frames
     // because they're about to go away and it won't get notifications of that.
     mDocument->StyleImageLoader()->ClearFrames(mPresContext);
   }
   mIgnoreFrameDestruction = aIgnore;
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1621,16 +1621,18 @@ public:
 
   /**
    * Returns whether or not the document has ever handled user input
    */
   virtual bool HasHandledUserInput() const = 0;
 
   virtual void FireResizeEvent() = 0;
 
+  void NativeAnonymousContentRemoved(nsIContent* aAnonContent);
+
 protected:
   /**
    * Refresh observer management.
    */
   void DoObserveStyleFlushes();
   void DoObserveLayoutFlushes();
 
   /**
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -246,16 +246,17 @@ nsReflowStatus::UpdateTruncated(const Re
 }
 
 /* static */ void
 nsIFrame::DestroyAnonymousContent(nsPresContext* aPresContext,
                                   already_AddRefed<nsIContent>&& aContent)
 {
   if (nsCOMPtr<nsIContent> content = aContent) {
     aPresContext->EventStateManager()->NativeAnonymousContentRemoved(content);
+    aPresContext->PresShell()->NativeAnonymousContentRemoved(content);
     content->UnbindFromTree();
   }
 }
 
 // Formerly the nsIFrameDebug interface
 
 std::ostream& operator<<(std::ostream& aStream,
                          const nsReflowStatus& aStatus)