Remove Event.relatedTargetScoped and update event path calculation for relatedTarget

See the context: https://github.com/w3c/webcomponents/issues/486

The spec change:
- https://github.com/w3c/webcomponents/commit/f113e26bfa999bac730c65ea7418fe787500313c
- https://github.com/w3c/webcomponents/commit/b1433e5f3a013ca825f02fb8f7b0e9d6217c0125

BUG=531990

Review-Url: https://codereview.chromium.org/2030513002
Cr-Commit-Position: refs/heads/master@{#397329}
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 8172c671..3b3a68ec 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -513,7 +513,6 @@
 crbug.com/505364 imported/wpt/shadow-dom/untriaged/user-interaction/focus-navigation/test-004.html [ Failure ]
 crbug.com/505364 imported/wpt/custom-elements/v0/instantiating/extensions-to-document-interface/create-element-interface-type-is-a-type-extension.html [ Failure ]
 crbug.com/505364 imported/csswg-test/css-scoping-1/css-scoping-shadow-slot-display-override.html [ Failure ]
-crbug.com/505364 imported/wpt/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-001.html [ Failure ]
 
 crbug.com/517840 imported/wpt/webrtc/rtcpeerconnection/rtcpeerconnection-idl.html [ Failure Timeout ]
 
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-manually-fired-with-same-related-target-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-manually-fired-with-same-related-target-expected.txt
index ba44ebf..de5b89ad 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-manually-fired-with-same-related-target-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/shadow-dom-event-dispatching-manually-fired-with-same-related-target-expected.txt
@@ -10,8 +10,6 @@
   mouseout
 
   mouseover
-     @div1 (target: div1) (related: div1)
-     @shadow-root (target: div1) (related: div1)
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-get-expected.txt b/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-get-expected.txt
index 0a803d3..bc5c923 100644
--- a/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-get-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/xmlhttprequest/xmlhttprequest-get-expected.txt
@@ -57,7 +57,6 @@
 loaded : '0'
 path : ''
 preventDefault : 'function preventDefault() { [native code] }'
-relatedTargetScoped : 'false'
 returnValue : 'true'
 srcElement : '[object XMLHttpRequest]'
 stopImmediatePropagation : 'function stopImmediatePropagation() { [native code] }'
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index f4cf85c..772051ad 100644
--- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -144,7 +144,6 @@
     getter defaultPrevented
     getter eventPhase
     getter path
-    getter relatedTargetScoped
     getter returnValue
     getter srcElement
     getter target
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-dir-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-dir-expected.txt
index 9485f02..fa12bbe 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-dir-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-dir-expected.txt
@@ -68,13 +68,12 @@
     bubbles: false
     cancelBubble: false
     cancelable: false
-    composed: false
+    composed: true
     currentTarget: null
     defaultPrevented: false
     eventPhase: 0
     isTrusted: false
     path: Array[0]
-    relatedTargetScoped: false
     returnValue: true
     srcElement: null
     target: null
diff --git a/third_party/WebKit/LayoutTests/shadow-dom/event-composed.html b/third_party/WebKit/LayoutTests/shadow-dom/event-composed.html
index 891b684..48a98d50 100644
--- a/third_party/WebKit/LayoutTests/shadow-dom/event-composed.html
+++ b/third_party/WebKit/LayoutTests/shadow-dom/event-composed.html
@@ -8,15 +8,6 @@
   </template>
 </div>
 <script>
-function assert_event_path_equals(actual, expected) {
-  assert_equals(actual.length, expected.length);
-  for (let i = 0; i < actual.length; ++i) {
-    assert_equals(actual[i][0], expected[i][0], 'currentTarget at ' + i + ' should be same');
-    assert_equals(actual[i][1], expected[i][1], 'relatedTarget at ' + i + ' should be same');
-    assert_array_equals(actual[i][2], expected[i][2], 'composedPath at ' + i + ' should be same');
-  }
-}
-
 test(() => {
   const e = new Event('test');
   assert_equals(e.composed, false);
diff --git a/third_party/WebKit/LayoutTests/shadow-dom/event-path-related-target-scoped.html b/third_party/WebKit/LayoutTests/shadow-dom/event-path-related-target-scoped.html
index 576bfee..97cc92f 100644
--- a/third_party/WebKit/LayoutTests/shadow-dom/event-path-related-target-scoped.html
+++ b/third_party/WebKit/LayoutTests/shadow-dom/event-path-related-target-scoped.html
@@ -2,55 +2,20 @@
 <script src="../resources/testharness.js"></script>
 <script src="../resources/testharnessreport.js"></script>
 <script src="resources/shadow-dom.js"></script>
-
-<div id="log"></div>
-<div id="sandbox">
-  <div id="top">
-    <div id="host">
-      <template>
-        <input id="input1"></input>
-        <input id="input2"></input>
-      </template>
-    </div>
-  </div>
+<div id=host label=host>
+  <template label=shadowRoot data-mode=open>
+    <input label="input1"></input>
+    <input label="input2"></input>
+  </template>
 </div>
 <script>
-
-var sandbox = document.getElementById('sandbox');
-convertTemplatesToShadowRootsWithin(sandbox);
-
-var host = document.getElementById('host');
-var topDiv = document.getElementById('top');
-var sr = host.shadowRoot;
-
-var input1 = getNodeInComposedTree('host/input1');
-var input2 = getNodeInComposedTree('host/input2');
-
-async_test(function(t) {
-  input2.onfocus = function(e) {
-    t.step(function() {
-      assert_false(e.relatedTargetScoped);
-      var expected1 = [input2, sr, host, topDiv, sandbox, document.body, document.documentElement, document, window];
-      assert_array_equals(e.path, expected1);
-      t.done();
-    });
-  };
-}, 'Event paths of untrusted events with relatedTargetScoped false do not stop.');
-
-async_test(function(t) {
-  input1.onfocus = function(e) {
-    t.step(function() {
-      assert_true(e.relatedTargetScoped);
-      var expected2 = [input1, sr];
-      assert_array_equals(e.path, expected2);
-      t.done();
-    });
-  };
-}, 'Event paths of untrusted events with relatedTargetScoped true stop at the common ancestor of the target & the related target.');
-
-var userFocus1 = new FocusEvent('focus', { relatedTarget: input1 });
-input2.dispatchEvent(userFocus1);
-
-var userFocus2 = new FocusEvent('focus', { relatedTarget: input2, relatedTargetScoped: true });
-input1.dispatchEvent(userFocus2);
+test(() => {
+  let nodes = createTestTree(host);
+  let log = dispatchEventWithLog(nodes, nodes['input1'],
+                                 new FocusEvent('test', { bubbles: true, relatedTarget: nodes['input2']}));
+  let expectedPath = ['input1', 'shadowRoot'];
+  assert_event_path_equals(log,
+                           [['input1', 'input2', expectedPath],
+                            ['shadowRoot', 'input2', expectedPath]]);
+}, 'An event should stop at the common ancestor of target and relatedTarget.');
 </script>
diff --git a/third_party/WebKit/LayoutTests/shadow-dom/events-related-target-scoped.html b/third_party/WebKit/LayoutTests/shadow-dom/events-related-target-scoped.html
deleted file mode 100644
index 5c8ed253..0000000
--- a/third_party/WebKit/LayoutTests/shadow-dom/events-related-target-scoped.html
+++ /dev/null
@@ -1,114 +0,0 @@
-<!DOCTYPE html>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script src="resources/shadow-dom.js"></script>
-
-<div id="log"></div>
-<div id="sandbox">
-  <div id = "host">
-      <template>
-          <input id="target1"></input>
-          <input id="target2"></input>
-          <input id="target3"></input>
-          <input id="target4"></input>
-          <input id="target5"></input>
-      </template>
-  </div>
-</div>
-
-<script>
-
-function moveMouseOver(element)
-{
-  if (!window.eventSender || !window.internals)
-      return;
-
-  var x = element.offsetLeft + element.offsetWidth / 2;
-  var y;
-  if (element.hasChildNodes() || window.internals.shadowRoot(element))
-      y = element.offsetTop;
-  else
-      y = element.offsetTop + element.offsetHeight / 2;
-  eventSender.mouseMoveTo(x, y);
-}
-
-var sandbox = document.getElementById('sandbox');
-convertTemplatesToShadowRootsWithin(sandbox);
-var target1 = getNodeInComposedTree('host/target1');
-var target2 = getNodeInComposedTree('host/target2');
-var target3 = getNodeInComposedTree('host/target3');
-var target4 = getNodeInComposedTree('host/target4');
-var target5 = getNodeInComposedTree('host/target5');
-
-async_test(function(t) {
-  target1.onfocus = function(e) {
-    t.step(function() {
-      assert_equals(e.relatedTarget, null);
-      assert_false(e.relatedTargetScoped);
-      t.done();
-    });
-  };
-}, 'Trusted events should have relatedTargetScoped set to false by default.');
-
-async_test(function(t) {
-  target3.onfocus = function(e) {
-    t.step(function() {
-      assert_equals(e.relatedTarget, target2);
-      assert_true(e.relatedTargetScoped);
-      t.done();
-    });
-  };
-}, 'Trusted focus events with a related target should have relatedTargetScoped true.');
-
-async_test(function(t) {
-  target1.onmouseenter = function(e) {
-    t.step(function() {
-      assert_equals(e.relatedTarget, null);
-      assert_false(e.relatedTargetScoped);
-      t.done();
-    });
-  };
-}, 'Trusted mouse events without a related target should have relatedTargetScoped set to false.');
-
-async_test(function(t) {
-  target3.onmouseenter = function(e) {
-    t.step(function() {
-      assert_equals(e.relatedTarget, target2);
-      assert_true(e.relatedTargetScoped);
-      t.done();
-    });
-  };
-}, 'Trusted mouse events with a related target should have relatedTargetScoped true.');
-
-async_test(function(t) {
-  target4.onfocus = function(e) {
-    t.step(function() {
-      assert_equals(e.relatedTarget, target5);
-      assert_false(e.relatedTargetScoped);
-      t.done();
-    });
-  };
-}, 'Untrusted events should have relatedTargetScoped set to false by default.');
-
-async_test(function(t) {
-  target5.onfocus = function(e) {
-    t.step(function() {
-      assert_equals(e.relatedTarget, target4);
-      assert_true(e.relatedTargetScoped);
-      t.done();
-    });
-  };
-}, 'Trusted focus events with a related target should have relatedTargetScoped true.');
-
-target1.focus();
-target2.focus();
-target3.focus();
-moveMouseOver(target1);
-moveMouseOver(target2);
-moveMouseOver(target3);
-var userFocus1 = new FocusEvent('focus', { relatedTarget: target5 });
-target4.dispatchEvent(userFocus1);
-var userFocus2 = new FocusEvent('focus', { relatedTarget: target4, relatedTargetScoped: true });
-target5.dispatchEvent(userFocus2);
-
-</script>
diff --git a/third_party/WebKit/LayoutTests/shadow-dom/resources/shadow-dom.js b/third_party/WebKit/LayoutTests/shadow-dom/resources/shadow-dom.js
index bbed4da..7b4841f 100644
--- a/third_party/WebKit/LayoutTests/shadow-dom/resources/shadow-dom.js
+++ b/third_party/WebKit/LayoutTests/shadow-dom/resources/shadow-dom.js
@@ -130,3 +130,13 @@
   target.dispatchEvent(event);
   return log;
 }
+
+// This function assumes that testharness.js is available.
+function assert_event_path_equals(actual, expected) {
+  assert_equals(actual.length, expected.length);
+  for (let i = 0; i < actual.length; ++i) {
+    assert_equals(actual[i][0], expected[i][0], 'currentTarget at ' + i + ' should be same');
+    assert_equals(actual[i][1], expected[i][1], 'relatedTarget at ' + i + ' should be same');
+    assert_array_equals(actual[i][2], expected[i][2], 'composedPath at ' + i + ' should be same');
+  }
+}
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 28ef2e4..fb22e2d 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -164,7 +164,6 @@
 [Worker]     getter defaultPrevented
 [Worker]     getter eventPhase
 [Worker]     getter path
-[Worker]     getter relatedTargetScoped
 [Worker]     getter returnValue
 [Worker]     getter srcElement
 [Worker]     getter target
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index d3ce1d6a..e9ee01a6 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -1587,7 +1587,6 @@
     getter defaultPrevented
     getter eventPhase
     getter path
-    getter relatedTargetScoped
     getter returnValue
     getter srcElement
     getter target
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
index cf1ad68..4c88e52 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -151,7 +151,6 @@
 [Worker]     getter defaultPrevented
 [Worker]     getter eventPhase
 [Worker]     getter path
-[Worker]     getter relatedTargetScoped
 [Worker]     getter returnValue
 [Worker]     getter srcElement
 [Worker]     getter target
diff --git a/third_party/WebKit/Source/core/events/DragEvent.cpp b/third_party/WebKit/Source/core/events/DragEvent.cpp
index 0d05b9e..92e3a0f3 100644
--- a/third_party/WebKit/Source/core/events/DragEvent.cpp
+++ b/third_party/WebKit/Source/core/events/DragEvent.cpp
@@ -99,8 +99,7 @@
 
 DispatchEventResult DragEventDispatchMediator::dispatchEvent(EventDispatcher& dispatcher) const
 {
-    if (event().relatedTargetScoped())
-        event().eventPath().adjustForRelatedTarget(dispatcher.node(), event().relatedTarget());
+    event().eventPath().adjustForRelatedTarget(dispatcher.node(), event().relatedTarget());
     return EventDispatchMediator::dispatchEvent(dispatcher);
 }
 
diff --git a/third_party/WebKit/Source/core/events/Event.cpp b/third_party/WebKit/Source/core/events/Event.cpp
index b806100..5d506668 100644
--- a/third_party/WebKit/Source/core/events/Event.cpp
+++ b/third_party/WebKit/Source/core/events/Event.cpp
@@ -52,42 +52,26 @@
 }
 
 Event::Event()
-    : Event("", false, false, false)
+    : Event("", false, false)
 {
     m_wasInitialized = false;
 }
 
 Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
-    : Event(eventType, canBubbleArg, cancelableArg, !isScoped(eventType), false, monotonicallyIncreasingTime())
-{
-}
-
-Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, EventTarget* relatedTarget)
-    : Event(eventType, canBubbleArg, cancelableArg, !isScoped(eventType), relatedTarget ? true : false, monotonicallyIncreasingTime())
+    : Event(eventType, canBubbleArg, cancelableArg, !isScoped(eventType), monotonicallyIncreasingTime())
 {
 }
 
 Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, double platformTimeStamp)
-    : Event(eventType, canBubbleArg, cancelableArg, !isScoped(eventType), false, platformTimeStamp)
+    : Event(eventType, canBubbleArg, cancelableArg, !isScoped(eventType), platformTimeStamp)
 {
 }
 
-Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, EventTarget* relatedTarget, double platformTimeStamp)
-    : Event(eventType, canBubbleArg, cancelableArg, !isScoped(eventType), relatedTarget ? true : false, platformTimeStamp)
-{
-}
-
-Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, bool composed)
-    : Event(eventType, canBubbleArg, cancelableArg, composed, false, monotonicallyIncreasingTime())
-{
-}
-
-Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, bool composed, bool relatedTargetScoped, double platformTimeStamp)
+Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, bool composed, double platformTimeStamp)
     : m_type(eventType)
     , m_canBubble(canBubbleArg)
     , m_cancelable(cancelableArg)
     , m_composed(composed)
-    , m_relatedTargetScoped(relatedTargetScoped)
     , m_propagationStopped(false)
     , m_immediatePropagationStopped(false)
     , m_defaultPrevented(false)
@@ -104,7 +88,7 @@
 }
 
 Event::Event(const AtomicString& eventType, const EventInit& initializer)
-    : Event(eventType, initializer.bubbles(), initializer.cancelable(), initializer.composed(), initializer.relatedTargetScoped(), monotonicallyIncreasingTime())
+    : Event(eventType, initializer.bubbles(), initializer.cancelable(), initializer.composed(), monotonicallyIncreasingTime())
 {
 }
 
@@ -136,8 +120,6 @@
     m_type = eventTypeArg;
     m_canBubble = canBubbleArg;
     m_cancelable = cancelableArg;
-
-    m_relatedTargetScoped = relatedTarget ? true : false;
 }
 
 bool Event::legacyReturnValue(ExecutionContext* executionContext) const
diff --git a/third_party/WebKit/Source/core/events/Event.h b/third_party/WebKit/Source/core/events/Event.h
index 1d71655..ef7e89b 100644
--- a/third_party/WebKit/Source/core/events/Event.h
+++ b/third_party/WebKit/Source/core/events/Event.h
@@ -131,7 +131,6 @@
     bool cancelable() const { return m_cancelable; }
     bool composed() const { return m_composed; }
     bool isScopedInV0() const;
-    bool relatedTargetScoped() const { return m_relatedTargetScoped; }
 
     // Event creation timestamp in milliseconds. If |HiResEventTimeStamp|
     // runtime feature is enabled it returns a DOMHighResTimeStamp using the
@@ -216,12 +215,8 @@
 
 protected:
     Event();
-    Event(const AtomicString& type, bool canBubble, bool cancelable);
-    Event(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget);
     Event(const AtomicString& type, bool canBubble, bool cancelable, double platformTimeStamp);
-    Event(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget, double platformTimeStamp);
-    Event(const AtomicString& type, bool canBubble, bool cancelable, bool composed);
-    Event(const AtomicString& type, bool canBubble, bool cancelable, bool composed, bool relatedTargetScoped, double platformTimeStamp);
+    Event(const AtomicString& type, bool canBubble, bool cancelable);
     Event(const AtomicString& type, const EventInit&);
 
     virtual void receivedTarget();
@@ -229,6 +224,8 @@
     void setCanBubble(bool bubble) { m_canBubble = bubble; }
 
 private:
+    Event(const AtomicString& type, bool canBubble, bool cancelable, bool composed, double platformTimeStamp);
+
     enum EventPathMode {
         EmptyAfterDispatch,
         NonEmptyAfterDispatch
@@ -240,7 +237,6 @@
     unsigned m_canBubble:1;
     unsigned m_cancelable:1;
     unsigned m_composed:1;
-    unsigned m_relatedTargetScoped:1;
 
     unsigned m_propagationStopped:1;
     unsigned m_immediatePropagationStopped:1;
diff --git a/third_party/WebKit/Source/core/events/Event.idl b/third_party/WebKit/Source/core/events/Event.idl
index 7671a1f..e9cf8c0 100644
--- a/third_party/WebKit/Source/core/events/Event.idl
+++ b/third_party/WebKit/Source/core/events/Event.idl
@@ -43,7 +43,6 @@
     readonly attribute boolean defaultPrevented;
 
     [RuntimeEnabled=ShadowDOMV1, MeasureAs=EventComposed] readonly attribute boolean composed;
-    [RuntimeEnabled=ShadowDOMV1, MeasureAs=EventRelatedTargetScoped] readonly attribute boolean relatedTargetScoped;
 
     [Unforgeable] readonly attribute boolean isTrusted;
 
diff --git a/third_party/WebKit/Source/core/events/EventInit.idl b/third_party/WebKit/Source/core/events/EventInit.idl
index a211a3c9..56bff0ce 100644
--- a/third_party/WebKit/Source/core/events/EventInit.idl
+++ b/third_party/WebKit/Source/core/events/EventInit.idl
@@ -8,5 +8,4 @@
     boolean bubbles = false;
     boolean cancelable = false;
     [RuntimeEnabled=ShadowDOMV1] boolean composed = false;
-    [RuntimeEnabled=ShadowDOMV1] boolean relatedTargetScoped = false;
 };
diff --git a/third_party/WebKit/Source/core/events/EventPath.cpp b/third_party/WebKit/Source/core/events/EventPath.cpp
index feb2f097..91eb910 100644
--- a/third_party/WebKit/Source/core/events/EventPath.cpp
+++ b/third_party/WebKit/Source/core/events/EventPath.cpp
@@ -258,33 +258,28 @@
         return;
     if (target.document() != relatedNode->document())
         return;
-    if (!target.inShadowIncludingDocument() || !relatedNode->inShadowIncludingDocument())
-        return;
+    retargetRelatedTarget(*relatedNode);
+    shrinkForRelatedTarget(target, *relatedNode);
+}
 
+void EventPath::retargetRelatedTarget(const Node& relatedTargetNode)
+{
     RelatedTargetMap relatedNodeMap;
-    buildRelatedNodeMap(*relatedNode, relatedNodeMap);
+    buildRelatedNodeMap(relatedTargetNode, relatedNodeMap);
 
     for (const auto& treeScopeEventContext : m_treeScopeEventContexts) {
         EventTarget* adjustedRelatedTarget = findRelatedNode(treeScopeEventContext->treeScope(), relatedNodeMap);
         ASSERT(adjustedRelatedTarget);
         treeScopeEventContext.get()->setRelatedTarget(adjustedRelatedTarget);
     }
-
-    shrinkIfNeeded(target, *relatedTarget);
 }
 
-void EventPath::shrinkIfNeeded(const Node& target, const EventTarget& relatedTarget)
+void EventPath::shrinkForRelatedTarget(const Node& target, const Node& relatedTarget)
 {
-    // Synthetic mouse events can have a relatedTarget which is identical to the target.
-    bool targetIsIdenticalToToRelatedTarget = (&target == &relatedTarget);
-
+    if (!target.isInShadowTree() && !relatedTarget.isInShadowTree())
+        return;
     for (size_t i = 0; i < size(); ++i) {
-        if (targetIsIdenticalToToRelatedTarget) {
-            if (target.treeScope().rootNode() == at(i).node()) {
-                shrink(i + 1);
-                break;
-            }
-        } else if (at(i).target() == at(i).relatedTarget()) {
+        if (at(i).target() == at(i).relatedTarget()) {
             // Event dispatching should be stopped here.
             shrink(i);
             break;
diff --git a/third_party/WebKit/Source/core/events/EventPath.h b/third_party/WebKit/Source/core/events/EventPath.h
index bbe7bd0..6f77175 100644
--- a/third_party/WebKit/Source/core/events/EventPath.h
+++ b/third_party/WebKit/Source/core/events/EventPath.h
@@ -83,7 +83,10 @@
     void calculateTreeOrderAndSetNearestAncestorClosedTree();
 
     void shrink(size_t newSize) { ASSERT(!m_windowEventContext); m_nodeEventContexts.shrink(newSize); }
-    void shrinkIfNeeded(const Node& target, const EventTarget& relatedTarget);
+
+    void retargetRelatedTarget(const Node& relatedTargetNode);
+
+    void shrinkForRelatedTarget(const Node& target, const Node& relatedTarget);
 
     void adjustTouchList(const TouchList*, HeapVector<Member<TouchList>> adjustedTouchList, const HeapVector<Member<TreeScope>>& treeScopes);
 
diff --git a/third_party/WebKit/Source/core/events/FocusEvent.cpp b/third_party/WebKit/Source/core/events/FocusEvent.cpp
index 91ca17d..99984e4 100644
--- a/third_party/WebKit/Source/core/events/FocusEvent.cpp
+++ b/third_party/WebKit/Source/core/events/FocusEvent.cpp
@@ -45,7 +45,7 @@
 }
 
 FocusEvent::FocusEvent(const AtomicString& type, bool canBubble, bool cancelable, AbstractView* view, int detail, EventTarget* relatedTarget, InputDeviceCapabilities* sourceCapabilities)
-    : UIEvent(type, canBubble, cancelable, relatedTarget, view, detail, sourceCapabilities)
+    : UIEvent(type, canBubble, cancelable, view, detail, sourceCapabilities)
     , m_relatedTarget(relatedTarget)
 {
 }
@@ -80,8 +80,7 @@
 
 DispatchEventResult FocusEventDispatchMediator::dispatchEvent(EventDispatcher& dispatcher) const
 {
-    if (event().relatedTargetScoped())
-        event().eventPath().adjustForRelatedTarget(dispatcher.node(), event().relatedTarget());
+    event().eventPath().adjustForRelatedTarget(dispatcher.node(), event().relatedTarget());
     return EventDispatchMediator::dispatchEvent(dispatcher);
 }
 
diff --git a/third_party/WebKit/Source/core/events/GestureEvent.cpp b/third_party/WebKit/Source/core/events/GestureEvent.cpp
index ab459cb7..b439b281 100644
--- a/third_party/WebKit/Source/core/events/GestureEvent.cpp
+++ b/third_party/WebKit/Source/core/events/GestureEvent.cpp
@@ -128,7 +128,7 @@
 }
 
 GestureEvent::GestureEvent(const AtomicString& type, AbstractView* view, int screenX, int screenY, int clientX, int clientY, PlatformEvent::Modifiers modifiers, float deltaX, float deltaY, float velocityX, float velocityY, ScrollInertialPhase inertialPhase, bool synthetic, ScrollGranularity deltaUnits, double platformTimeStamp, int resendingPluginId, GestureSource source)
-    : MouseRelatedEvent(type, true, true, nullptr, view, 0, IntPoint(screenX, screenY), IntPoint(clientX, clientY), IntPoint(0, 0), modifiers, platformTimeStamp, PositionType::Position)
+    : MouseRelatedEvent(type, true, true, view, 0, IntPoint(screenX, screenY), IntPoint(clientX, clientY), IntPoint(0, 0), modifiers, platformTimeStamp, PositionType::Position)
     , m_deltaX(deltaX)
     , m_deltaY(deltaY)
     , m_velocityX(velocityX)
diff --git a/third_party/WebKit/Source/core/events/MouseEvent.cpp b/third_party/WebKit/Source/core/events/MouseEvent.cpp
index ecd784f3..f6a378fe 100644
--- a/third_party/WebKit/Source/core/events/MouseEvent.cpp
+++ b/third_party/WebKit/Source/core/events/MouseEvent.cpp
@@ -119,7 +119,7 @@
     double platformTimeStamp,
     PlatformMouseEvent::SyntheticEventType syntheticEventType,
     const String& region)
-    : MouseRelatedEvent(eventType, canBubble, cancelable, relatedTarget, view, detail, IntPoint(screenX, screenY),
+    : MouseRelatedEvent(eventType, canBubble, cancelable, view, detail, IntPoint(screenX, screenY),
         IntPoint(windowX, windowY), IntPoint(movementX, movementY), modifiers,
         platformTimeStamp,
         syntheticEventType == PlatformMouseEvent::Positionless ? PositionType::Positionless : PositionType::Position,
@@ -273,8 +273,7 @@
 DispatchEventResult MouseEventDispatchMediator::dispatchEvent(EventDispatcher& dispatcher) const
 {
     MouseEvent& mouseEvent = event();
-    if (mouseEvent.relatedTargetScoped())
-        mouseEvent.eventPath().adjustForRelatedTarget(dispatcher.node(), mouseEvent.relatedTarget());
+    mouseEvent.eventPath().adjustForRelatedTarget(dispatcher.node(), mouseEvent.relatedTarget());
 
     if (!mouseEvent.isTrusted())
         return dispatcher.dispatch();
diff --git a/third_party/WebKit/Source/core/events/MouseRelatedEvent.cpp b/third_party/WebKit/Source/core/events/MouseRelatedEvent.cpp
index ffb097ca..1fdb6af 100644
--- a/third_party/WebKit/Source/core/events/MouseRelatedEvent.cpp
+++ b/third_party/WebKit/Source/core/events/MouseRelatedEvent.cpp
@@ -51,11 +51,11 @@
     return LayoutSize(frameView->scrollX() / scaleFactor, frameView->scrollY() / scaleFactor);
 }
 
-MouseRelatedEvent::MouseRelatedEvent(const AtomicString& eventType, bool canBubble, bool cancelable, EventTarget* relatedTarget,
+MouseRelatedEvent::MouseRelatedEvent(const AtomicString& eventType, bool canBubble, bool cancelable,
     AbstractView* abstractView, int detail, const IntPoint& screenLocation,
     const IntPoint& rootFrameLocation, const IntPoint& movementDelta, PlatformEvent::Modifiers modifiers,
     double platformTimeStamp, PositionType positionType, InputDeviceCapabilities* sourceCapabilities)
-    : UIEventWithKeyState(eventType, canBubble, cancelable, relatedTarget, abstractView, detail, modifiers, platformTimeStamp, sourceCapabilities)
+    : UIEventWithKeyState(eventType, canBubble, cancelable, abstractView, detail, modifiers, platformTimeStamp, sourceCapabilities)
     , m_screenLocation(screenLocation)
     , m_movementDelta(movementDelta)
     , m_positionType(positionType)
diff --git a/third_party/WebKit/Source/core/events/MouseRelatedEvent.h b/third_party/WebKit/Source/core/events/MouseRelatedEvent.h
index 3c1acc8..a18cbf6 100644
--- a/third_party/WebKit/Source/core/events/MouseRelatedEvent.h
+++ b/third_party/WebKit/Source/core/events/MouseRelatedEvent.h
@@ -71,7 +71,7 @@
     MouseRelatedEvent();
     // TODO(lanwei): Will make this argument non-optional and all the callers need to provide
     // sourceCapabilities even when it is null, see https://crbug.com/476530.
-    MouseRelatedEvent(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget,
+    MouseRelatedEvent(const AtomicString& type, bool canBubble, bool cancelable,
         AbstractView*, int detail, const IntPoint& screenLocation,
         const IntPoint& rootFrameLocation, const IntPoint& movementDelta, PlatformEvent::Modifiers,
         double platformTimeStamp, PositionType, InputDeviceCapabilities* sourceCapabilities = nullptr);
diff --git a/third_party/WebKit/Source/core/events/PointerEvent.cpp b/third_party/WebKit/Source/core/events/PointerEvent.cpp
index a922c699..cf32bc42 100644
--- a/third_party/WebKit/Source/core/events/PointerEvent.cpp
+++ b/third_party/WebKit/Source/core/events/PointerEvent.cpp
@@ -93,9 +93,7 @@
 
     ASSERT(!event().target() || event().target() != event().relatedTarget());
 
-    EventTarget* relatedTarget = event().relatedTarget();
-    if (event().relatedTargetScoped())
-        event().eventPath().adjustForRelatedTarget(dispatcher.node(), relatedTarget);
+    event().eventPath().adjustForRelatedTarget(dispatcher.node(), event().relatedTarget());
 
     return dispatcher.dispatch();
 }
diff --git a/third_party/WebKit/Source/core/events/RelatedEvent.cpp b/third_party/WebKit/Source/core/events/RelatedEvent.cpp
index 1285141b..a214507 100644
--- a/third_party/WebKit/Source/core/events/RelatedEvent.cpp
+++ b/third_party/WebKit/Source/core/events/RelatedEvent.cpp
@@ -30,7 +30,7 @@
 }
 
 RelatedEvent::RelatedEvent(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget)
-    : Event(type, canBubble, cancelable, relatedTarget)
+    : Event(type, canBubble, cancelable)
     , m_relatedTarget(relatedTarget)
 {
 }
diff --git a/third_party/WebKit/Source/core/events/UIEvent.cpp b/third_party/WebKit/Source/core/events/UIEvent.cpp
index 317cf06..6e5bb55 100644
--- a/third_party/WebKit/Source/core/events/UIEvent.cpp
+++ b/third_party/WebKit/Source/core/events/UIEvent.cpp
@@ -40,14 +40,6 @@
 {
 }
 
-UIEvent::UIEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, EventTarget* relatedTarget, AbstractView* viewArg, int detailArg, InputDeviceCapabilities* sourceCapabilitiesArg)
-    : Event(eventType, canBubbleArg, cancelableArg, relatedTarget)
-    , m_view(viewArg)
-    , m_detail(detailArg)
-    , m_sourceCapabilities(sourceCapabilitiesArg)
-{
-}
-
 UIEvent::UIEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, double platformTimeStamp, AbstractView* viewArg, int detailArg, InputDeviceCapabilities* sourceCapabilitiesArg)
     : Event(eventType, canBubbleArg, cancelableArg, platformTimeStamp)
     , m_view(viewArg)
@@ -56,14 +48,6 @@
 {
 }
 
-UIEvent::UIEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, EventTarget* relatedTarget, double platformTimeStamp, AbstractView* viewArg, int detailArg, InputDeviceCapabilities* sourceCapabilitiesArg)
-    : Event(eventType, canBubbleArg, cancelableArg, relatedTarget, platformTimeStamp)
-    , m_view(viewArg)
-    , m_detail(detailArg)
-    , m_sourceCapabilities(sourceCapabilitiesArg)
-{
-}
-
 UIEvent::UIEvent(const AtomicString& eventType, const UIEventInit& initializer)
     : Event(eventType, initializer)
     , m_view(initializer.view())
diff --git a/third_party/WebKit/Source/core/events/UIEvent.h b/third_party/WebKit/Source/core/events/UIEvent.h
index 4c743285..b4d91ac 100644
--- a/third_party/WebKit/Source/core/events/UIEvent.h
+++ b/third_party/WebKit/Source/core/events/UIEvent.h
@@ -71,9 +71,7 @@
     UIEvent();
     // TODO(crbug.com/563542): Remove of this ctor in favor of making platformTimeStamp (and perhaps sourceCapabilities) required in all constructions sites
     UIEvent(const AtomicString& type, bool canBubble, bool cancelable, AbstractView*, int detail, InputDeviceCapabilities* sourceCapabilities = nullptr);
-    UIEvent(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget, AbstractView*, int detail, InputDeviceCapabilities* sourceCapabilities = nullptr);
     UIEvent(const AtomicString& type, bool canBubble, bool cancelable, double platformTimeStamp, AbstractView*, int detail, InputDeviceCapabilities* sourceCapabilities);
-    UIEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, EventTarget* relatedTarget, double platformTimeStamp, AbstractView* viewArg, int detailArg, InputDeviceCapabilities* sourceCapabilitiesArg);
     UIEvent(const AtomicString&, const UIEventInit&);
 
 private:
diff --git a/third_party/WebKit/Source/core/events/UIEventWithKeyState.cpp b/third_party/WebKit/Source/core/events/UIEventWithKeyState.cpp
index b1eedb8..11aeb67 100644
--- a/third_party/WebKit/Source/core/events/UIEventWithKeyState.cpp
+++ b/third_party/WebKit/Source/core/events/UIEventWithKeyState.cpp
@@ -29,13 +29,6 @@
 {
 }
 
-UIEventWithKeyState::UIEventWithKeyState(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget, AbstractView* view,
-    int detail, PlatformEvent::Modifiers modifiers, double platformTimeStamp, InputDeviceCapabilities* sourceCapabilities)
-    : UIEvent(type, canBubble, cancelable, relatedTarget, platformTimeStamp, view, detail, sourceCapabilities)
-    , m_modifiers(modifiers)
-{
-}
-
 UIEventWithKeyState::UIEventWithKeyState(const AtomicString& type, const EventModifierInit& initializer)
     : UIEvent(type, initializer)
     , m_modifiers(0)
diff --git a/third_party/WebKit/Source/core/events/UIEventWithKeyState.h b/third_party/WebKit/Source/core/events/UIEventWithKeyState.h
index 80c88ee..c6b69d3 100644
--- a/third_party/WebKit/Source/core/events/UIEventWithKeyState.h
+++ b/third_party/WebKit/Source/core/events/UIEventWithKeyState.h
@@ -57,8 +57,6 @@
 
     UIEventWithKeyState(const AtomicString& type, bool canBubble, bool cancelable, AbstractView*,
         int detail, PlatformEvent::Modifiers, double platformTimeStamp, InputDeviceCapabilities* sourceCapabilities = nullptr);
-    UIEventWithKeyState(const AtomicString& type, bool canBubble, bool cancelable, EventTarget* relatedTarget, AbstractView*,
-        int detail, PlatformEvent::Modifiers, double platformTimeStamp, InputDeviceCapabilities* sourceCapabilities = nullptr);
     UIEventWithKeyState(const AtomicString& type, const EventModifierInit& initializer);
     void initModifiers(bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
 
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index 20afcab..a8f00c7 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1074,7 +1074,6 @@
         HTMLLabelElementControlForNonFormAssociatedElement = 1263,
         PatternAttributeUnicodeFlagIsIncompatible = 1264,
         HTMLMediaElementLoadNetworkEmptyNotPaused = 1265,
-        EventRelatedTargetScoped = 1266,
         V8Window_WebkitSpeechGrammar_ConstructorGetter = 1267,
         V8Window_WebkitSpeechGrammarList_ConstructorGetter = 1268,
         V8Window_WebkitSpeechRecognition_ConstructorGetter = 1269,