Changeset 198056 in webkit
- Timestamp:
- Mar 11, 2016 7:11:04 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 8 added
- 26 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r198050 r198056 1 2016-03-11 Ryosuke Niwa <rniwa@webkit.org> 2 3 Add Event.deepPath() and Event.scoped 4 https://bugs.webkit.org/show_bug.cgi?id=153538 5 <rdar://problem/24363836> 6 7 Reviewed by Darin Adler. 8 9 Added a W3C style testharness.js tests for Event.prototype.scoped, Event.prototype.scopedRelatedTarget, 10 Event.prototype.deepPath() and a test that uses eventSender to verify the values of the scoped and 11 scopedRelatedTarget flags on trusted events. 12 13 * fast/shadow-dom/Extensions-to-Event-Interface-expected.txt: Added. 14 * fast/shadow-dom/Extensions-to-Event-Interface.html: Added. 15 * fast/shadow-dom/event-with-related-target.html: 16 * fast/shadow-dom/resources: Added. 17 * fast/shadow-dom/resources/event-path-test-helpers.js: Added. Extracted from event-with-related-target.html. 18 * fast/shadow-dom/trusted-event-scoped-flags-expected.txt: Added. 19 * fast/shadow-dom/trusted-event-scoped-flags.html: Added. 20 * fast/xmlhttprequest/xmlhttprequest-get-expected.txt: 21 * http/tests/workers/worker-importScriptsOnError-expected.txt: 22 * inspector/model/remote-object-get-properties-expected.txt: 23 * platform/ios-simulator/fast/shadow-dom/trusted-event-scoped-flags-expected.txt: Added. 24 1 25 2016-03-11 Jiewen Tan <jiewen_tan@apple.com> 2 26 -
trunk/LayoutTests/fast/shadow-dom/event-with-related-target.html
r190288 r198056 8 8 <script src="../../resources/testharness.js"></script> 9 9 <script src="../../resources/testharnessreport.js"></script> 10 <script src="resources/event-path-test-helpers.js"></script> 10 11 <link rel='stylesheet' href='../../resources/testharness.css'> 11 12 </head> … … 13 14 <div id="log"></div> 14 15 <script> 15 16 function dispatchEventWithLog(shadow, target, event) {17 var eventPath = [];18 var relatedTargets = [];19 20 var attachedNodes = [];21 for (var nodeKey in shadow) {22 var startingNode = shadow[nodeKey];23 for (var node = startingNode; node; node = node.parentNode) {24 if (attachedNodes.indexOf(node) >= 0)25 continue;26 attachedNodes.push(node);27 node.addEventListener(event.type, (function (event) {28 eventPath.push(this.label);29 relatedTargets.push(event.relatedTarget.label);30 }).bind(node));31 }32 }33 34 target.dispatchEvent(event);35 36 return {eventPath: eventPath, relatedTargets: relatedTargets};37 }38 39 /*40 -SR: ShadowRoot -S: Slot41 A ------------------------------- A-SR42 + B ------------ B-SR + A1 --- A1-SR43 + C + B1 --- B1-SR + A2-S + A1a44 + D --- D-SR + B1a + B1b --- B1b-SR45 + D1 + B1c-S + B1b146 + B1b247 */48 function createTestTree(mode) {49 var namedNodes = {};50 51 function element(name) {52 var element = document.createElement(name.indexOf('-S') > 0 ? 'slot' : 'div');53 element.label = name;54 namedNodes[name] = element;55 for (var i = 1; i < arguments.length; i++) {56 var item = arguments[i];57 if (typeof(item) == 'function')58 item(element);59 else60 element.appendChild(item);61 }62 return element;63 }64 65 function shadow(name) {66 var children = [];67 for (var i = 1; i < arguments.length; i++)68 children.push(arguments[i]);69 return function (element) {70 var shadowRoot = element.attachShadow({mode: mode});71 shadowRoot.label = name;72 namedNodes[name] = shadowRoot;73 for (var child of children)74 shadowRoot.appendChild(child);75 }76 }77 78 var host = element('A',79 shadow('A-SR',80 element('A1',81 shadow('A1-SR',82 element('A1a'))),83 element('A2-S')84 ),85 element('B',86 shadow('B-SR',87 element('B1',88 shadow('B1-SR',89 element('B1b',90 shadow('B1b-SR',91 element('B1b1'),92 element('B1b2'))),93 element('B1c-S')),94 element('B1a'))),95 element('C'),96 element('D',97 shadow('D-SR',98 element('D1')))));99 100 return namedNodes;101 }102 16 103 17 /* -
trunk/LayoutTests/fast/shadow-dom/negative-tabindex-on-shadow-host-expected.txt
r197439 r198056 3 3 4 4 1. First sequentially focusable element outside shadow trees 5 2. / 3.2. Shadow host with a positive tabindex 6 3.1. Focusable element inside a shadow host with a positive tabindex 7 2. / 3.2. Shadow host with a positive tabindex 5 2. Shadow host with a positive tabindex 6 3. Focusable element inside a shadow host with a positive tabindex 8 7 4.1. Focusable element inside a shadow host with no tabindex 9 8 4.2. Shadow host with no tabindex -
trunk/LayoutTests/fast/shadow-dom/negative-tabindex-on-shadow-host.html
r197439 r198056 8 8 <div id="host-with-negative-tabindex" tabindex="-1" onfocus="log(this)">Shadow host with a negative tabindex</div> 9 9 <div id="host-with-no-tabindex" onfocus="log(this)">4.2. Shadow host with no tabindex</div> 10 <div id="host-with-positive-tabindex" tabindex="2" onfocus="log(this)">2. / 3.2.Shadow host with a positive tabindex</div>10 <div id="host-with-positive-tabindex" tabindex="2" onfocus="log(this)">2. Shadow host with a positive tabindex</div> 11 11 <div tabindex="0" onfocus="log(this)">5. Last sequentially focusable element outside shadow trees</div> 12 12 </div> … … 24 24 document.getElementById('host-with-positive-tabindex').attachShadow({mode: 'closed'}).innerHTML = ` 25 25 <slot></slot> 26 <div tabindex="0" onfocus="log(this)">3. 1.Focusable element inside a shadow host with a positive tabindex</div>26 <div tabindex="0" onfocus="log(this)">3. Focusable element inside a shadow host with a positive tabindex</div> 27 27 `; 28 28 -
trunk/LayoutTests/fast/xmlhttprequest/xmlhttprequest-get-expected.txt
r196520 r198056 49 49 clipboardData : 'undefined' 50 50 currentTarget : '[object XMLHttpRequest]' 51 deepPath : 'function deepPath() { 52 [native code] 53 }' 51 54 defaultPrevented : 'false' 52 55 eventPhase : '2' … … 61 64 [native code] 62 65 }' 66 relatedTargetScoped : 'false' 63 67 returnValue : 'true' 68 scoped : 'true' 64 69 srcElement : '[object XMLHttpRequest]' 65 70 stopImmediatePropagation : 'function stopImmediatePropagation() { -
trunk/LayoutTests/http/tests/workers/worker-importScriptsOnError-expected.txt
r196520 r198056 29 29 colno: 14, 30 30 currentTarget: [object Worker], 31 deepPath: function deepPath() { [native code] }, 31 32 defaultPrevented: false, 32 33 eventPhase: 2, … … 37 38 message: Error: Script error., 38 39 preventDefault: function preventDefault() { [native code] }, 40 relatedTargetScoped: false, 39 41 returnValue: true, 42 scoped: true, 40 43 srcElement: [object Worker], 41 44 stopImmediatePropagation: function stopImmediatePropagation() { [native code] }, -
trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt
r197815 r198056 49 49 bubbles 50 50 cancelable 51 scoped 52 relatedTargetScoped 51 53 timeStamp 52 54 defaultPrevented … … 66 68 bubbles 67 69 cancelable 70 scoped 71 relatedTargetScoped 68 72 timeStamp 69 73 defaultPrevented … … 72 76 cancelBubble 73 77 clipboardData 78 deepPath 74 79 stopPropagation 75 80 preventDefault -
trunk/Source/WebCore/ChangeLog
r198055 r198056 1 2016-03-11 Ryosuke Niwa <rniwa@webkit.org> 2 3 Add Event.deepPath() and Event.scoped 4 https://bugs.webkit.org/show_bug.cgi?id=153538 5 <rdar://problem/24363836> 6 7 Reviewed by Darin Adler. 8 9 Added the support for deepPath(), scoped, and relatedTargetScoped on Event.prototype for shadow DOM: 10 http://w3c.github.io/webcomponents/spec/shadow/#extensions-to-event-interface 11 and updated the EventPath class to respect scoped and relatedTargetScoped flags as specified at: 12 http://w3c.github.io/webcomponents/spec/shadow/#get-the-parent 13 14 Tests: fast/shadow-dom/Extensions-to-Event-Interface.html 15 fast/shadow-dom/trusted-event-scoped-flags.html 16 17 * bindings/scripts/CodeGeneratorJS.pm: 18 (GenerateConstructorDefinition): Added the support for Conditional for InitializedByEventConstructor. 19 * bindings/scripts/test/GObject/WebKitDOMTestEventConstructor.cpp: 20 * bindings/scripts/test/GObject/WebKitDOMTestEventConstructor.h: 21 * bindings/scripts/test/JS/JSTestEventConstructor.cpp: 22 * bindings/scripts/test/ObjC/DOMTestEventConstructor.h: 23 * bindings/scripts/test/ObjC/DOMTestEventConstructor.mm: 24 * bindings/scripts/test/TestEventConstructor.idl: Added a test case for using InitializedByEventConstructor 25 with Conditional. 26 * dom/Event.cpp: 27 (WebCore::Event::Event): Initialize m_scoped and m_relatedTargetScoped from EventInit dictionary. 28 (WebCore::Event::scoped): Added. Implements http://w3c.github.io/webcomponents/spec/shadow/#scoped-flag 29 (WebCore::Event::deepPath): Added. 30 * dom/Event.h: 31 (WebCore::Event::relatedTargetScoped): Added. Overridden by FocusEvent and MouseEvent to implement 32 http://w3c.github.io/webcomponents/spec/shadow/#relatedtargetscoped-flag 33 (WebCore::Event::setEventPath): Added. 34 (WebCore::Event::clearEventPath): Added. 35 * dom/Event.idl: Added scoped, relatedTargetScoped, and deepPath() conditionally enabled for shadow DOM. 36 * dom/EventContext.h: 37 (WebCore::EventContext::currentTarget): 38 * dom/EventDispatcher.cpp: 39 (WebCore::EventDispatcher::dispatchEvent): Set the event path while the event is being dispatched. 40 * dom/EventPath.cpp: 41 (WebCore::shouldEventCrossShadowBoundary): Check event.scoped flag instead of hard-coding a list of events here 42 which has been moved to Event::scoped. See above. 43 (WebCore::EventPath::setRelatedTarget): Check m_event.relatedTargetScoped() instead of hard-coding a list of 44 events here. relatedTargetScoped is overridden by FocusEvent and MouseEvent. 45 (WebCore::EventPath::hasEventListeners): Fixed the misleading variable name. 46 (WebCore::isUnclosedNodeOf): Added. Implements http://w3c.github.io/webcomponents/spec/shadow/#dfn-unclosed-node 47 (WebCore::EventPath::computePathDisclosedToTarget): Added. Implements the algorithm to filter event targets: 48 http://w3c.github.io/webcomponents/spec/shadow/#widl-Event-deepPath-sequence-EventTarget 49 * dom/EventPath.h: 50 * dom/FocusEvent.cpp: 51 (WebCore::FocusEvent::relatedTargetScoped): Returns true when this is a trusted event per: 52 http://w3c.github.io/webcomponents/spec/shadow/#relatedtargetscoped-flag 53 * dom/FocusEvent.h: 54 * dom/MouseEvent.cpp: 55 (WebCore::MouseEvent::relatedTargetScoped): Ditto. 56 * dom/MouseEvent.h: 57 1 58 2016-03-11 John Wilander <wilander@apple.com> 2 59 -
trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
r198023 r198056 4857 4857 my $attributeName = $attribute->signature->name; 4858 4858 my $attributeImplName = $attribute->signature->extendedAttributes->{"ImplementedAs"} || $attributeName; 4859 my $conditionalString = $codeGenerator->GenerateConditionalString($attribute->signature); 4860 4861 push(@implContent, "#if ${conditionalString}\n") if $conditionalString; 4862 4859 4863 push(@implContent, <<END); 4860 4864 if (!dictionary.tryGetProperty("${attributeName}", eventInit.${attributeImplName})) 4861 4865 return false; 4862 4866 END 4867 push(@implContent, "#endif\n") if $conditionalString; 4868 4863 4869 } 4864 4870 } -
trunk/Source/WebCore/bindings/scripts/test/GObject/WebKitDOMTestEventConstructor.cpp
r171294 r198056 72 72 PROP_ATTR1, 73 73 PROP_ATTR2, 74 PROP_ATTR3, 74 75 }; 75 76 … … 94 95 case PROP_ATTR2: 95 96 g_value_take_string(value, webkit_dom_test_event_constructor_get_attr2(self)); 97 break; 98 case PROP_ATTR3: 99 g_value_take_string(value, webkit_dom_test_event_constructor_get_attr3(self)); 96 100 break; 97 101 default: … … 140 144 WEBKIT_PARAM_READABLE)); 141 145 146 g_object_class_install_property( 147 gobjectClass, 148 PROP_ATTR3, 149 g_param_spec_string( 150 "attr3", 151 "TestEventConstructor:attr3", 152 "read-only gchar* TestEventConstructor:attr3", 153 "", 154 WEBKIT_PARAM_READABLE)); 155 142 156 } 143 157 … … 166 180 } 167 181 182 gchar* webkit_dom_test_event_constructor_get_attr3(WebKitDOMTestEventConstructor* self) 183 { 184 #if ENABLE(SPECIAL_EVENT) 185 WebCore::JSMainThreadNullState state; 186 g_return_val_if_fail(WEBKIT_DOM_IS_TEST_EVENT_CONSTRUCTOR(self), 0); 187 WebCore::TestEventConstructor* item = WebKit::core(self); 188 gchar* result = convertToUTF8String(item->attr3()); 189 return result; 190 #else 191 UNUSED_PARAM(self); 192 WEBKIT_WARN_FEATURE_NOT_PRESENT("Special Event") 193 return 0; 194 #endif /* ENABLE(SPECIAL_EVENT) */ 195 } 196 -
trunk/Source/WebCore/bindings/scripts/test/GObject/WebKitDOMTestEventConstructor.h
r170422 r198056 70 70 webkit_dom_test_event_constructor_get_attr2(WebKitDOMTestEventConstructor* self); 71 71 72 /** 73 * webkit_dom_test_event_constructor_get_attr3: 74 * @self: A #WebKitDOMTestEventConstructor 75 * 76 * Returns: A #gchar 77 * 78 * Stability: Unstable 79 **/ 80 WEBKIT_API gchar* 81 webkit_dom_test_event_constructor_get_attr3(WebKitDOMTestEventConstructor* self); 82 72 83 G_END_DECLS 73 84 -
trunk/Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp
r198023 r198056 39 39 JSC::EncodedJSValue jsTestEventConstructorAttr1(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName); 40 40 JSC::EncodedJSValue jsTestEventConstructorAttr2(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName); 41 #if ENABLE(SPECIAL_EVENT) 42 JSC::EncodedJSValue jsTestEventConstructorAttr3(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName); 43 #endif 41 44 JSC::EncodedJSValue jsTestEventConstructorConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName); 42 45 bool setJSTestEventConstructorConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue); … … 107 110 if (!dictionary.tryGetProperty("attr2", eventInit.attr2)) 108 111 return false; 112 #if ENABLE(SPECIAL_EVENT) 113 if (!dictionary.tryGetProperty("attr3", eventInit.attr3)) 114 return false; 115 #endif 109 116 return true; 110 117 } … … 132 139 { "attr1", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestEventConstructorAttr1), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, 133 140 { "attr2", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestEventConstructorAttr2), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, 141 #if ENABLE(SPECIAL_EVENT) 142 { "attr3", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsTestEventConstructorAttr3), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } }, 143 #else 144 { 0, 0, NoIntrinsic, { 0, 0 } }, 145 #endif 134 146 }; 135 147 … … 194 206 } 195 207 208 209 #if ENABLE(SPECIAL_EVENT) 210 EncodedJSValue jsTestEventConstructorAttr3(ExecState* state, EncodedJSValue thisValue, PropertyName) 211 { 212 UNUSED_PARAM(state); 213 UNUSED_PARAM(thisValue); 214 JSValue decodedThisValue = JSValue::decode(thisValue); 215 auto* castedThis = jsDynamicCast<JSTestEventConstructor*>(decodedThisValue); 216 if (UNLIKELY(!castedThis)) { 217 return throwGetterTypeError(*state, "TestEventConstructor", "attr3"); 218 } 219 auto& impl = castedThis->wrapped(); 220 JSValue result = jsStringWithCache(state, impl.attr3()); 221 return JSValue::encode(result); 222 } 223 224 #endif 196 225 197 226 EncodedJSValue jsTestEventConstructorConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName) -
trunk/Source/WebCore/bindings/scripts/test/ObjC/DOMTestEventConstructor.h
r183350 r198056 33 33 @property (readonly, copy) NSString *attr1; 34 34 @property (readonly, copy) NSString *attr2; 35 @property (readonly, copy) NSString *attr3; 35 36 @end -
trunk/Source/WebCore/bindings/scripts/test/ObjC/DOMTestEventConstructor.mm
r193378 r198056 68 68 } 69 69 70 #if ENABLE(SPECIAL_EVENT) 71 - (NSString *)attr3 72 { 73 WebCore::JSMainThreadNullState state; 74 return IMPL->attr3(); 75 } 76 #endif 77 70 78 @end 71 79 -
trunk/Source/WebCore/bindings/scripts/test/TestEventConstructor.idl
r165676 r198056 35 35 readonly attribute DOMString attr1; 36 36 [InitializedByEventConstructor] readonly attribute DOMString attr2; 37 [InitializedByEventConstructor, Conditional=SPECIAL_EVENT] readonly attribute DOMString attr3; 37 38 }; -
trunk/Source/WebCore/dom/Event.cpp
r196520 r198056 24 24 #include "Event.h" 25 25 26 #include "EventPath.h" 26 27 #include "EventTarget.h" 27 28 #include "UserGestureIndicator.h" … … 60 61 , m_canBubble(initializer.bubbles) 61 62 , m_cancelable(initializer.cancelable) 63 , m_scoped(initializer.scoped) 64 , m_relatedTargetScoped(initializer.relatedTargetScoped) 62 65 , m_createTime(convertSecondsToDOMTimeStamp(currentTime())) 63 66 { … … 84 87 } 85 88 89 bool Event::scoped() const 90 { 91 if (m_scoped) 92 return true; 93 94 // http://w3c.github.io/webcomponents/spec/shadow/#scoped-flag 95 if (!isTrusted()) 96 return false; 97 98 return m_type == eventNames().abortEvent 99 || m_type == eventNames().changeEvent 100 || m_type == eventNames().errorEvent 101 || m_type == eventNames().loadEvent 102 || m_type == eventNames().resetEvent 103 || m_type == eventNames().resizeEvent 104 || m_type == eventNames().scrollEvent 105 || m_type == eventNames().selectEvent 106 || m_type == eventNames().selectstartEvent; 107 } 108 86 109 EventInterface Event::eventInterface() const 87 110 { … … 162 185 if (m_target) 163 186 receivedTarget(); 187 } 188 189 Vector<EventTarget*> Event::deepPath() const 190 { 191 if (!m_eventPath) 192 return Vector<EventTarget*>(); 193 return m_eventPath->computePathDisclosedToTarget(*m_target); 164 194 } 165 195 -
trunk/Source/WebCore/dom/Event.h
r196520 r198056 37 37 38 38 class DataTransfer; 39 class EventPath; 39 40 class EventTarget; 40 41 class HTMLIFrameElement; … … 43 44 bool bubbles { false }; 44 45 bool cancelable { false }; 46 bool scoped { false }; 47 bool relatedTargetScoped { false }; 45 48 }; 46 49 … … 115 118 bool bubbles() const { return m_canBubble; } 116 119 bool cancelable() const { return m_cancelable; } 120 bool scoped() const; 121 virtual bool relatedTargetScoped() const { return m_relatedTargetScoped; } 122 117 123 DOMTimeStamp timeStamp() const { return m_createTime; } 124 125 void setEventPath(const EventPath& path) { m_eventPath = &path; } 126 void clearEventPath() { m_eventPath = nullptr; } 127 Vector<EventTarget*> deepPath() const; 118 128 119 129 void stopPropagation() { m_propagationStopped = true; } … … 199 209 bool m_canBubble { false }; 200 210 bool m_cancelable { false }; 211 bool m_scoped { false }; 212 bool m_relatedTargetScoped { false }; 201 213 202 214 bool m_propagationStopped { false }; … … 209 221 unsigned short m_eventPhase { 0 }; 210 222 EventTarget* m_currentTarget { nullptr }; 223 const EventPath* m_eventPath { nullptr }; 211 224 RefPtr<EventTarget> m_target; 212 225 DOMTimeStamp m_createTime; -
trunk/Source/WebCore/dom/Event.idl
r196520 r198056 58 58 [InitializedByEventConstructor] readonly attribute boolean bubbles; 59 59 [InitializedByEventConstructor] readonly attribute boolean cancelable; 60 [InitializedByEventConstructor, Conditional=SHADOW_DOM, EnabledAtRuntime=ShadowDOM] readonly attribute boolean scoped; 61 [InitializedByEventConstructor, Conditional=SHADOW_DOM, EnabledAtRuntime=ShadowDOM] readonly attribute boolean relatedTargetScoped; 60 62 readonly attribute DOMTimeStamp timeStamp; 63 64 [Conditional=SHADOW_DOM, EnabledAtRuntime=ShadowDOM] sequence<Node> deepPath(); 61 65 62 66 void stopPropagation(); -
trunk/Source/WebCore/dom/EventContext.h
r197563 r198056 48 48 49 49 Node* node() const { return m_node.get(); } 50 EventTarget* currentTarget() const { return m_currentTarget.get(); } 50 51 EventTarget* target() const { return m_target.get(); } 51 52 bool currentTargetSameAsTarget() const { return m_currentTarget.get() == m_target.get(); } -
trunk/Source/WebCore/dom/EventDispatcher.cpp
r197924 r198056 178 178 downcast<HTMLInputElement>(*node).willDispatchEvent(event, clickHandlingState); 179 179 180 if (!event.propagationStopped() && !eventPath.isEmpty()) 180 if (!event.propagationStopped() && !eventPath.isEmpty()) { 181 event.setEventPath(eventPath); 181 182 dispatchEventInDOM(event, eventPath, windowEventContext); 183 event.clearEventPath(); 184 } 182 185 183 186 event.setTarget(EventPath::eventTargetRespectingTargetRules(*node)); -
trunk/Source/WebCore/dom/EventPath.cpp
r197924 r198056 50 50 #endif 51 51 52 // WebKit never allowed selectstart event to cross the the shadow DOM boundary.53 // Changing this breaks existing sites.54 // See https://bugs.webkit.org/show_bug.cgi?id=52195 for details.55 const AtomicString& eventType = event.type();56 52 bool targetIsInShadowRoot = targetNode && &targetNode->treeScope().rootNode() == &shadowRoot; 57 return !targetIsInShadowRoot 58 || !(eventType == eventNames().abortEvent 59 || eventType == eventNames().changeEvent 60 || eventType == eventNames().errorEvent 61 || eventType == eventNames().loadEvent 62 || eventType == eventNames().resetEvent 63 || eventType == eventNames().resizeEvent 64 || eventType == eventNames().scrollEvent 65 || eventType == eventNames().selectEvent 66 || eventType == eventNames().selectstartEvent); 53 return !targetIsInShadowRoot || !event.scoped(); 67 54 } 68 55 … … 175 162 176 163 bool originIsRelatedTarget = &origin == relatedNode; 177 // FIXME: We should add a new flag on Event instead. 178 bool shouldTrimEventPath = m_event.type() == eventNames().mouseoverEvent 179 || m_event.type() == eventNames().mousemoveEvent 180 || m_event.type() == eventNames().mouseoutEvent; 164 bool relatedTargetScoped = m_event.relatedTargetScoped(); 181 165 Node& rootNodeInOriginTreeScope = origin.treeScope().rootNode(); 182 166 TreeScope* previousTreeScope = nullptr; … … 190 174 191 175 Node* currentRelatedNode = retargeter.currentNode(currentTreeScope); 192 if (UNLIKELY( shouldTrimEventPath&& !originIsRelatedTarget && context.target() == currentRelatedNode)) {176 if (UNLIKELY(relatedTargetScoped && !originIsRelatedTarget && context.target() == currentRelatedNode)) { 193 177 m_path.shrink(contextIndex); 194 178 break; … … 197 181 context.setRelatedTarget(currentRelatedNode); 198 182 199 if (UNLIKELY( shouldTrimEventPath&& originIsRelatedTarget && context.node() == &rootNodeInOriginTreeScope)) {183 if (UNLIKELY(relatedTargetScoped && originIsRelatedTarget && context.node() == &rootNodeInOriginTreeScope)) { 200 184 m_path.shrink(contextIndex + 1); 201 185 break; … … 252 236 bool EventPath::hasEventListeners(const AtomicString& eventType) const 253 237 { 254 for (auto& eventPath: m_path) {255 if ( eventPath->node()->hasEventListeners(eventType))238 for (auto& context : m_path) { 239 if (context->node()->hasEventListeners(eventType)) 256 240 return true; 257 241 } 258 242 259 243 return false; 244 } 245 246 // http://w3c.github.io/webcomponents/spec/shadow/#dfn-unclosed-node 247 static bool isUnclosedNodeOf(const Node& a, const Node& b) 248 { 249 // Use Vector instead of HashSet since we expect the number of ancestor tree scopes to be small. 250 Vector<TreeScope*, 8> treeScopesOpenToB; 251 252 for (auto* scope = &b.treeScope(); scope; scope = scope->parentTreeScope()) 253 treeScopesOpenToB.append(scope); 254 255 for (auto* treeScopeThatCanAccessA = &a.treeScope(); treeScopeThatCanAccessA; treeScopeThatCanAccessA = treeScopeThatCanAccessA->parentTreeScope()) { 256 for (auto* openToB : treeScopesOpenToB) { 257 if (openToB == treeScopeThatCanAccessA) 258 return true; 259 } 260 auto& root = treeScopeThatCanAccessA->rootNode(); 261 if (is<ShadowRoot>(root) && downcast<ShadowRoot>(root).type() != ShadowRoot::Type::Open) 262 break; 263 } 264 265 return false; 266 } 267 268 Vector<EventTarget*> EventPath::computePathDisclosedToTarget(const EventTarget& target) const 269 { 270 Vector<EventTarget*> path; 271 const Node* targetNode = const_cast<EventTarget&>(target).toNode(); 272 if (!targetNode) 273 return path; 274 275 for (auto& context : m_path) { 276 if (Node* nodeInPath = context->currentTarget()->toNode()) { 277 if (isUnclosedNodeOf(*nodeInPath, *targetNode)) 278 path.append(context->currentTarget()); 279 } 280 } 281 282 return path; 260 283 } 261 284 -
trunk/Source/WebCore/dom/EventPath.h
r197924 r198056 49 49 EventContext* lastContextIfExists() { return m_path.isEmpty() ? nullptr : m_path.last().get(); } 50 50 51 Vector<EventTarget*> computePathDisclosedToTarget(const EventTarget&) const; 52 51 53 static EventTarget* eventTargetRespectingTargetRules(Node& referenceNode) 52 54 { -
trunk/Source/WebCore/dom/FocusEvent.cpp
r196400 r198056 53 53 } 54 54 55 bool FocusEvent::relatedTargetScoped() const 56 { 57 return (isTrusted() && m_relatedTarget) || UIEvent::relatedTargetScoped(); 58 } 59 55 60 } // namespace WebCore -
trunk/Source/WebCore/dom/FocusEvent.h
r197563 r198056 59 59 FocusEvent(const AtomicString& type, const FocusEventInit&); 60 60 61 bool relatedTargetScoped() const override; 62 61 63 bool isFocusEvent() const override; 62 64 -
trunk/Source/WebCore/dom/MouseEvent.cpp
r196598 r198056 190 190 } 191 191 192 bool MouseEvent::relatedTargetScoped() const 193 { 194 return (isTrusted() && m_relatedTarget) || UIEvent::relatedTargetScoped(); 195 } 196 192 197 int MouseEvent::which() const 193 198 { -
trunk/Source/WebCore/dom/MouseEvent.h
r197566 r198056 122 122 MouseEvent(); 123 123 124 bool relatedTargetScoped() const override; 125 124 126 private: 125 127 unsigned short m_button;
Note: See TracChangeset
for help on using the changeset viewer.