浏览代码

IDLGenerators: Set reflected unsigned long value according to spec

Setting an unsigned long attribute with IDL to a value outside the
range 0 to 2147483647, the value should be set to the default value.
Tim Ledbetter 7 月之前
父节点
当前提交
e5c99b475a

+ 16 - 0
Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp

@@ -3833,6 +3833,22 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
         impl->remove_attribute(HTML::AttributeNames::@attribute.reflect_name@);
         impl->remove_attribute(HTML::AttributeNames::@attribute.reflect_name@);
     else
     else
         MUST(impl->set_attribute(HTML::AttributeNames::@attribute.reflect_name@, String {}));
         MUST(impl->set_attribute(HTML::AttributeNames::@attribute.reflect_name@, String {}));
+)~~~");
+                } else if (attribute.type->name() == "unsigned long") {
+                    // The setter steps are:
+                    // FIXME: 1. If the reflected IDL attribute is limited to only positive numbers and the given value is 0, then throw an "IndexSizeError" DOMException.
+                    // 2. Let minimum be 0.
+                    // FIXME: 3. If the reflected IDL attribute is limited to only positive numbers or limited to only positive numbers with fallback, then set minimum to 1.
+                    // 4. Let newValue be minimum.
+                    // FIXME: 5. If the reflected IDL attribute has a default value, then set newValue to defaultValue.
+                    // 6. If the given value is in the range minimum to 2147483647, inclusive, then set newValue to it.
+                    // 7. Run this's set the content attribute with newValue converted to the shortest possible string representing the number as a valid non-negative integer.
+                    attribute_generator.append(R"~~~(
+    u32 minimum = 0;
+    u32 new_value = minimum;
+    if (cpp_value >= minimum && cpp_value <= 2147483647)
+        new_value = cpp_value;
+    MUST(impl->set_attribute(HTML::AttributeNames::@attribute.reflect_name@, String::number(new_value)));
 )~~~");
 )~~~");
                 } else if (attribute.type->is_integer() && !attribute.type->is_nullable()) {
                 } else if (attribute.type->is_integer() && !attribute.type->is_nullable()) {
                     attribute_generator.append(R"~~~(
                     attribute_generator.append(R"~~~(

+ 16 - 0
Tests/LibWeb/Text/expected/HTML/unsigned-long-reflection.txt

@@ -0,0 +1,16 @@
+img.getAttribute("hspace") after img.setAttribute("hspace", "1"): 1
+img.hspace after img.setAttribute("hspace", "1"): 1
+img.getAttribute("hspace") after img.hspace = 1: 1
+img.hspace after img.hspace = 1: 1
+img.getAttribute("hspace") after img.setAttribute("hspace", "2147483647"): 2147483647
+img.hspace after img.setAttribute("hspace", "2147483647"): 2147483647
+img.getAttribute("hspace") after img.hspace = 2147483647: 2147483647
+img.hspace after img.hspace = 2147483647: 2147483647
+img.getAttribute("hspace") after img.setAttribute("hspace", "2147483648"): 2147483648
+img.hspace after img.setAttribute("hspace", "2147483648"): 0
+img.getAttribute("hspace") after img.hspace = 2147483648: 0
+img.hspace after img.hspace = 2147483648: 0
+img.getAttribute("hspace") after img.setAttribute("hspace", "4294967295"): 4294967295
+img.hspace after img.setAttribute("hspace", "4294967295"): 0
+img.getAttribute("hspace") after img.hspace = 4294967295: 0
+img.hspace after img.hspace = 4294967295: 0

+ 27 - 0
Tests/LibWeb/Text/input/HTML/unsigned-long-reflection.html

@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        function testProperty(elementName, propertyName, propertyGetter, propertySetter) {
+            const attributeName = propertyName.toLowerCase();
+            function setValue(value) {
+                let element = document.createElement(elementName);
+                element.setAttribute(attributeName, value.toString());
+                println(`${elementName}.getAttribute("${attributeName}") after ${elementName}.setAttribute("${propertyName}", "${value}"): ${element.getAttribute(`${attributeName}`)}`);
+                println(`${elementName}.${propertyName} after ${elementName}.setAttribute("${attributeName}", "${value}"): ${propertyGetter(element)}`);
+
+                element = document.createElement(elementName);
+                propertySetter(element, value);
+                println(`${elementName}.getAttribute("${attributeName}") after ${elementName}.${propertyName} = ${value}: ${element.getAttribute(attributeName)}`);
+                println(`${elementName}.${propertyName} after ${elementName}.${propertyName} = ${value}: ${propertyGetter(element)}`);
+            }
+
+            setValue(1);
+            setValue(2147483647);
+            setValue(2147483648);
+            setValue(4294967295);
+        }
+
+        testProperty("img", "hspace", (img) => img.hspace, (img, value) => img.hspace = value);
+    });
+</script>