diff options
author | Gaming4JC <g4jc@hyperbola.info> | 2020-01-02 21:25:47 -0500 |
---|---|---|
committer | Gaming4JC <g4jc@hyperbola.info> | 2020-01-26 15:50:09 -0500 |
commit | 5222f6e9daa4cb74b404f769b23510b3d600efd9 (patch) | |
tree | e00a760b5b662dcfb35e2849ea1e9d83c85617e2 /dom/bindings/parser | |
parent | 244277a3fa428b70ba46cf611dbe1905733515eb (diff) | |
download | uxp-5222f6e9daa4cb74b404f769b23510b3d600efd9.tar.gz |
Bug 1274159 - Part 2-2: Support HTMLConstructor WebIDL extended attribute for custom elements;
Tag UXP Issue #1344
Diffstat (limited to 'dom/bindings/parser')
-rw-r--r-- | dom/bindings/parser/WebIDL.py | 29 | ||||
-rw-r--r-- | dom/bindings/parser/tests/test_constructor.py | 166 | ||||
-rw-r--r-- | dom/bindings/parser/tests/test_constructor_no_interface_object.py | 33 |
3 files changed, 222 insertions, 6 deletions
diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 4f602365b1..a89620a9f3 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -1582,7 +1582,7 @@ class IDLInterface(IDLInterfaceOrNamespace): [self.location]) self._noInterfaceObject = True - elif identifier == "Constructor" or identifier == "NamedConstructor" or identifier == "ChromeConstructor": + elif identifier == "Constructor" or identifier == "NamedConstructor" or identifier == "ChromeConstructor" or identifier == "HTMLConstructor": if identifier == "Constructor" and not self.hasInterfaceObject(): raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible", [self.location]) @@ -1595,11 +1595,20 @@ class IDLInterface(IDLInterfaceOrNamespace): raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible", [self.location]) + if identifier == "HTMLConstructor": + if not self.hasInterfaceObject(): + raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible", + [self.location]) + + if not attr.noArguments(): + raise WebIDLError(str(identifier) + " must take no arguments", + [attr.location]) + args = attr.args() if attr.hasArgs() else [] retType = IDLWrapperType(self.location, self) - if identifier == "Constructor" or identifier == "ChromeConstructor": + if identifier == "Constructor" or identifier == "ChromeConstructor" or identifier == "HTMLConstructor": name = "constructor" allowForbidden = True else: @@ -1610,7 +1619,8 @@ class IDLInterface(IDLInterfaceOrNamespace): allowForbidden=allowForbidden) method = IDLMethod(self.location, methodIdentifier, retType, - args, static=True) + args, static=True, + htmlConstructor=(identifier == "HTMLConstructor")) # Constructors are always NewObject and are always # assumed to be able to throw (since there's no way to # indicate otherwise) and never have any other @@ -1622,7 +1632,7 @@ class IDLInterface(IDLInterfaceOrNamespace): method.addExtendedAttributes( [IDLExtendedAttribute(self.location, ("ChromeOnly",))]) - if identifier == "Constructor" or identifier == "ChromeConstructor": + if identifier == "Constructor" or identifier == "ChromeConstructor" or identifier == "HTMLConstructor": method.resolve(self) else: # We need to detect conflicts for NamedConstructors across @@ -4537,7 +4547,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope): static=False, getter=False, setter=False, creator=False, deleter=False, specialType=NamedOrIndexed.Neither, legacycaller=False, stringifier=False, jsonifier=False, - maplikeOrSetlikeOrIterable=None): + maplikeOrSetlikeOrIterable=None, htmlConstructor=False): # REVIEW: specialType is NamedOrIndexed -- wow, this is messed up. IDLInterfaceMember.__init__(self, location, identifier, IDLInterfaceMember.Tags.Method) @@ -4567,6 +4577,10 @@ class IDLMethod(IDLInterfaceMember, IDLScope): self._jsonifier = jsonifier assert maplikeOrSetlikeOrIterable is None or isinstance(maplikeOrSetlikeOrIterable, IDLMaplikeOrSetlikeOrIterableBase) self.maplikeOrSetlikeOrIterable = maplikeOrSetlikeOrIterable + assert isinstance(htmlConstructor, bool) + # The identifier of a HTMLConstructor must be 'constructor'. + assert not htmlConstructor or identifier.name == "constructor" + self._htmlConstructor = htmlConstructor self._specialType = specialType self._unforgeable = False self.dependsOn = "Everything" @@ -4667,6 +4681,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope): self.isStringifier() or self.isJsonifier()) + def isHTMLConstructor(self): + return self._htmlConstructor + def hasOverloads(self): return self._hasOverloads @@ -4722,6 +4739,8 @@ class IDLMethod(IDLInterfaceMember, IDLScope): assert not method.isStringifier() assert not self.isJsonifier() assert not method.isJsonifier() + assert not self.isHTMLConstructor() + assert not method.isHTMLConstructor() return self diff --git a/dom/bindings/parser/tests/test_constructor.py b/dom/bindings/parser/tests/test_constructor.py index 348204c7dc..fb651c08d2 100644 --- a/dom/bindings/parser/tests/test_constructor.py +++ b/dom/bindings/parser/tests/test_constructor.py @@ -13,7 +13,7 @@ def WebIDLTest(parser, harness): def checkMethod(method, QName, name, signatures, static=True, getter=False, setter=False, creator=False, deleter=False, legacycaller=False, stringifier=False, - chromeOnly=False): + chromeOnly=False, htmlConstructor=False): harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") harness.ok(method.isMethod(), "Method is a method") @@ -29,6 +29,7 @@ def WebIDLTest(parser, harness): harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value") harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value") harness.check(method.getExtendedAttribute("ChromeOnly") is not None, chromeOnly, "Method has the correct value for ChromeOnly") + harness.check(method.isHTMLConstructor(), htmlConstructor, "Method has the correct htmlConstructor value") harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures") sigpairs = zip(method.signatures(), signatures) @@ -80,6 +81,21 @@ def WebIDLTest(parser, harness): parser = parser.reset() parser.parse(""" + [HTMLConstructor] + interface TestHTMLConstructor { + }; + """) + results = parser.finish() + harness.check(len(results), 1, "Should be one production") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), + "Should be an IDLInterface") + + checkMethod(results[0].ctor(), "::TestHTMLConstructor::constructor", + "constructor", [("TestHTMLConstructor (Wrapper)", [])], + htmlConstructor=True) + + parser = parser.reset() + parser.parse(""" [ChromeConstructor()] interface TestChromeConstructor { }; @@ -107,3 +123,151 @@ def WebIDLTest(parser, harness): threw = True harness.ok(threw, "Can't have both a Constructor and a ChromeConstructor") + + # Test HTMLConstructor with argument + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor(DOMString a)] + interface TestHTMLConstructorWithArgs { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "HTMLConstructor should take no argument") + + # Test HTMLConstructor on a callback interface + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor] + callback interface TestHTMLConstructorOnCallbackInterface { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "HTMLConstructor can't be used on a callback interface") + + # Test HTMLConstructor and Constructor + parser = parser.reset() + threw = False + try: + parser.parse(""" + [Constructor, + HTMLConstructor] + interface TestHTMLConstructorAndConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Can't have both a Constructor and a HTMLConstructor") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor, + Constructor] + interface TestHTMLConstructorAndConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor, + Constructor(DOMString a)] + interface TestHTMLConstructorAndConstructor { + }; + """) + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [Constructor(DOMString a), + HTMLConstructor] + interface TestHTMLConstructorAndConstructor { + }; + """) + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor") + + # Test HTMLConstructor and ChromeConstructor + parser = parser.reset() + threw = False + try: + parser.parse(""" + [ChromeConstructor, + HTMLConstructor] + interface TestHTMLConstructorAndChromeConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor, + ChromeConstructor] + interface TestHTMLConstructorAndChromeConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [ChromeConstructor(DOMString a), + HTMLConstructor] + interface TestHTMLConstructorAndChromeConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor, + ChromeConstructor(DOMString a)] + interface TestHTMLConstructorAndChromeConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor")
\ No newline at end of file diff --git a/dom/bindings/parser/tests/test_constructor_no_interface_object.py b/dom/bindings/parser/tests/test_constructor_no_interface_object.py index 2b09ae71e6..af7b73d67f 100644 --- a/dom/bindings/parser/tests/test_constructor_no_interface_object.py +++ b/dom/bindings/parser/tests/test_constructor_no_interface_object.py @@ -34,3 +34,36 @@ def WebIDLTest(parser, harness): interface TestNamedConstructorNoInterfaceObject { }; """) + + # Test HTMLConstructor and NoInterfaceObject + parser = parser.reset() + + threw = False + try: + parser.parse(""" + [NoInterfaceObject, HTMLConstructor] + interface TestHTMLConstructorNoInterfaceObject { + }; + """) + + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Should have thrown.") + + parser = parser.reset() + + threw = False + try: + parser.parse(""" + [HTMLConstructor, NoInterfaceObject] + interface TestHTMLConstructorNoInterfaceObject { + }; + """) + + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Should have thrown.")
\ No newline at end of file |