Title: [203950] trunk
Revision
203950
Author
[email protected]
Date
2016-07-30 17:29:19 -0700 (Sat, 30 Jul 2016)

Log Message

Enable strict type checking for Window dictionary members
https://bugs.webkit.org/show_bug.cgi?id=160356

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Rebaseline W3C test now that one more check is passing.

* web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt:

Source/WebCore:

Enable strict type checking for Window dictionary members. Technically,
we should do strict type checking of all wrapper types but this patch
focuses on Window because it is common to pass a Window dictionary
member to Event constructors.

By strict type checking, I mean that we should throw a TypeError is
the value is not null/undefined and does not implement the Window
interface:
- http://heycam.github.io/webidl/#es-interface

Firefox and Chrome comply with the specification already.

No new tests, updated / rebaselined existing tests.

* bindings/js/JSDictionary.cpp:
(WebCore::JSDictionary::convertValue):

LayoutTests:

Update existing tests to reflect behavior change.

* fast/events/constructors/composition-event-constructor-expected.txt:
* fast/events/constructors/composition-event-constructor.html:
* fast/events/constructors/focus-event-constructor-expected.txt:
* fast/events/constructors/focus-event-constructor.html:
* fast/events/constructors/keyboard-event-constructor-expected.txt:
* fast/events/constructors/keyboard-event-constructor.html:
* fast/events/constructors/mouse-event-constructor.html:
* fast/events/constructors/ui-event-constructor-expected.txt:
* fast/events/constructors/ui-event-constructor.html:
* fast/events/constructors/wheel-event-constructor.html:
* platform/mac/fast/events/constructors/mouse-event-constructor-expected.txt:
* platform/mac/fast/events/constructors/wheel-event-constructor-expected.txt:

* resources/js-test-pre.js:
Add a shouldThrowErrorName() utility function that is similar to shouldThrow()
but only checks the error name instead of the full error message. Checking
only the error name has the benefit of working across browsers and facilitating
refactoring of error messages.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (203949 => 203950)


--- trunk/LayoutTests/ChangeLog	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/ChangeLog	2016-07-31 00:29:19 UTC (rev 203950)
@@ -1,5 +1,33 @@
 2016-07-30  Chris Dumez  <[email protected]>
 
+        Enable strict type checking for Window dictionary members
+        https://bugs.webkit.org/show_bug.cgi?id=160356
+
+        Reviewed by Darin Adler.
+
+        Update existing tests to reflect behavior change.
+
+        * fast/events/constructors/composition-event-constructor-expected.txt:
+        * fast/events/constructors/composition-event-constructor.html:
+        * fast/events/constructors/focus-event-constructor-expected.txt:
+        * fast/events/constructors/focus-event-constructor.html:
+        * fast/events/constructors/keyboard-event-constructor-expected.txt:
+        * fast/events/constructors/keyboard-event-constructor.html:
+        * fast/events/constructors/mouse-event-constructor.html:
+        * fast/events/constructors/ui-event-constructor-expected.txt:
+        * fast/events/constructors/ui-event-constructor.html:
+        * fast/events/constructors/wheel-event-constructor.html:
+        * platform/mac/fast/events/constructors/mouse-event-constructor-expected.txt:
+        * platform/mac/fast/events/constructors/wheel-event-constructor-expected.txt:
+
+        * resources/js-test-pre.js:
+        Add a shouldThrowErrorName() utility function that is similar to shouldThrow()
+        but only checks the error name instead of the full error message. Checking
+        only the error name has the benefit of working across browsers and facilitating
+        refactoring of error messages.
+
+2016-07-30  Chris Dumez  <[email protected]>
+
         [WebIDL] Enable strict type checking for nullable attribute setters of wrapper types
         https://bugs.webkit.org/show_bug.cgi?id=160375
 

Modified: trunk/LayoutTests/fast/events/constructors/composition-event-constructor-expected.txt (203949 => 203950)


--- trunk/LayoutTests/fast/events/constructors/composition-event-constructor-expected.txt	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/fast/events/constructors/composition-event-constructor-expected.txt	2016-07-31 00:29:19 UTC (rev 203950)
@@ -14,19 +14,19 @@
 PASS new CompositionEvent('eventType', { cancelable: true }).cancelable is true
 PASS new CompositionEvent('eventType', { view: window }).view is window
 PASS new CompositionEvent('eventType', { view: this }).view is this
-PASS new CompositionEvent('eventType', { view: testObject }).view is null
-PASS new CompositionEvent('eventType', { view: document }).view is null
+PASS new CompositionEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new CompositionEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new CompositionEvent('eventType', { view: undefined }).view is null
 PASS new CompositionEvent('eventType', { view: null }).view is null
-PASS new CompositionEvent('eventType', { view: false }).view is null
-PASS new CompositionEvent('eventType', { view: true }).view is null
-PASS new CompositionEvent('eventType', { view: '' }).view is null
-PASS new CompositionEvent('eventType', { view: 'chocolate' }).view is null
-PASS new CompositionEvent('eventType', { view: 12345 }).view is null
-PASS new CompositionEvent('eventType', { view: 18446744073709551615 }).view is null
-PASS new CompositionEvent('eventType', { view: NaN }).view is null
-PASS new CompositionEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
-PASS new CompositionEvent('eventType', { get view() { return 123; } }).view is null
+PASS new CompositionEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new CompositionEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new CompositionEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new CompositionEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new CompositionEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new CompositionEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new CompositionEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new CompositionEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new CompositionEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new CompositionEvent('eventType', { get view() { throw 'CompositionEvent Error'; } }) threw exception CompositionEvent Error.
 PASS new CompositionEvent('eventType', { data: 'koakuma' }).data is "koakuma"
 PASS new CompositionEvent('eventType', { data: '' }).data is ""

Modified: trunk/LayoutTests/fast/events/constructors/composition-event-constructor.html (203949 => 203950)


--- trunk/LayoutTests/fast/events/constructors/composition-event-constructor.html	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/fast/events/constructors/composition-event-constructor.html	2016-07-31 00:29:19 UTC (rev 203950)
@@ -31,20 +31,20 @@
 shouldBe("new CompositionEvent('eventType', { view: this }).view", "this");
 
 // Non-window objects.
-shouldBe("new CompositionEvent('eventType', { view: testObject }).view", "null");
-shouldBe("new CompositionEvent('eventType', { view: document }).view", "null");
-shouldBe("new CompositionEvent('eventType', { view: undefined }).view", "null");
-shouldBe("new CompositionEvent('eventType', { view: null }).view", "null");
-shouldBe("new CompositionEvent('eventType', { view: false }).view", "null");
-shouldBe("new CompositionEvent('eventType', { view: true }).view", "null");
-shouldBe("new CompositionEvent('eventType', { view: '' }).view", "null");
-shouldBe("new CompositionEvent('eventType', { view: 'chocolate' }).view", "null");
-shouldBe("new CompositionEvent('eventType', { view: 12345 }).view", "null");
-shouldBe("new CompositionEvent('eventType', { view: 18446744073709551615 }).view", "null");
-shouldBe("new CompositionEvent('eventType', { view: NaN }).view", "null");
+shouldThrowErrorName("new CompositionEvent('eventType', { view: testObject }).view", "TypeError");
+shouldThrowErrorName("new CompositionEvent('eventType', { view: document }).view", "TypeError");
+shouldBeNull("new CompositionEvent('eventType', { view: undefined }).view");
+shouldBeNull("new CompositionEvent('eventType', { view: null }).view");
+shouldThrowErrorName("new CompositionEvent('eventType', { view: false }).view", "TypeError");
+shouldThrowErrorName("new CompositionEvent('eventType', { view: true }).view", "TypeError");
+shouldThrowErrorName("new CompositionEvent('eventType', { view: '' }).view", "TypeError");
+shouldThrowErrorName("new CompositionEvent('eventType', { view: 'chocolate' }).view", "TypeError");
+shouldThrowErrorName("new CompositionEvent('eventType', { view: 12345 }).view", "TypeError");
+shouldThrowErrorName("new CompositionEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
+shouldThrowErrorName("new CompositionEvent('eventType', { view: NaN }).view", "TypeError");
 // Note that valueOf() is not called, when the left hand side is evaluated.
-shouldBeFalse("new CompositionEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
-shouldBe("new CompositionEvent('eventType', { get view() { return 123; } }).view", "null");
+shouldThrowErrorName("new CompositionEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
+shouldThrowErrorName("new CompositionEvent('eventType', { get view() { return 123; } }).view", "TypeError");
 shouldThrow("new CompositionEvent('eventType', { get view() { throw 'CompositionEvent Error'; } })");
 
 // data is passed.

Modified: trunk/LayoutTests/fast/events/constructors/focus-event-constructor-expected.txt (203949 => 203950)


--- trunk/LayoutTests/fast/events/constructors/focus-event-constructor-expected.txt	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/fast/events/constructors/focus-event-constructor-expected.txt	2016-07-31 00:29:19 UTC (rev 203950)
@@ -14,19 +14,19 @@
 PASS new FocusEvent('eventType', { cancelable: true }).cancelable is true
 PASS new FocusEvent('eventType', { view: window }).view is window
 PASS new FocusEvent('eventType', { view: this }).view is this
-PASS new FocusEvent('eventType', { view: testObject }).view is null
-PASS new FocusEvent('eventType', { view: document }).view is null
+PASS new FocusEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new FocusEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new FocusEvent('eventType', { view: undefined }).view is null
 PASS new FocusEvent('eventType', { view: null }).view is null
-PASS new FocusEvent('eventType', { view: false }).view is null
-PASS new FocusEvent('eventType', { view: true }).view is null
-PASS new FocusEvent('eventType', { view: '' }).view is null
-PASS new FocusEvent('eventType', { view: 'chocolate' }).view is null
-PASS new FocusEvent('eventType', { view: 12345 }).view is null
-PASS new FocusEvent('eventType', { view: 18446744073709551615 }).view is null
-PASS new FocusEvent('eventType', { view: NaN }).view is null
-PASS new FocusEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
-PASS new FocusEvent('eventType', { get view() { return 123; } }).view is null
+PASS new FocusEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new FocusEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new FocusEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new FocusEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new FocusEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new FocusEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new FocusEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new FocusEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new FocusEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new FocusEvent('eventType', { get view() { throw 'FocusEvent Error'; } }) threw exception FocusEvent Error.
 PASS new FocusEvent('eventType', { relatedTarget: testDiv }).relatedTarget is testDiv
 PASS new FocusEvent('eventType', { relatedTarget: document }).relatedTarget is document

Modified: trunk/LayoutTests/fast/events/constructors/focus-event-constructor.html (203949 => 203950)


--- trunk/LayoutTests/fast/events/constructors/focus-event-constructor.html	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/fast/events/constructors/focus-event-constructor.html	2016-07-31 00:29:19 UTC (rev 203950)
@@ -33,20 +33,20 @@
 shouldBe("new FocusEvent('eventType', { view: this }).view", "this");
 
 // Non-window objects.
-shouldBe("new FocusEvent('eventType', { view: testObject }).view", "null");
-shouldBe("new FocusEvent('eventType', { view: document }).view", "null");
-shouldBe("new FocusEvent('eventType', { view: undefined }).view", "null");
-shouldBe("new FocusEvent('eventType', { view: null }).view", "null");
-shouldBe("new FocusEvent('eventType', { view: false }).view", "null");
-shouldBe("new FocusEvent('eventType', { view: true }).view", "null");
-shouldBe("new FocusEvent('eventType', { view: '' }).view", "null");
-shouldBe("new FocusEvent('eventType', { view: 'chocolate' }).view", "null");
-shouldBe("new FocusEvent('eventType', { view: 12345 }).view", "null");
-shouldBe("new FocusEvent('eventType', { view: 18446744073709551615 }).view", "null");
-shouldBe("new FocusEvent('eventType', { view: NaN }).view", "null");
+shouldThrowErrorName("new FocusEvent('eventType', { view: testObject }).view", "TypeError");
+shouldThrowErrorName("new FocusEvent('eventType', { view: document }).view", "TypeError");
+shouldBeNull("new FocusEvent('eventType', { view: undefined }).view");
+shouldBeNull("new FocusEvent('eventType', { view: null }).view");
+shouldThrowErrorName("new FocusEvent('eventType', { view: false }).view", "TypeError");
+shouldThrowErrorName("new FocusEvent('eventType', { view: true }).view", "TypeError");
+shouldThrowErrorName("new FocusEvent('eventType', { view: '' }).view", "TypeError");
+shouldThrowErrorName("new FocusEvent('eventType', { view: 'chocolate' }).view", "TypeError");
+shouldThrowErrorName("new FocusEvent('eventType', { view: 12345 }).view", "TypeError");
+shouldThrowErrorName("new FocusEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
+shouldThrowErrorName("new FocusEvent('eventType', { view: NaN }).view", "TypeError");
 // Note that valueOf() is not called, when the left hand side is evaluated.
-shouldBeFalse("new FocusEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
-shouldBe("new FocusEvent('eventType', { get view() { return 123; } }).view", "null");
+shouldThrowErrorName("new FocusEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
+shouldThrowErrorName("new FocusEvent('eventType', { get view() { return 123; } }).view", "TypeError");
 shouldThrow("new FocusEvent('eventType', { get view() { throw 'FocusEvent Error'; } })");
 
 // relatedTarget is passed.

Modified: trunk/LayoutTests/fast/events/constructors/keyboard-event-constructor-expected.txt (203949 => 203950)


--- trunk/LayoutTests/fast/events/constructors/keyboard-event-constructor-expected.txt	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/fast/events/constructors/keyboard-event-constructor-expected.txt	2016-07-31 00:29:19 UTC (rev 203950)
@@ -19,19 +19,19 @@
 PASS new KeyboardEvent('eventType', { cancelable: true }).cancelable is true
 PASS new KeyboardEvent('eventType', { view: window }).view is window
 PASS new KeyboardEvent('eventType', { view: this }).view is this
-PASS new KeyboardEvent('eventType', { view: testObject }).view is null
-PASS new KeyboardEvent('eventType', { view: document }).view is null
+PASS new KeyboardEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new KeyboardEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new KeyboardEvent('eventType', { view: undefined }).view is null
 PASS new KeyboardEvent('eventType', { view: null }).view is null
-PASS new KeyboardEvent('eventType', { view: false }).view is null
-PASS new KeyboardEvent('eventType', { view: true }).view is null
-PASS new KeyboardEvent('eventType', { view: '' }).view is null
-PASS new KeyboardEvent('eventType', { view: 'chocolate' }).view is null
-PASS new KeyboardEvent('eventType', { view: 12345 }).view is null
-PASS new KeyboardEvent('eventType', { view: 18446744073709551615 }).view is null
-PASS new KeyboardEvent('eventType', { view: NaN }).view is null
-PASS new KeyboardEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
-PASS new KeyboardEvent('eventType', { get view() { return 123; } }).view is null
+PASS new KeyboardEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new KeyboardEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new KeyboardEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new KeyboardEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new KeyboardEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new KeyboardEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new KeyboardEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new KeyboardEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new KeyboardEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new KeyboardEvent('eventType', { get view() { throw 'KeyboardEvent Error'; } }) threw exception KeyboardEvent Error.
 PASS new KeyboardEvent('eventType', { keyIdentifier: 'koakuma' }).keyIdentifier is "koakuma"
 PASS new KeyboardEvent('eventType', { keyIdentifier: '' }).keyIdentifier is ""

Modified: trunk/LayoutTests/fast/events/constructors/keyboard-event-constructor.html (203949 => 203950)


--- trunk/LayoutTests/fast/events/constructors/keyboard-event-constructor.html	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/fast/events/constructors/keyboard-event-constructor.html	2016-07-31 00:29:19 UTC (rev 203950)
@@ -36,20 +36,20 @@
 shouldBe("new KeyboardEvent('eventType', { view: this }).view", "this");
 
 // Non-window objects.
-shouldBe("new KeyboardEvent('eventType', { view: testObject }).view", "null");
-shouldBe("new KeyboardEvent('eventType', { view: document }).view", "null");
-shouldBe("new KeyboardEvent('eventType', { view: undefined }).view", "null");
-shouldBe("new KeyboardEvent('eventType', { view: null }).view", "null");
-shouldBe("new KeyboardEvent('eventType', { view: false }).view", "null");
-shouldBe("new KeyboardEvent('eventType', { view: true }).view", "null");
-shouldBe("new KeyboardEvent('eventType', { view: '' }).view", "null");
-shouldBe("new KeyboardEvent('eventType', { view: 'chocolate' }).view", "null");
-shouldBe("new KeyboardEvent('eventType', { view: 12345 }).view", "null");
-shouldBe("new KeyboardEvent('eventType', { view: 18446744073709551615 }).view", "null");
-shouldBe("new KeyboardEvent('eventType', { view: NaN }).view", "null");
+shouldThrowErrorName("new KeyboardEvent('eventType', { view: testObject }).view", "TypeError");
+shouldThrowErrorName("new KeyboardEvent('eventType', { view: document }).view", "TypeError");
+shouldBeNull("new KeyboardEvent('eventType', { view: undefined }).view");
+shouldBeNull("new KeyboardEvent('eventType', { view: null }).view");
+shouldThrowErrorName("new KeyboardEvent('eventType', { view: false }).view", "TypeError");
+shouldThrowErrorName("new KeyboardEvent('eventType', { view: true }).view", "TypeError");
+shouldThrowErrorName("new KeyboardEvent('eventType', { view: '' }).view", "TypeError");
+shouldThrowErrorName("new KeyboardEvent('eventType', { view: 'chocolate' }).view", "TypeError");
+shouldThrowErrorName("new KeyboardEvent('eventType', { view: 12345 }).view", "TypeError");
+shouldThrowErrorName("new KeyboardEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
+shouldThrowErrorName("new KeyboardEvent('eventType', { view: NaN }).view", "TypeError");
 // Note that valueOf() is not called, when the left hand side is evaluated.
-shouldBeFalse("new KeyboardEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
-shouldBe("new KeyboardEvent('eventType', { get view() { return 123; } }).view", "null");
+shouldThrowErrorName("new KeyboardEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
+shouldThrowErrorName("new KeyboardEvent('eventType', { get view() { return 123; } }).view", "TypeError");
 shouldThrow("new KeyboardEvent('eventType', { get view() { throw 'KeyboardEvent Error'; } })");
 
 // keyIdentifier is passed.

Modified: trunk/LayoutTests/fast/events/constructors/mouse-event-constructor.html (203949 => 203950)


--- trunk/LayoutTests/fast/events/constructors/mouse-event-constructor.html	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/fast/events/constructors/mouse-event-constructor.html	2016-07-31 00:29:19 UTC (rev 203950)
@@ -42,20 +42,20 @@
 shouldBe("new MouseEvent('eventType', { view: this }).view", "this");
 
 // Non-window objects.
-shouldBe("new MouseEvent('eventType', { view: testObject }).view", "null");
-shouldBe("new MouseEvent('eventType', { view: document }).view", "null");
-shouldBe("new MouseEvent('eventType', { view: undefined }).view", "null");
-shouldBe("new MouseEvent('eventType', { view: null }).view", "null");
-shouldBe("new MouseEvent('eventType', { view: false }).view", "null");
-shouldBe("new MouseEvent('eventType', { view: true }).view", "null");
-shouldBe("new MouseEvent('eventType', { view: '' }).view", "null");
-shouldBe("new MouseEvent('eventType', { view: 'chocolate' }).view", "null");
-shouldBe("new MouseEvent('eventType', { view: 12345 }).view", "null");
-shouldBe("new MouseEvent('eventType', { view: 18446744073709551615 }).view", "null");
-shouldBe("new MouseEvent('eventType', { view: NaN }).view", "null");
+shouldThrowErrorName("new MouseEvent('eventType', { view: testObject }).view", "TypeError");
+shouldThrowErrorName("new MouseEvent('eventType', { view: document }).view", "TypeError");
+shouldBeNull("new MouseEvent('eventType', { view: undefined }).view");
+shouldBeNull("new MouseEvent('eventType', { view: null }).view");
+shouldThrowErrorName("new MouseEvent('eventType', { view: false }).view", "TypeError");
+shouldThrowErrorName("new MouseEvent('eventType', { view: true }).view", "TypeError");
+shouldThrowErrorName("new MouseEvent('eventType', { view: '' }).view", "TypeError");
+shouldThrowErrorName("new MouseEvent('eventType', { view: 'chocolate' }).view", "TypeError");
+shouldThrowErrorName("new MouseEvent('eventType', { view: 12345 }).view", "TypeError");
+shouldThrowErrorName("new MouseEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
+shouldThrowErrorName("new MouseEvent('eventType', { view: NaN }).view", "TypeError");
 // Note that valueOf() is not called, when the left hand side is evaluated.
-shouldBeFalse("new MouseEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
-shouldBe("new MouseEvent('eventType', { get view() { return 123; } }).view", "null");
+shouldThrowErrorName("new MouseEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
+shouldThrowErrorName("new MouseEvent('eventType', { get view() { return 123; } }).view", "TypeError");
 shouldThrow("new MouseEvent('eventType', { get view() { throw 'MouseEvent Error'; } })");
 
 // detail, screenX, screenY, clientX and clientY are passed.

Modified: trunk/LayoutTests/fast/events/constructors/ui-event-constructor-expected.txt (203949 => 203950)


--- trunk/LayoutTests/fast/events/constructors/ui-event-constructor-expected.txt	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/fast/events/constructors/ui-event-constructor-expected.txt	2016-07-31 00:29:19 UTC (rev 203950)
@@ -13,19 +13,19 @@
 PASS new UIEvent('eventType', { cancelable: true }).cancelable is true
 PASS new UIEvent('eventType', { view: window }).view is window
 PASS new UIEvent('eventType', { view: this }).view is this
-PASS new UIEvent('eventType', { view: testObject }).view is null
-PASS new UIEvent('eventType', { view: document }).view is null
+PASS new UIEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new UIEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new UIEvent('eventType', { view: undefined }).view is null
 PASS new UIEvent('eventType', { view: null }).view is null
-PASS new UIEvent('eventType', { view: false }).view is null
-PASS new UIEvent('eventType', { view: true }).view is null
-PASS new UIEvent('eventType', { view: '' }).view is null
-PASS new UIEvent('eventType', { view: 'chocolate' }).view is null
-PASS new UIEvent('eventType', { view: 12345 }).view is null
-PASS new UIEvent('eventType', { view: 18446744073709551615 }).view is null
-PASS new UIEvent('eventType', { view: NaN }).view is null
-PASS new UIEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
-PASS new UIEvent('eventType', { get view() { return 123; } }).view is null
+PASS new UIEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new UIEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new UIEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new UIEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new UIEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new UIEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new UIEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new UIEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new UIEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new UIEvent('eventType', { get view() { throw 'UIEvent Error'; } }) threw exception UIEvent Error.
 PASS new UIEvent('eventType', { detail: 0 }).detail is 0
 PASS new UIEvent('eventType', { detail: 2147483647 }).detail is 2147483647

Modified: trunk/LayoutTests/fast/events/constructors/ui-event-constructor.html (203949 => 203950)


--- trunk/LayoutTests/fast/events/constructors/ui-event-constructor.html	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/fast/events/constructors/ui-event-constructor.html	2016-07-31 00:29:19 UTC (rev 203950)
@@ -30,20 +30,20 @@
 shouldBe("new UIEvent('eventType', { view: this }).view", "this");
 
 // Non-window objects.
-shouldBe("new UIEvent('eventType', { view: testObject }).view", "null");
-shouldBe("new UIEvent('eventType', { view: document }).view", "null");
-shouldBe("new UIEvent('eventType', { view: undefined }).view", "null");
-shouldBe("new UIEvent('eventType', { view: null }).view", "null");
-shouldBe("new UIEvent('eventType', { view: false }).view", "null");
-shouldBe("new UIEvent('eventType', { view: true }).view", "null");
-shouldBe("new UIEvent('eventType', { view: '' }).view", "null");
-shouldBe("new UIEvent('eventType', { view: 'chocolate' }).view", "null");
-shouldBe("new UIEvent('eventType', { view: 12345 }).view", "null");
-shouldBe("new UIEvent('eventType', { view: 18446744073709551615 }).view", "null");
-shouldBe("new UIEvent('eventType', { view: NaN }).view", "null");
+shouldThrowErrorName("new UIEvent('eventType', { view: testObject }).view", "TypeError");
+shouldThrowErrorName("new UIEvent('eventType', { view: document }).view", "TypeError");
+shouldBeNull("new UIEvent('eventType', { view: undefined }).view");
+shouldBeNull("new UIEvent('eventType', { view: null }).view");
+shouldThrowErrorName("new UIEvent('eventType', { view: false }).view", "TypeError");
+shouldThrowErrorName("new UIEvent('eventType', { view: true }).view", "TypeError");
+shouldThrowErrorName("new UIEvent('eventType', { view: '' }).view", "TypeError");
+shouldThrowErrorName("new UIEvent('eventType', { view: 'chocolate' }).view", "TypeError");
+shouldThrowErrorName("new UIEvent('eventType', { view: 12345 }).view", "TypeError");
+shouldThrowErrorName("new UIEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
+shouldThrowErrorName("new UIEvent('eventType', { view: NaN }).view", "TypeError");
 // Note that valueOf() is not called, when the left hand side is evaluated.
-shouldBeFalse("new UIEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
-shouldBe("new UIEvent('eventType', { get view() { return 123; } }).view", "null");
+shouldThrowErrorName("new UIEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
+shouldThrowErrorName("new UIEvent('eventType', { get view() { return 123; } }).view", "TypeError");
 shouldThrow("new UIEvent('eventType', { get view() { throw 'UIEvent Error'; } })");
 
 // detail is passed.

Modified: trunk/LayoutTests/fast/events/constructors/wheel-event-constructor.html (203949 => 203950)


--- trunk/LayoutTests/fast/events/constructors/wheel-event-constructor.html	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/fast/events/constructors/wheel-event-constructor.html	2016-07-31 00:29:19 UTC (rev 203950)
@@ -45,20 +45,20 @@
 shouldBe("new WheelEvent('eventType', { view: this }).view", "this");
 
 // Non-window objects.
-shouldBe("new WheelEvent('eventType', { view: testObject }).view", "null");
-shouldBe("new WheelEvent('eventType', { view: document }).view", "null");
-shouldBe("new WheelEvent('eventType', { view: undefined }).view", "null");
-shouldBe("new WheelEvent('eventType', { view: null }).view", "null");
-shouldBe("new WheelEvent('eventType', { view: false }).view", "null");
-shouldBe("new WheelEvent('eventType', { view: true }).view", "null");
-shouldBe("new WheelEvent('eventType', { view: '' }).view", "null");
-shouldBe("new WheelEvent('eventType', { view: 'chocolate' }).view", "null");
-shouldBe("new WheelEvent('eventType', { view: 12345 }).view", "null");
-shouldBe("new WheelEvent('eventType', { view: 18446744073709551615 }).view", "null");
-shouldBe("new WheelEvent('eventType', { view: NaN }).view", "null");
+shouldThrowErrorName("new WheelEvent('eventType', { view: testObject }).view", "TypeError");
+shouldThrowErrorName("new WheelEvent('eventType', { view: document }).view", "TypeError");
+shouldBeNull("new WheelEvent('eventType', { view: undefined }).view");
+shouldBeNull("new WheelEvent('eventType', { view: null }).view");
+shouldThrowErrorName("new WheelEvent('eventType', { view: false }).view", "TypeError");
+shouldThrowErrorName("new WheelEvent('eventType', { view: true }).view", "TypeError");
+shouldThrowErrorName("new WheelEvent('eventType', { view: '' }).view", "TypeError");
+shouldThrowErrorName("new WheelEvent('eventType', { view: 'chocolate' }).view", "TypeError");
+shouldThrowErrorName("new WheelEvent('eventType', { view: 12345 }).view", "TypeError");
+shouldThrowErrorName("new WheelEvent('eventType', { view: 18446744073709551615 }).view", "TypeError");
+shouldThrowErrorName("new WheelEvent('eventType', { view: NaN }).view", "TypeError");
 // Note that valueOf() is not called, when the left hand side is evaluated.
-shouldBeFalse("new WheelEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window");
-shouldBe("new WheelEvent('eventType', { get view() { return 123; } }).view", "null");
+shouldThrowErrorName("new WheelEvent('eventType', { view: {valueOf: function () { return window; } } }).view", "TypeError");
+shouldThrowErrorName("new WheelEvent('eventType', { get view() { return 123; } }).view", "TypeError");
 shouldThrow("new WheelEvent('eventType', { get view() { throw 'WheelEvent Error'; } })");
 
 // detail, screenX, screenY, clientX and clientY are passed.

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (203949 => 203950)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2016-07-31 00:29:19 UTC (rev 203950)
@@ -1,5 +1,16 @@
 2016-07-30  Chris Dumez  <[email protected]>
 
+        Enable strict type checking for Window dictionary members
+        https://bugs.webkit.org/show_bug.cgi?id=160356
+
+        Reviewed by Darin Adler.
+
+        Rebaseline W3C test now that one more check is passing.
+
+        * web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt:
+
+2016-07-30  Chris Dumez  <[email protected]>
+
         [WebIDL] Enable strict type checking for operations' nullable parameters of wrapper types
         https://bugs.webkit.org/show_bug.cgi?id=160374
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt (203949 => 203950)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-subclasses-constructors-expected.txt	2016-07-31 00:29:19 UTC (rev 203950)
@@ -41,7 +41,5 @@
 PASS CompositionEvent constructor (empty argument) 
 PASS CompositionEvent constructor (argument with default values) 
 PASS CompositionEvent constructor (argument with non-default values) 
-FAIL UIEvent constructor (view argument with wrong type) assert_throws: function "function () {
-    new UIEvent("x", { view: 7 })
-  }" did not throw
+PASS UIEvent constructor (view argument with wrong type) 
 

Modified: trunk/LayoutTests/platform/mac/fast/events/constructors/mouse-event-constructor-expected.txt (203949 => 203950)


--- trunk/LayoutTests/platform/mac/fast/events/constructors/mouse-event-constructor-expected.txt	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/platform/mac/fast/events/constructors/mouse-event-constructor-expected.txt	2016-07-31 00:29:19 UTC (rev 203950)
@@ -23,19 +23,19 @@
 PASS new MouseEvent('eventType', { cancelable: true }).cancelable is true
 PASS new MouseEvent('eventType', { view: window }).view is window
 PASS new MouseEvent('eventType', { view: this }).view is this
-PASS new MouseEvent('eventType', { view: testObject }).view is null
-PASS new MouseEvent('eventType', { view: document }).view is null
+PASS new MouseEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new MouseEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new MouseEvent('eventType', { view: undefined }).view is null
 PASS new MouseEvent('eventType', { view: null }).view is null
-PASS new MouseEvent('eventType', { view: false }).view is null
-PASS new MouseEvent('eventType', { view: true }).view is null
-PASS new MouseEvent('eventType', { view: '' }).view is null
-PASS new MouseEvent('eventType', { view: 'chocolate' }).view is null
-PASS new MouseEvent('eventType', { view: 12345 }).view is null
-PASS new MouseEvent('eventType', { view: 18446744073709551615 }).view is null
-PASS new MouseEvent('eventType', { view: NaN }).view is null
-PASS new MouseEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
-PASS new MouseEvent('eventType', { get view() { return 123; } }).view is null
+PASS new MouseEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new MouseEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new MouseEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new MouseEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new MouseEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new MouseEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new MouseEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new MouseEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new MouseEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new MouseEvent('eventType', { get view() { throw 'MouseEvent Error'; } }) threw exception MouseEvent Error.
 PASS new MouseEvent('eventType', { detail: 0 }).detail is 0
 PASS new MouseEvent('eventType', { detail: 2147483647 }).detail is 2147483647

Modified: trunk/LayoutTests/platform/mac/fast/events/constructors/wheel-event-constructor-expected.txt (203949 => 203950)


--- trunk/LayoutTests/platform/mac/fast/events/constructors/wheel-event-constructor-expected.txt	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/platform/mac/fast/events/constructors/wheel-event-constructor-expected.txt	2016-07-31 00:29:19 UTC (rev 203950)
@@ -26,19 +26,19 @@
 PASS new WheelEvent('eventType', { cancelable: true }).cancelable is true
 PASS new WheelEvent('eventType', { view: window }).view is window
 PASS new WheelEvent('eventType', { view: this }).view is this
-PASS new WheelEvent('eventType', { view: testObject }).view is null
-PASS new WheelEvent('eventType', { view: document }).view is null
+PASS new WheelEvent('eventType', { view: testObject }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new WheelEvent('eventType', { view: document }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new WheelEvent('eventType', { view: undefined }).view is null
 PASS new WheelEvent('eventType', { view: null }).view is null
-PASS new WheelEvent('eventType', { view: false }).view is null
-PASS new WheelEvent('eventType', { view: true }).view is null
-PASS new WheelEvent('eventType', { view: '' }).view is null
-PASS new WheelEvent('eventType', { view: 'chocolate' }).view is null
-PASS new WheelEvent('eventType', { view: 12345 }).view is null
-PASS new WheelEvent('eventType', { view: 18446744073709551615 }).view is null
-PASS new WheelEvent('eventType', { view: NaN }).view is null
-PASS new WheelEvent('eventType', { view: {valueOf: function () { return window; } } }).view == window is false
-PASS new WheelEvent('eventType', { get view() { return 123; } }).view is null
+PASS new WheelEvent('eventType', { view: false }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new WheelEvent('eventType', { view: true }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new WheelEvent('eventType', { view: '' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new WheelEvent('eventType', { view: 'chocolate' }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new WheelEvent('eventType', { view: 12345 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new WheelEvent('eventType', { view: 18446744073709551615 }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new WheelEvent('eventType', { view: NaN }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new WheelEvent('eventType', { view: {valueOf: function () { return window; } } }).view threw exception TypeError: Dictionary member is not of type Window.
+PASS new WheelEvent('eventType', { get view() { return 123; } }).view threw exception TypeError: Dictionary member is not of type Window.
 PASS new WheelEvent('eventType', { get view() { throw 'WheelEvent Error'; } }) threw exception WheelEvent Error.
 PASS new WheelEvent('eventType', { detail: 0 }).detail is 0
 PASS new WheelEvent('eventType', { detail: 2147483647 }).detail is 2147483647

Modified: trunk/LayoutTests/resources/js-test-pre.js (203949 => 203950)


--- trunk/LayoutTests/resources/js-test-pre.js	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/LayoutTests/resources/js-test-pre.js	2016-07-31 00:29:19 UTC (rev 203950)
@@ -617,6 +617,24 @@
         testFailed((_message ? _message : _a) + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + ".");
 }
 
+function shouldThrowErrorName(_a, _name)
+{
+    var _exception;
+    try {
+        typeof _a == "function" ? _a() : eval(_a);
+    } catch (e) {
+        _exception = e;
+    }
+
+    if (_exception) {
+        if (_exception.name == _name)
+            testPassed(_a + " threw exception " + _exception + ".");
+        else
+            testFailed(_a + " should throw a " + _name + ". Threw a " + _exception.name + ".");
+    } else
+        testFailed(_a + " should throw a " + _name + ". Did not throw.");
+}
+
 function shouldHaveHadError(message)
 {
     if (errorMessage) {

Modified: trunk/Source/WebCore/ChangeLog (203949 => 203950)


--- trunk/Source/WebCore/ChangeLog	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/Source/WebCore/ChangeLog	2016-07-31 00:29:19 UTC (rev 203950)
@@ -1,5 +1,29 @@
 2016-07-30  Chris Dumez  <[email protected]>
 
+        Enable strict type checking for Window dictionary members
+        https://bugs.webkit.org/show_bug.cgi?id=160356
+
+        Reviewed by Darin Adler.
+
+        Enable strict type checking for Window dictionary members. Technically,
+        we should do strict type checking of all wrapper types but this patch
+        focuses on Window because it is common to pass a Window dictionary
+        member to Event constructors.
+
+        By strict type checking, I mean that we should throw a TypeError is
+        the value is not null/undefined and does not implement the Window
+        interface:
+        - http://heycam.github.io/webidl/#es-interface
+
+        Firefox and Chrome comply with the specification already.
+
+        No new tests, updated / rebaselined existing tests.
+
+        * bindings/js/JSDictionary.cpp:
+        (WebCore::JSDictionary::convertValue):
+
+2016-07-30  Chris Dumez  <[email protected]>
+
         [WebIDL] Enable strict type checking for nullable attribute setters of wrapper types
         https://bugs.webkit.org/show_bug.cgi?id=160375
 

Modified: trunk/Source/WebCore/bindings/js/JSDictionary.cpp (203949 => 203950)


--- trunk/Source/WebCore/bindings/js/JSDictionary.cpp	2016-07-31 00:23:21 UTC (rev 203949)
+++ trunk/Source/WebCore/bindings/js/JSDictionary.cpp	2016-07-31 00:29:19 UTC (rev 203950)
@@ -178,7 +178,12 @@
 
 void JSDictionary::convertValue(ExecState* state, JSValue value, RefPtr<DOMWindow>& result)
 {
-    result = JSDOMWindow::toWrapped(*state, value);
+    auto* window = JSDOMWindow::toWrapped(*state, value);
+    if (UNLIKELY(!window) && !value.isUndefinedOrNull()) {
+        throwVMTypeError(state, "Dictionary member is not of type Window");
+        return;
+    }
+    result = window;
 }
 
 void JSDictionary::convertValue(ExecState* state, JSValue value, RefPtr<EventTarget>& result)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to