Commit e3f31124 authored by yuzus's avatar yuzus Committed by Commit bot

Add scoped flag to Event.

Spec is described here: http://w3c.github.io/webcomponents/spec/shadow/#dfn-scoped-flag
Only with UA's creation of certain events(abort, error, etc.), this scoped flag is set to true.
Note that any event created by users has scoped flag set to false by default.
R=hayato@chromium.org
BUG=531990, 575042

Review URL: https://codereview.chromium.org/1586563005

Cr-Commit-Position: refs/heads/master@{#371747}
parent a0ad68e8
...@@ -433,6 +433,15 @@ crbug.com/505364 imported/web-platform-tests/shadow-dom/untriaged/styles/css-var ...@@ -433,6 +433,15 @@ crbug.com/505364 imported/web-platform-tests/shadow-dom/untriaged/styles/css-var
crbug.com/505364 imported/web-platform-tests/shadow-dom/untriaged/styles/test-003.html [ Failure ] crbug.com/505364 imported/web-platform-tests/shadow-dom/untriaged/styles/test-003.html [ Failure ]
crbug.com/505364 imported/web-platform-tests/shadow-dom/untriaged/styles/test-010.html [ Failure Crash ] crbug.com/505364 imported/web-platform-tests/shadow-dom/untriaged/styles/test-010.html [ Failure Crash ]
crbug.com/505364 imported/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html [ Failure Crash ] crbug.com/505364 imported/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html [ Failure Crash ]
crbug.com/578010 imported/web-platform-tests/shadow-dom/untriaged/events/events-that-are-always-stopped/test-001.html [ Failure ]
crbug.com/578010 imported/web-platform-tests/shadow-dom/untriaged/events/events-that-are-always-stopped/test-002.html [ Failure ]
crbug.com/578010 imported/web-platform-tests/shadow-dom/untriaged/events/events-that-are-always-stopped/test-003.html [ Failure ]
crbug.com/578010 imported/web-platform-tests/shadow-dom/untriaged/events/events-that-are-always-stopped/test-004.html [ Failure ]
crbug.com/578010 imported/web-platform-tests/shadow-dom/untriaged/events/events-that-are-always-stopped/test-005.html [ Failure ]
crbug.com/578010 imported/web-platform-tests/shadow-dom/untriaged/events/events-that-are-always-stopped/test-006.html [ Failure ]
crbug.com/578010 imported/web-platform-tests/shadow-dom/untriaged/events/events-that-are-always-stopped/test-007.html [ Failure ]
crbug.com/578010 imported/web-platform-tests/shadow-dom/untriaged/events/events-that-are-always-stopped/test-008.html [ Failure ]
crbug.com/578010 imported/web-platform-tests/shadow-dom/untriaged/events/events-that-are-always-stopped/test-009.html [ Failure ]
crbug.com/552532 [ Win10 ] fast/replaced/no-focus-ring-embed.html [ Pass Crash ] crbug.com/552532 [ Win10 ] fast/replaced/no-focus-ring-embed.html [ Pass Crash ]
crbug.com/552532 [ Win10 ] fast/replaced/no-focus-ring-object.html [ Pass Crash ] crbug.com/552532 [ Win10 ] fast/replaced/no-focus-ring-object.html [ Pass Crash ]
......
CONSOLE WARNING: Calling Element.createShadowRoot() for an element which already hosts a shadow root is deprecated. See https://www.chromestatus.com/features/4668884095336448 for more details. CONSOLE WARNING: Calling Element.createShadowRoot() for an element which already hosts a shadow root is deprecated. See https://www.chromestatus.com/features/4668884095336448 for more details.
Tests to ensure that some kinds of events are stopeed at shadow boundary. Tests to ensure that all kinds of events are not stopeed at shadow boundary if created by users.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Other events than "click" should be stopped at shadow boundary. A "click" is added for the purpose of comparing results. None of the events should be stopped at a Shadow boundary if created by users.
abort abort
@target (target: target) @target (target: target)
@parent-of-target (target: target) @parent-of-target (target: target)
@host (target: host)
@top (target: host)
select select
@target (target: target) @target (target: target)
@parent-of-target (target: target) @parent-of-target (target: target)
@host (target: host)
@top (target: host)
change change
@target (target: target) @target (target: target)
@parent-of-target (target: target) @parent-of-target (target: target)
@host (target: host)
@top (target: host)
reset reset
@target (target: target) @target (target: target)
@parent-of-target (target: target) @parent-of-target (target: target)
@host (target: host)
@top (target: host)
resize resize
@target (target: target) @target (target: target)
@parent-of-target (target: target) @parent-of-target (target: target)
@host (target: host)
@top (target: host)
scroll scroll
@target (target: target) @target (target: target)
@parent-of-target (target: target) @parent-of-target (target: target)
@host (target: host)
@top (target: host)
selectstart selectstart
@target (target: target) @target (target: target)
@parent-of-target (target: target) @parent-of-target (target: target)
@host (target: host)
@top (target: host)
load load
@target (target: target) @target (target: target)
@parent-of-target (target: target) @parent-of-target (target: target)
@host (target: host)
error @top (target: host)
@target (target: target)
@parent-of-target (target: target)
click click
@target (target: target) @target (target: target)
...@@ -55,6 +67,7 @@ An event fired on a distributed child should not be stopped at the shadow bounda ...@@ -55,6 +67,7 @@ An event fired on a distributed child should not be stopped at the shadow bounda
@content (target: distributed-child) @content (target: distributed-child)
@parent-of-content (target: distributed-child) @parent-of-content (target: distributed-child)
@host2 (target: distributed-child) @host2 (target: distributed-child)
@host1 (target: host1)
An event is dispatched on a node in an older shadow tree. The older and the younger shadow root should receive the event, however, the shadow host shouldn't An event is dispatched on a node in an older shadow tree. The older and the younger shadow root should receive the event, however, the shadow host shouldn't
...@@ -63,6 +76,7 @@ An event is dispatched on a node in an older shadow tree. The older and the youn ...@@ -63,6 +76,7 @@ An event is dispatched on a node in an older shadow tree. The older and the youn
@older-shadow-root (target: target) @older-shadow-root (target: target)
@shadow-insertion-point (target: target) @shadow-insertion-point (target: target)
@younger-shadow-root (target: target) @younger-shadow-root (target: target)
@shadow-host (target: shadow-host)
PASS successfullyParsed is true PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<div id="sandbox"></div> <div id="sandbox"></div>
<pre id="console"></pre> <pre id="console"></pre>
<script> <script>
description("Tests to ensure that some kinds of events are stopeed at shadow boundary."); description("Tests to ensure that all kinds of events are not stopeed at shadow boundary if created by users.");
var eventRecords = {}; var eventRecords = {};
...@@ -49,9 +49,9 @@ function recordEvent(event) ...@@ -49,9 +49,9 @@ function recordEvent(event)
eventRecords[eventType].push(eventString); eventRecords[eventType].push(eventString);
} }
debug('Other events than "click" should be stopped at shadow boundary. A "click" is added for the purpose of comparing results.'); debug('None of the events should be stopped at a Shadow boundary if created by users.');
var events = ['abort', 'select', 'change', 'reset', 'resize', 'scroll', 'selectstart', 'load', 'error', 'click']; var events = ['abort', 'select', 'change', 'reset', 'resize', 'scroll', 'selectstart', 'load', 'click'];
function addEventListeners(nodes) function addEventListeners(nodes)
{ {
...@@ -62,7 +62,7 @@ function addEventListeners(nodes) ...@@ -62,7 +62,7 @@ function addEventListeners(nodes)
} }
} }
function testEventsShoudBeStoppedAtShadowBoundary() function testEventsShouldNotBeStoppedAtShadowBoundary()
{ {
var sandbox = document.getElementById('sandbox'); var sandbox = document.getElementById('sandbox');
sandbox.innerHTML = ''; sandbox.innerHTML = '';
...@@ -138,7 +138,7 @@ function testEventsInMultipleShadowTrees() ...@@ -138,7 +138,7 @@ function testEventsInMultipleShadowTrees()
function test() function test()
{ {
testEventsShoudBeStoppedAtShadowBoundary() testEventsShouldNotBeStoppedAtShadowBoundary();
testEventsFiredOnDistributedNodesShouldNotBeStoppedAtShadowBoundary(); testEventsFiredOnDistributedNodesShouldNotBeStoppedAtShadowBoundary();
testEventsInMultipleShadowTrees(); testEventsInMultipleShadowTrees();
} }
......
<!DOCTYPE html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="resources/shadow-dom.js"></script>
<img id="img" src="../../images/resources/test-load.jpg">
<div id="sandbox">
<div id = "host">
<template>
<img id="target" src="../../images/resources/test-load.jpg">
</template>
</div>
</div>
<script>
setup({ explicit_done: true });
var e;
test(function() {
e = new Event('test');
assert_equals(e.scoped, false);
}, "A new event's scoped value should be set to false by default.");
test(function() {
e = new Event('test', { scoped: true });
assert_equals(e.scoped, true);
}, 'Users should be able to set a scoped value.');
img.onload = function(e) {
test(function() {
assert_equals(e.scoped, true);
}, "UA load event's scoped should be set to true");
};
var resultNonTrusted = [];
function addEventListeners(nodes)
{
for (var i = 0; i < nodes.length; ++i) {
var node = getNodeInTreeOfTrees(nodes[i]);
node.addEventListener('load', recordEvent, false);
node.addEventListener('error', recordEvent, false);
}
}
function recordEvent(event)
{
if (event.type == 'load') {
if (event.currentTarget.id == 'host'){
test(function() {
assert_true(false);
}, "Load event should be stopped if created by UAs.");
} else {
test(function() {
assert_equals(event.currentTarget.id, 'target');
}, "Event fired in the right place.");
}
}
if (event.type == 'error') {
resultNonTrusted.push(event.currentTarget.id);
if (resultNonTrusted.length == 2) {
test(function() {
assert_array_equals(resultNonTrusted, ['target', 'host']);
}, "Only certain trusted events should stop in bubbling.");
done();
}
}
}
var sandbox = document.getElementById('sandbox');
convertTemplatesToShadowRootsWithin(sandbox);
var targetImg = getNodeInTreeOfTrees('host/target');
addEventListeners(['host', 'host/target']);
targetImg.setAttribute('src', '../../images/resources/lenna.jpg');
var userError = new Event('error');
targetImg.dispatchEvent(userError);
</script>
...@@ -58,6 +58,7 @@ path : '' ...@@ -58,6 +58,7 @@ path : ''
position : '0' position : '0'
preventDefault : 'function preventDefault() { [native code] }' preventDefault : 'function preventDefault() { [native code] }'
returnValue : 'true' returnValue : 'true'
scoped : 'true'
srcElement : '[object XMLHttpRequest]' srcElement : '[object XMLHttpRequest]'
stopImmediatePropagation : 'function stopImmediatePropagation() { [native code] }' stopImmediatePropagation : 'function stopImmediatePropagation() { [native code] }'
stopPropagation : 'function stopPropagation() { [native code] }' stopPropagation : 'function stopPropagation() { [native code] }'
......
...@@ -150,6 +150,7 @@ interface Event ...@@ -150,6 +150,7 @@ interface Event
getter eventPhase getter eventPhase
getter path getter path
getter returnValue getter returnValue
getter scoped
getter srcElement getter srcElement
getter target getter target
getter timeStamp getter timeStamp
......
...@@ -151,6 +151,7 @@ Starting worker: resources/global-interface-listing.js ...@@ -151,6 +151,7 @@ Starting worker: resources/global-interface-listing.js
[Worker] getter eventPhase [Worker] getter eventPhase
[Worker] getter path [Worker] getter path
[Worker] getter returnValue [Worker] getter returnValue
[Worker] getter scoped
[Worker] getter srcElement [Worker] getter srcElement
[Worker] getter target [Worker] getter target
[Worker] getter timeStamp [Worker] getter timeStamp
......
...@@ -1398,6 +1398,7 @@ interface Event ...@@ -1398,6 +1398,7 @@ interface Event
getter eventPhase getter eventPhase
getter path getter path
getter returnValue getter returnValue
getter scoped
getter srcElement getter srcElement
getter target getter target
getter timeStamp getter timeStamp
......
...@@ -141,6 +141,7 @@ Starting worker: resources/global-interface-listing.js ...@@ -141,6 +141,7 @@ Starting worker: resources/global-interface-listing.js
[Worker] getter eventPhase [Worker] getter eventPhase
[Worker] getter path [Worker] getter path
[Worker] getter returnValue [Worker] getter returnValue
[Worker] getter scoped
[Worker] getter srcElement [Worker] getter srcElement
[Worker] getter target [Worker] getter target
[Worker] getter timeStamp [Worker] getter timeStamp
......
...@@ -34,20 +34,44 @@ ...@@ -34,20 +34,44 @@
namespace blink { namespace blink {
static bool defaultScopedFromEventType(const AtomicString& eventType)
{
return (eventType == EventTypeNames::abort
|| eventType == EventTypeNames::change
|| eventType == EventTypeNames::error
|| eventType == EventTypeNames::load
|| eventType == EventTypeNames::reset
|| eventType == EventTypeNames::resize
|| eventType == EventTypeNames::scroll
|| eventType == EventTypeNames::select
|| eventType == EventTypeNames::selectstart);
}
Event::Event() Event::Event()
: Event("", false, false) : Event("", false, false, false)
{ {
} }
Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg) Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
: Event(eventType, canBubbleArg, cancelableArg, monotonicallyIncreasingTime()) : Event(eventType, canBubbleArg, cancelableArg, defaultScopedFromEventType(eventType), monotonicallyIncreasingTime())
{ {
} }
Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, double platformTimeStamp) Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, double platformTimeStamp)
: Event(eventType, canBubbleArg, cancelableArg, defaultScopedFromEventType(eventType), platformTimeStamp)
{
}
Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, bool scoped)
: Event(eventType, canBubbleArg, cancelableArg, scoped, monotonicallyIncreasingTime())
{
}
Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, bool scoped, double platformTimeStamp)
: m_type(eventType) : m_type(eventType)
, m_canBubble(canBubbleArg) , m_canBubble(canBubbleArg)
, m_cancelable(cancelableArg) , m_cancelable(cancelableArg)
, m_scoped(scoped)
, m_propagationStopped(false) , m_propagationStopped(false)
, m_immediatePropagationStopped(false) , m_immediatePropagationStopped(false)
, m_defaultPrevented(false) , m_defaultPrevented(false)
...@@ -63,7 +87,7 @@ Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableAr ...@@ -63,7 +87,7 @@ Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableAr
} }
Event::Event(const AtomicString& eventType, const EventInit& initializer) Event::Event(const AtomicString& eventType, const EventInit& initializer)
: Event(eventType, initializer.bubbles(), initializer.cancelable()) : Event(eventType, initializer.bubbles(), initializer.cancelable(), initializer.scoped())
{ {
} }
......
...@@ -123,6 +123,7 @@ public: ...@@ -123,6 +123,7 @@ public:
bool bubbles() const { return m_canBubble; } bool bubbles() const { return m_canBubble; }
bool cancelable() const { return m_cancelable; } bool cancelable() const { return m_cancelable; }
bool scoped() const { return m_scoped; }
// Event creation timestamp in milliseconds. If |HiResEventTimeStamp| // Event creation timestamp in milliseconds. If |HiResEventTimeStamp|
// runtime feature is enabled it returns a DOMHighResTimeStamp using the // runtime feature is enabled it returns a DOMHighResTimeStamp using the
...@@ -205,6 +206,8 @@ protected: ...@@ -205,6 +206,8 @@ protected:
Event(); Event();
Event(const AtomicString& type, bool canBubble, bool cancelable); Event(const AtomicString& type, bool canBubble, bool cancelable);
Event(const AtomicString& type, bool canBubble, bool cancelable, double platformTimeStamp); Event(const AtomicString& type, bool canBubble, bool cancelable, double platformTimeStamp);
Event(const AtomicString& type, bool canBubble, bool cancelable, bool scoped);
Event(const AtomicString& type, bool canBubble, bool cancelable, bool scoped, double platformTimeStamp);
Event(const AtomicString& type, const EventInit&); Event(const AtomicString& type, const EventInit&);
virtual void receivedTarget(); virtual void receivedTarget();
...@@ -216,6 +219,7 @@ private: ...@@ -216,6 +219,7 @@ private:
AtomicString m_type; AtomicString m_type;
unsigned m_canBubble:1; unsigned m_canBubble:1;
unsigned m_cancelable:1; unsigned m_cancelable:1;
unsigned m_scoped:1;
unsigned m_propagationStopped:1; unsigned m_propagationStopped:1;
unsigned m_immediatePropagationStopped:1; unsigned m_immediatePropagationStopped:1;
......
...@@ -43,6 +43,8 @@ ...@@ -43,6 +43,8 @@
void preventDefault(); void preventDefault();
readonly attribute boolean defaultPrevented; readonly attribute boolean defaultPrevented;
[RuntimeEnabled=ShadowDOMV1, MeasureAs=EventScoped] readonly attribute boolean scoped;
[RuntimeEnabled=TrustedEvents, Unforgeable] readonly attribute boolean isTrusted; [RuntimeEnabled=TrustedEvents, Unforgeable] readonly attribute boolean isTrusted;
// TODO(majidvp): At the moment the actual return value type can either // TODO(majidvp): At the moment the actual return value type can either
......
...@@ -7,4 +7,5 @@ ...@@ -7,4 +7,5 @@
dictionary EventInit { dictionary EventInit {
boolean bubbles = false; boolean bubbles = false;
boolean cancelable = false; boolean cancelable = false;
[RuntimeEnabled=ShadowDOMV1] boolean scoped = false;
}; };
...@@ -55,15 +55,7 @@ static inline bool shouldStopAtShadowRoot(Event& event, ShadowRoot& shadowRoot, ...@@ -55,15 +55,7 @@ static inline bool shouldStopAtShadowRoot(Event& event, ShadowRoot& shadowRoot,
// See https://bugs.webkit.org/show_bug.cgi?id=52195 for details. // See https://bugs.webkit.org/show_bug.cgi?id=52195 for details.
const AtomicString eventType = event.type(); const AtomicString eventType = event.type();
return target.toNode() && target.toNode()->shadowHost() == shadowRoot.host() return target.toNode() && target.toNode()->shadowHost() == shadowRoot.host()
&& (eventType == EventTypeNames::abort && event.scoped();
|| eventType == EventTypeNames::change
|| eventType == EventTypeNames::error
|| eventType == EventTypeNames::load
|| eventType == EventTypeNames::reset
|| eventType == EventTypeNames::resize
|| eventType == EventTypeNames::scroll
|| eventType == EventTypeNames::select
|| eventType == EventTypeNames::selectstart);
} }
EventPath::EventPath(Node& node, Event* event) EventPath::EventPath(Node& node, Event* event)
......
...@@ -993,6 +993,7 @@ public: ...@@ -993,6 +993,7 @@ public:
V8PromiseChain = 1137, V8PromiseChain = 1137,
V8PromiseAccept = 1138, V8PromiseAccept = 1138,
V8PromiseDefer = 1139, V8PromiseDefer = 1139,
EventScoped = 1140,
// Add new features immediately above this line. Don't change assigned // Add new features immediately above this line. Don't change assigned
// numbers of any item, and don't reuse removed slots. // numbers of any item, and don't reuse removed slots.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment