summaryrefslogtreecommitdiff
path: root/dom/bindings/parser
diff options
context:
space:
mode:
authorGaming4JC <g4jc@hyperbola.info>2020-01-02 21:25:47 -0500
committerGaming4JC <g4jc@hyperbola.info>2020-01-26 15:50:09 -0500
commit5222f6e9daa4cb74b404f769b23510b3d600efd9 (patch)
treee00a760b5b662dcfb35e2849ea1e9d83c85617e2 /dom/bindings/parser
parent244277a3fa428b70ba46cf611dbe1905733515eb (diff)
downloaduxp-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.py29
-rw-r--r--dom/bindings/parser/tests/test_constructor.py166
-rw-r--r--dom/bindings/parser/tests/test_constructor_no_interface_object.py33
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