Przeglądaj źródła

LibWeb: Ensure principal realm returned for nested Shadow Realms

Recently reported against the shadow realm proposal after running into
issues with WPT tests.

In a nested shadow realm, the associated realm is a shadow realm, not
the principal realm. One such issue this fixes is a crash when a nested
shadow realm performs an operation which requires the principal settings
object.
Shannon Booth 7 miesięcy temu
rodzic
commit
91007eb476

+ 2 - 2
Libraries/LibWeb/Bindings/MainThreadVM.cpp

@@ -580,8 +580,8 @@ ErrorOr<void> initialize_main_thread_vm(HTML::EventLoop::Type type)
             // 4. Set settings's execution context to context.
             .execution_context = move(context),
 
-            // 5. Set settings's principal realm to O's associated realm
-            .principal_realm = object.shape().realm(),
+            // 5. Set settings's principal realm to O's associated realm's principal realm
+            .principal_realm = HTML::principal_realm(object.shape().realm()),
 
             // 6. Set settings's module map to a new module map, initially empty.
             .module_map = realm.create<HTML::ModuleMap>(),

+ 1 - 0
Tests/LibWeb/Text/expected/HTML/ShadowRealm-in-ShadowRealm-evaluate-DOM-Event.txt

@@ -0,0 +1 @@
+Some event...

+ 41 - 0
Tests/LibWeb/Text/input/HTML/ShadowRealm-in-ShadowRealm-evaluate-DOM-Event.html

@@ -0,0 +1,41 @@
+<script src="../include.js"></script>
+<script>
+    function shadowRealmEvalAsync(realm, asyncBody) {
+        return new Promise(realm.evaluate(`
+            (resolve, reject) => {
+                (async () => {
+                    ${asyncBody}
+                })().then(resolve, (e) => reject(e.toString()));
+            }
+        `));
+    };
+
+    asyncTest(async done => {
+        const outerShadowRealm = new ShadowRealm();
+
+        outerShadowRealm.evaluate(`
+            var innerShadowRealm = new ShadowRealm();
+        `);
+
+        const outerResult = await shadowRealmEvalAsync(outerShadowRealm, `
+            function shadowRealmEvalAsync(realm, asyncBody) {
+                return new Promise(realm.evaluate(\`
+                    (resolve, reject) => {
+                        (async () => {
+                            \${asyncBody}
+                        })().then(resolve, (e) => reject(e.toString()));
+                    }
+                \`));
+            };
+
+            const innerResult = await shadowRealmEvalAsync(innerShadowRealm, \`
+                return new Event("Some event...").type;
+            \`);
+
+            return innerResult;
+        `);
+
+        println(outerResult);
+        done();
+    });
+</script>