Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebKit export of https://bugs.webkit.org/show_bug.cgi?id=223758 #29027

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions WebIDL/ecmascript-binding/global-object-implicit-this-value.any.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// META: global=window,worker

// https://heycam.github.io/webidl/#dfn-attribute-getter (step 1.1.2.1)
// https://heycam.github.io/webidl/#dfn-attribute-setter (step 4.5.1)
// https://heycam.github.io/webidl/#dfn-create-operation-function (step 2.1.2.1)

const notGlobalObject = Object.create(Object.getPrototypeOf(globalThis));

test(() => {
assert_throws_js(TypeError, () => { Object.create(globalThis).self; });
assert_throws_js(TypeError, () => { getGlobalPropertyDescriptor("location").get.call(notGlobalObject); });
assert_throws_js(TypeError, () => { Reflect.get(globalThis, "navigator", notGlobalObject); });
assert_throws_js(TypeError, () => { new Proxy(globalThis, {}).onerror; });
}, "Global object's getter throws when called on incompatible object");

test(() => {
assert_throws_js(TypeError, () => { Object.create(globalThis).origin = origin; });
assert_throws_js(TypeError, () => { getGlobalPropertyDescriptor("onerror").set.call(notGlobalObject, onerror); });
assert_throws_js(TypeError, () => { Reflect.set(globalThis, "onoffline", onoffline, notGlobalObject); });
assert_throws_js(TypeError, () => { new Proxy(globalThis, {}).ononline = ononline; });
}, "Global object's setter throws when called on incompatible object");

test(() => {
assert_throws_js(TypeError, () => { Object.create(globalThis).setTimeout(() => {}, 100); });
assert_throws_js(TypeError, () => { clearTimeout.call(notGlobalObject, () => {}); });
assert_throws_js(TypeError, () => { Reflect.apply(btoa, notGlobalObject, [""]); });
assert_throws_js(TypeError, () => { new Proxy(globalThis, {}).removeEventListener("foo", () => {}); });
}, "Global object's operation throws when called on incompatible object");

if (typeof document !== "undefined") {
shvaikalesh marked this conversation as resolved.
Show resolved Hide resolved
test(() => {
assert_throws_js(TypeError, () => { Object.getOwnPropertyDescriptor(window, "document").get.call(document.all); });
}, "Global object's getter throws when called on incompatible object (document.all)");

test(() => {
assert_throws_js(TypeError, () => { Object.getOwnPropertyDescriptor(window, "name").set.call(document.all); });
}, "Global object's setter throws when called on incompatible object (document.all)");

test(() => {
assert_throws_js(TypeError, () => { focus.call(document.all); });
}, "Global object's operation throws when called on incompatible object (document.all)");
}

// An engine might have different code path for calling a function from outer scope to implement step 1.b.iii of https://tc39.es/ecma262/#sec-evaluatecall
const locationGetter = getGlobalPropertyDescriptor("location").get;
test(() => {
assert_equals(getGlobalPropertyDescriptor("self").get.call(null), self);
assert_equals((() => locationGetter())(), location);
shvaikalesh marked this conversation as resolved.
Show resolved Hide resolved
assert_equals(Reflect.get(globalThis, "origin", null), origin);
assert_equals(Reflect.get(globalThis, "onoffline", undefined), onoffline);
}, "Global object's getter works when called on null / undefined");

test(() => {
const fn = () => {};

// origin is [Replaceable]
getGlobalPropertyDescriptor("origin").set.call(null, "foo");
shvaikalesh marked this conversation as resolved.
Show resolved Hide resolved
assert_equals(origin, "foo");
getGlobalPropertyDescriptor("onerror").set.call(undefined, fn);
assert_equals(onerror, fn);
assert_true(Reflect.set(globalThis, "onoffline", fn, null));
assert_equals(onoffline, fn);

const ononlineSetter = getGlobalPropertyDescriptor("ononline").set;
(() => { ononlineSetter(fn); })();
shvaikalesh marked this conversation as resolved.
Show resolved Hide resolved
assert_equals(ononline, fn);
}, "Global object's setter works when called on null / undefined");

// An engine might have different code path for calling a function from outer scope to implement step 1.b.iii of https://tc39.es/ecma262/#sec-evaluatecall
const __addEventListener = addEventListener;
test(() => {
assert_equals(atob.call(null, ""), "");
assert_equals(typeof (0, setInterval)(() => {}, 100), "number");

(() => { __addEventListener("foo", event => { event.preventDefault(); }); })();
const __dispatchEvent = dispatchEvent;
(() => { assert_false(__dispatchEvent(new Event("foo", { cancelable: true }))); })();
}, "Global object's operation works when called on null / undefined");

function getGlobalPropertyDescriptor(key) {
for (let obj = globalThis; obj; obj = Object.getPrototypeOf(obj)) {
const desc = Object.getOwnPropertyDescriptor(obj, key);
if (desc) return desc;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test AudioWorkletGlobalScope's registerProcessor() called on globalThis
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webaudio/resources/audit.js"></script>
</head>
<body>
<script id="layout-test-code">
const audit = Audit.createTaskRunner();
const realtimeContext = new AudioContext();
const filePath = 'processors/dummy-processor-globalthis.js';

audit.define('registerprocessor-called-on-globalthis', (task, should) => {
realtimeContext.audioWorklet.addModule(filePath).then(() => {
const dummyWorkletNode = new AudioWorkletNode(realtimeContext, 'dummy-globalthis');
should(dummyWorkletNode instanceof AudioWorkletNode,
'"dummyWorkletNode" is an instance of AudioWorkletNode').beTrue();
task.done();
});
});

audit.run();
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class DummyProcessor extends AudioWorkletProcessor {
constructor() {
super();
}

process(inputs, outputs, parameters) {
// Doesn't do anything here.
return true;
}
}

globalThis.registerProcessor('dummy-globalthis', DummyProcessor);