mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 04:15:43 +00:00
Bug 798151. Support stringifier operations (but not yet attributes!) on non-proxy bindings, and fix Object.prototype.toString for proxy bindings. r=peterv
This commit is contained in:
parent
800cb6581d
commit
e435c28e4e
@ -153,6 +153,11 @@ function testClassList(e) {
|
||||
|
||||
// [Stringifies]
|
||||
|
||||
ok(DOMTokenList.prototype.hasOwnProperty("toString"),
|
||||
"Should have own toString on DOMTokenList")
|
||||
ok(!DOMSettableTokenList.prototype.hasOwnProperty("toString"),
|
||||
"Should not have own toString on DOMSettableTokenList")
|
||||
|
||||
e.removeAttribute("class");
|
||||
is(e.classList.toString(), "", "wrong classList.toString() value");
|
||||
is(e.classList + "", "", "wrong classList string conversion value");
|
||||
|
@ -1038,6 +1038,19 @@ class MethodDefiner(PropertyDefiner):
|
||||
"flags": "0",
|
||||
"pref": None })
|
||||
|
||||
if not static:
|
||||
stringifier = descriptor.operations['Stringifier']
|
||||
if stringifier:
|
||||
toStringDesc = { "name": "toString",
|
||||
"nativeName": stringifier.identifier.name,
|
||||
"length": 0,
|
||||
"flags": "JSPROP_ENUMERATE",
|
||||
"pref": PropertyDefiner.getControllingPref(stringifier) }
|
||||
if isChromeOnly(stringifier):
|
||||
self.chrome.append(toStringDesc)
|
||||
else:
|
||||
self.regular.append(toStringDesc)
|
||||
|
||||
if static:
|
||||
if not descriptor.interface.hasInterfaceObject():
|
||||
# static methods go on the interface object
|
||||
@ -1055,12 +1068,12 @@ class MethodDefiner(PropertyDefiner):
|
||||
return m["pref"]
|
||||
|
||||
def specData(m):
|
||||
accessor = m.get("nativeName", m["name"])
|
||||
if m.get("methodInfo", True):
|
||||
jitinfo = ("&%s_methodinfo" % m["name"])
|
||||
jitinfo = ("&%s_methodinfo" % accessor)
|
||||
accessor = "genericMethod"
|
||||
else:
|
||||
jitinfo = "nullptr"
|
||||
accessor = m.get("nativeName", m["name"])
|
||||
return (m["name"], accessor, jitinfo, m["length"], m["flags"])
|
||||
|
||||
return self.generatePrefableArray(
|
||||
@ -5100,26 +5113,6 @@ class CGDOMJSProxyHandler_obj_toString(ClassMethod):
|
||||
ClassMethod.__init__(self, "obj_toString", "JSString*", args)
|
||||
self.descriptor = descriptor
|
||||
def getBody(self):
|
||||
stringifier = self.descriptor.operations['Stringifier']
|
||||
if stringifier:
|
||||
name = stringifier.identifier.name
|
||||
nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
|
||||
signature = stringifier.signatures()[0]
|
||||
returnType = signature[0]
|
||||
extendedAttributes = self.descriptor.getExtendedAttributes(stringifier)
|
||||
infallible = 'infallible' in extendedAttributes
|
||||
if not infallible:
|
||||
error = CGGeneric(
|
||||
('ThrowMethodFailedWithDetails(cx, rv, "%s", "toString");\n' +
|
||||
"return NULL;") % self.descriptor.interface.identifier.name)
|
||||
else:
|
||||
error = None
|
||||
call = CGCallGenerator(error, [], "", returnType, extendedAttributes, self.descriptor, nativeName, False, object="UnwrapProxy(proxy)")
|
||||
return call.define() + """
|
||||
|
||||
JSString* jsresult;
|
||||
return xpc_qsStringToJsstring(cx, result, &jsresult) ? jsresult : NULL;"""
|
||||
|
||||
return "return mozilla::dom::DOMProxyHandler::obj_toString(cx, \"%s\");" % self.descriptor.name
|
||||
|
||||
class CGDOMJSProxyHandler_finalize(ClassMethod):
|
||||
@ -5232,7 +5225,8 @@ class CGDescriptor(CGThing):
|
||||
(hasMethod, hasGetter, hasLenientGetter,
|
||||
hasSetter, hasLenientSetter) = False, False, False, False, False
|
||||
for m in descriptor.interface.members:
|
||||
if m.isMethod() and not m.isStatic() and not m.isIdentifierLess():
|
||||
if (m.isMethod() and not m.isStatic() and
|
||||
(not m.isIdentifierLess() or m == descriptor.operations['Stringifier'])):
|
||||
cgThings.append(CGSpecializedMethod(descriptor, m))
|
||||
cgThings.append(CGMemberJITInfo(descriptor, m))
|
||||
hasMethod = True
|
||||
|
@ -190,28 +190,33 @@ class Descriptor(DescriptorProvider):
|
||||
self.concrete = (not self.interface.isExternal() and
|
||||
not self.interface.isCallback() and
|
||||
desc.get('concrete', True))
|
||||
operations = {
|
||||
'IndexedGetter': None,
|
||||
'IndexedSetter': None,
|
||||
'IndexedCreator': None,
|
||||
'IndexedDeleter': None,
|
||||
'NamedGetter': None,
|
||||
'NamedSetter': None,
|
||||
'NamedCreator': None,
|
||||
'NamedDeleter': None,
|
||||
'Stringifier': None
|
||||
}
|
||||
if self.concrete:
|
||||
self.proxy = False
|
||||
operations = {
|
||||
'IndexedGetter': None,
|
||||
'IndexedSetter': None,
|
||||
'IndexedCreator': None,
|
||||
'IndexedDeleter': None,
|
||||
'NamedGetter': None,
|
||||
'NamedSetter': None,
|
||||
'NamedCreator': None,
|
||||
'NamedDeleter': None,
|
||||
'Stringifier': None
|
||||
}
|
||||
iface = self.interface
|
||||
def addOperation(operation, m):
|
||||
if not operations[operation]:
|
||||
operations[operation] = m
|
||||
# Since stringifiers go on the prototype, we only need to worry
|
||||
# about our own stringifier, not those of our ancestor interfaces.
|
||||
for m in iface.members:
|
||||
if m.isMethod() and m.isStringifier():
|
||||
addOperation('Stringifier', m)
|
||||
while iface:
|
||||
for m in iface.members:
|
||||
if not m.isMethod():
|
||||
continue
|
||||
|
||||
def addOperation(operation, m):
|
||||
if not operations[operation]:
|
||||
operations[operation] = m
|
||||
def addIndexedOrNamedOperation(operation, m):
|
||||
self.proxy = True
|
||||
if m.isIndexed():
|
||||
@ -220,31 +225,28 @@ class Descriptor(DescriptorProvider):
|
||||
assert m.isNamed()
|
||||
operation = 'Named' + operation
|
||||
addOperation(operation, m)
|
||||
|
||||
if m.isStringifier():
|
||||
addOperation('Stringifier', m)
|
||||
else:
|
||||
if m.isGetter():
|
||||
addIndexedOrNamedOperation('Getter', m)
|
||||
if m.isSetter():
|
||||
addIndexedOrNamedOperation('Setter', m)
|
||||
if m.isCreator():
|
||||
addIndexedOrNamedOperation('Creator', m)
|
||||
if m.isDeleter():
|
||||
addIndexedOrNamedOperation('Deleter', m)
|
||||
raise TypeError("deleter specified on %s but we "
|
||||
"don't support deleters yet" %
|
||||
self.interface.identifier.name)
|
||||
|
||||
if m.isGetter():
|
||||
addIndexedOrNamedOperation('Getter', m)
|
||||
if m.isSetter():
|
||||
addIndexedOrNamedOperation('Setter', m)
|
||||
if m.isCreator():
|
||||
addIndexedOrNamedOperation('Creator', m)
|
||||
if m.isDeleter():
|
||||
addIndexedOrNamedOperation('Deleter', m)
|
||||
raise TypeError("deleter specified on %s but we "
|
||||
"don't support deleters yet" %
|
||||
self.interface.identifier.name)
|
||||
|
||||
iface.setUserData('hasConcreteDescendant', True)
|
||||
iface = iface.parent
|
||||
|
||||
if self.proxy:
|
||||
self.operations = operations
|
||||
iface = self.interface
|
||||
while iface:
|
||||
iface.setUserData('hasProxyDescendant', True)
|
||||
iface = iface.parent
|
||||
self.operations = operations
|
||||
|
||||
if self.interface.isExternal() and 'prefable' in desc:
|
||||
raise TypeError("%s is external but has a prefable setting" %
|
||||
|
@ -447,6 +447,5 @@
|
||||
"DOMStringList interface: existence and properties of interface object": true,
|
||||
"DOMStringList interface: existence and properties of interface prototype object": true,
|
||||
"DOMStringList interface: existence and properties of interface prototype object's \"constructor\" property": true,
|
||||
"DOMStringList interface: attribute length": true,
|
||||
"Stringification of document.body.classList": true
|
||||
"DOMStringList interface: attribute length": true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user