소스 검색

LibWeb: Add support for LegacyWindowAlias IDL extended attribute

Bastiaan van der Plaat 1 년 전
부모
커밋
c1ba3e5fa9

+ 26 - 5
Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp

@@ -329,13 +329,29 @@ void add_@global_object_snake_name@_exposed_interfaces(JS::Object& global)
     static constexpr u8 attr = JS::Attribute::Writable | JS::Attribute::Configurable;
 )~~~");
 
-    auto add_interface = [](SourceGenerator& gen, StringView name, StringView prototype_class, Optional<LegacyConstructor> const& legacy_constructor) {
+    auto add_interface = [](SourceGenerator& gen, StringView name, StringView prototype_class, Optional<LegacyConstructor> const& legacy_constructor, Optional<ByteString> const& legacy_alias_name) {
         gen.set("interface_name", name);
         gen.set("prototype_class", prototype_class);
 
         gen.append(R"~~~(
     global.define_intrinsic_accessor("@interface_name@", attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@interface_name@"_fly_string); });)~~~");
 
+        // https://webidl.spec.whatwg.org/#LegacyWindowAlias
+        if (legacy_alias_name.has_value()) {
+            if (legacy_alias_name->starts_with('(')) {
+                auto legacy_alias_names = legacy_alias_name->substring_view(1).split_view(',');
+                for (auto legacy_alias_name : legacy_alias_names) {
+                    gen.set("interface_alias_name", legacy_alias_name.trim_whitespace());
+                    gen.append(R"~~~(
+    global.define_intrinsic_accessor("@interface_alias_name@", attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@interface_name@"_fly_string); });)~~~");
+                }
+            } else {
+                gen.set("interface_alias_name", *legacy_alias_name);
+                gen.append(R"~~~(
+    global.define_intrinsic_accessor("@interface_alias_name@", attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@interface_name@"_fly_string); });)~~~");
+            }
+        }
+
         if (legacy_constructor.has_value()) {
             gen.set("legacy_interface_name", legacy_constructor->name);
             gen.append(R"~~~(
@@ -354,10 +370,15 @@ void add_@global_object_snake_name@_exposed_interfaces(JS::Object& global)
     for (auto& interface : exposed_interfaces) {
         auto gen = generator.fork();
 
-        if (interface.is_namespace)
+        if (interface.is_namespace) {
             add_namespace(gen, interface.name, interface.namespace_class);
-        else if (!interface.extended_attributes.contains("LegacyNamespace"sv))
-            add_interface(gen, interface.namespaced_name, interface.prototype_class, lookup_legacy_constructor(interface));
+        } else if (!interface.extended_attributes.contains("LegacyNamespace"sv)) {
+            if (class_name == "Window") {
+                add_interface(gen, interface.namespaced_name, interface.prototype_class, lookup_legacy_constructor(interface), interface.extended_attributes.get("LegacyWindowAlias"sv));
+            } else {
+                add_interface(gen, interface.namespaced_name, interface.prototype_class, lookup_legacy_constructor(interface), {});
+            }
+        }
     }
 
     generator.append(R"~~~(
@@ -389,7 +410,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
     VERIFY(!paths.is_empty());
     VERIFY(!base_path.is_empty());
 
-    const LexicalPath lexical_base(base_path);
+    LexicalPath const lexical_base(base_path);
 
     // Read in all IDL files, we must own the storage for all of these for the lifetime of the program
     Vector<ByteString> file_contents;

+ 5 - 0
Tests/LibWeb/Text/expected/geometry/legacy-window-alias.txt

@@ -0,0 +1,5 @@
+1. true
+2. {"a":1,"b":0,"c":0,"d":1,"e":0,"f":0,"m11":1,"m12":0,"m13":0,"m14":0,"m21":0,"m22":1,"m23":0,"m24":0,"m31":0,"m32":0,"m33":1,"m34":0,"m41":0,"m42":0,"m43":0,"m44":1,"is2D":true,"isIdentity":true}
+3. true
+4. true
+5. "[object DOMMatrix]"

+ 33 - 0
Tests/LibWeb/Text/input/geometry/legacy-window-alias.html

@@ -0,0 +1,33 @@
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        let testCounter = 1;
+        function testPart(part) {
+            println(`${testCounter++}. ${JSON.stringify(part())}`);
+        }
+
+        // 1. Compare constructors
+        testPart(() => WebKitCSSMatrix === DOMMatrix);
+
+        // 2. Use alias constructor
+        testPart(() => new WebKitCSSMatrix());
+
+        // 3. Check alias constructor
+        testPart(() => {
+            const m = new WebKitCSSMatrix();
+            return m.constructor === DOMMatrix;
+        });
+
+        // 4. Check constructor for alias
+        testPart(() => {
+            const m = new DOMMatrix();
+            return m.constructor === WebKitCSSMatrix;
+        });
+
+        // 5. Stringify alias constructor
+        testPart(() => {
+            const m = new WebKitCSSMatrix();
+            return {}.toString.call(m);
+        });
+    });
+</script>

+ 0 - 1
Userland/Libraries/LibWeb/Geometry/DOMMatrix.idl

@@ -1,7 +1,6 @@
 #import <Geometry/DOMMatrixReadOnly.idl>
 
 // https://drafts.fxtf.org/geometry/#dommatrix
-// FIXME: LegacyWindowAlias currently doesn't do anything.
 [Exposed=(Window,Worker), Serializable, LegacyWindowAlias=(SVGMatrix, WebKitCSSMatrix)]
 interface DOMMatrix : DOMMatrixReadOnly {
     constructor(optional (DOMString or sequence<unrestricted double>) init);