auto merge of #5208 : Ms2ger/servo/USVString, r=jdm

This commit is contained in:
bors-servo 2015-03-13 14:30:49 -06:00
commit 19cd87aefc
14 changed files with 477 additions and 151 deletions

View file

@ -419,7 +419,8 @@ def typeIsSequenceOrHasSequenceMember(type):
return False
def typeNeedsRooting(type, descriptorProvider):
return type.isGeckoInterface() and descriptorProvider.getDescriptor(type.name).needsRooting
return (type.isGeckoInterface() and
descriptorProvider.getDescriptor(type.unroll().inner.identifier.name).needsRooting)
def union_native_type(t):
@ -716,6 +717,32 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
return handleOptional(conversionCode, CGGeneric(declType), default)
if type.isUSVString():
assert not isEnforceRange and not isClamp
conversionCode = (
"match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n"
" Ok(strval) => strval,\n"
" Err(_) => { %s },\n"
"}" % exceptionCode)
if defaultValue is None:
default = None
elif isinstance(defaultValue, IDLNullValue):
assert type.nullable()
default = "None"
else:
assert defaultValue.type.tag() in (IDLType.Tags.domstring, IDLType.Tags.usvstring)
default = 'USVString("%s".to_owned())' % defaultValue.value
if type.nullable():
default = "Some(%s)" % default
declType = "USVString"
if type.nullable():
declType = "Option<%s>" % declType
return handleOptional(conversionCode, CGGeneric(declType), default)
if type.isByteString():
assert not isEnforceRange and not isClamp
@ -1085,6 +1112,11 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
if returnType.nullable():
result = CGWrapper(result, pre="Option<", post=">")
return result
if returnType.isUSVString():
result = CGGeneric("USVString")
if returnType.nullable():
result = CGWrapper(result, pre="Option<", post=">")
return result
if returnType.isByteString():
result = CGGeneric("ByteString")
if returnType.nullable():
@ -4646,6 +4678,7 @@ class CGBindingRoot(CGThing):
'dom::bindings::proxyhandler::{fill_property_descriptor, get_expando_object}',
'dom::bindings::proxyhandler::{get_property_descriptor}',
'dom::bindings::str::ByteString',
'dom::bindings::str::USVString',
'libc',
'util::str::DOMString',
'std::borrow::ToOwned',

View file

@ -204,7 +204,7 @@ class IDLObject(object):
deps.add(self.filename())
for d in self._getDependentObjects():
deps = deps.union(d.getDeps(visited))
deps.update(d.getDeps(visited))
return deps
@ -338,7 +338,10 @@ class IDLUnresolvedIdentifier(IDLObject):
assert len(name) > 0
if name[:2] == "__" and name != "__content" and name != "___noSuchMethod__" and not allowDoubleUnderscore:
if name == "__noSuchMethod__":
raise WebIDLError("__noSuchMethod__ is deprecated", [location])
if name[:2] == "__" and name != "__content" and not allowDoubleUnderscore:
raise WebIDLError("Identifiers beginning with __ are reserved",
[location])
if name[0] == '_' and not allowDoubleUnderscore:
@ -448,7 +451,59 @@ class IDLIdentifierPlaceholder(IDLObjectWithIdentifier):
obj = self.identifier.resolve(scope, None)
return scope.lookupIdentifier(obj)
class IDLExternalInterface(IDLObjectWithIdentifier):
class IDLExposureMixins():
def __init__(self, location):
# _exposureGlobalNames are the global names listed in our [Exposed]
# extended attribute. exposureSet is the exposure set as defined in the
# Web IDL spec: it contains interface names.
self._exposureGlobalNames = set()
self.exposureSet = set()
self._location = location
self._globalScope = None
def finish(self, scope):
assert scope.parentScope is None
self._globalScope = scope
# Verify that our [Exposed] value, if any, makes sense.
for globalName in self._exposureGlobalNames:
if globalName not in scope.globalNames:
raise WebIDLError("Unknown [Exposed] value %s" % globalName,
[self._location])
if len(self._exposureGlobalNames) == 0:
self._exposureGlobalNames.add(scope.primaryGlobalName)
globalNameSetToExposureSet(scope, self._exposureGlobalNames,
self.exposureSet)
def isExposedInWindow(self):
return 'Window' in self.exposureSet
def isExposedInAnyWorker(self):
return len(self.getWorkerExposureSet()) > 0
def isExposedInSystemGlobals(self):
return 'BackstagePass' in self.exposureSet
def isExposedInSomeButNotAllWorkers(self):
"""
Returns true if the Exposed extended attribute for this interface
exposes it in some worker globals but not others. The return value does
not depend on whether the interface is exposed in Window or System
globals.
"""
if not self.isExposedInAnyWorker():
return False
workerScopes = self.parentScope.globalNameMapping["Worker"]
return len(workerScopes.difference(self.exposureSet)) > 0
def getWorkerExposureSet(self):
workerScopes = self._globalScope.globalNameMapping["Worker"]
return workerScopes.intersection(self.exposureSet)
class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
def __init__(self, location, parentScope, identifier):
raise WebIDLError("Servo does not support external interfaces.",
[self.location])
@ -511,7 +566,7 @@ def globalNameSetToExposureSet(globalScope, nameSet, exposureSet):
for name in nameSet:
exposureSet.update(globalScope.globalNameMapping[name])
class IDLInterface(IDLObjectWithScope):
class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
def __init__(self, location, parentScope, name, parent, members,
isKnownNonPartial):
assert isinstance(parentScope, IDLScope)
@ -546,13 +601,9 @@ class IDLInterface(IDLObjectWithScope):
self.totalMembersInSlots = 0
# Tracking of the number of own own members we have in slots
self._ownMembersInSlots = 0
# _exposureGlobalNames are the global names listed in our [Exposed]
# extended attribute. exposureSet is the exposure set as defined in the
# Web IDL spec: it contains interface names.
self._exposureGlobalNames = set()
self.exposureSet = set()
IDLObjectWithScope.__init__(self, location, parentScope, name)
IDLExposureMixins.__init__(self, location)
if isKnownNonPartial:
self.setNonPartial(location, parent, members)
@ -592,17 +643,7 @@ class IDLInterface(IDLObjectWithScope):
"declaration" % self.identifier.name,
[self.location])
# Verify that our [Exposed] value, if any, makes sense.
for globalName in self._exposureGlobalNames:
if globalName not in scope.globalNames:
raise WebIDLError("Unknown [Exposed] value %s" % globalName,
[self.location])
if len(self._exposureGlobalNames) == 0:
self._exposureGlobalNames.add(scope.primaryGlobalName)
globalNameSetToExposureSet(scope, self._exposureGlobalNames,
self.exposureSet)
IDLExposureMixins.finish(self, scope)
# Now go ahead and merge in our partial interfaces.
for partial in self._partialInterfaces:
@ -681,6 +722,17 @@ class IDLInterface(IDLObjectWithScope):
self.parent.identifier.name),
[self.location, self.parent.location])
# Interfaces which have interface objects can't inherit
# from [NoInterfaceObject] interfaces.
if (self.parent.getExtendedAttribute("NoInterfaceObject") and
not self.getExtendedAttribute("NoInterfaceObject")):
raise WebIDLError("Interface %s does not have "
"[NoInterfaceObject] but inherits from "
"interface %s which does" %
(self.identifier.name,
self.parent.identifier.name),
[self.location, self.parent.location])
for iface in self.implementedInterfaces:
iface.finish(scope)
@ -718,9 +770,13 @@ class IDLInterface(IDLObjectWithScope):
ctor = self.ctor()
if ctor is not None:
assert len(ctor._exposureGlobalNames) == 0
ctor._exposureGlobalNames.update(self._exposureGlobalNames)
ctor.finish(scope)
for ctor in self.namedConstructors:
assert len(ctor._exposureGlobalNames) == 0
ctor._exposureGlobalNames.update(self._exposureGlobalNames)
ctor.finish(scope)
# Make a copy of our member list, so things that implement us
@ -921,10 +977,15 @@ class IDLInterface(IDLObjectWithScope):
list(i.location for i in
self.interfacesBasedOnSelf if i.parent == self))
for member in self.members:
member.validate()
if self.isCallback() and member.getExtendedAttribute("Replaceable"):
raise WebIDLError("[Replaceable] used on an attribute on "
"interface %s which is a callback interface" %
self.identifier.name,
[self.location, member.location])
# Check that PutForwards refers to another attribute and that no
# cycles exist in forwarded assignments.
if member.isAttr():
@ -966,10 +1027,25 @@ class IDLInterface(IDLObjectWithScope):
if (self.getExtendedAttribute("Pref") and
self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
raise WebIDLError("[Pref] used on an member that is not %s-only" %
raise WebIDLError("[Pref] used on an interface that is not %s-only" %
self.parentScope.primaryGlobalName,
[self.location])
if (self.getExtendedAttribute("CheckPermissions") and
self._exposureGlobalNames != set([self.parentScope.primaryGlobalName])):
raise WebIDLError("[CheckPermissions] used on an interface that is "
"not %s-only" %
self.parentScope.primaryGlobalName,
[self.location])
# Conditional exposure makes no sense for interfaces with no
# interface object, unless they're navigator properties.
if (self.isExposedConditionally() and
not self.hasInterfaceObject() and
not self.getNavigatorProperty()):
raise WebIDLError("Interface with no interface object is "
"exposed conditionally",
[self.location])
def isInterface(self):
return True
@ -1151,10 +1227,11 @@ class IDLInterface(IDLObjectWithScope):
self.parentScope.globalNames.add(self.identifier.name)
self.parentScope.globalNameMapping[self.identifier.name].add(self.identifier.name)
self._isOnGlobalProtoChain = True
elif (identifier == "NeedNewResolve" or
elif (identifier == "NeedResolve" or
identifier == "OverrideBuiltins" or
identifier == "ChromeOnly" or
identifier == "Unforgeable" or
identifier == "UnsafeInPrerendering" or
identifier == "LegacyEventInit"):
# Known extended attributes that do not take values
if not attr.noArguments():
@ -1284,7 +1361,7 @@ class IDLInterface(IDLObjectWithScope):
def _getDependentObjects(self):
deps = set(self.members)
deps.union(self.implementedInterfaces)
deps.update(self.implementedInterfaces)
if self.parent:
deps.add(self.parent)
return deps
@ -1292,6 +1369,13 @@ class IDLInterface(IDLObjectWithScope):
def hasMembersInSlots(self):
return self._ownMembersInSlots != 0
def isExposedConditionally(self):
return (self.getExtendedAttribute("Pref") or
self.getExtendedAttribute("ChromeOnly") or
self.getExtendedAttribute("Func") or
self.getExtendedAttribute("AvailableIn") or
self.getExtendedAttribute("CheckPermissions"))
class IDLDictionary(IDLObjectWithScope):
def __init__(self, location, parentScope, name, parent, members):
assert isinstance(parentScope, IDLScope)
@ -1486,7 +1570,7 @@ class IDLType(IDLObject):
'any',
'domstring',
'bytestring',
'scalarvaluestring',
'usvstring',
'object',
'date',
'void',
@ -1539,7 +1623,7 @@ class IDLType(IDLObject):
def isDOMString(self):
return False
def isScalarValueString(self):
def isUSVString(self):
return False
def isVoid(self):
@ -1688,7 +1772,10 @@ class IDLNullableType(IDLType):
assert not innerType.isVoid()
assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any]
IDLType.__init__(self, location, innerType.name)
name = innerType.name
if innerType.isComplete():
name += "OrNull"
IDLType.__init__(self, location, name)
self.inner = innerType
self.builtin = False
@ -1722,8 +1809,8 @@ class IDLNullableType(IDLType):
def isDOMString(self):
return self.inner.isDOMString()
def isScalarValueString(self):
return self.inner.isScalarValueString()
def isUSVString(self):
return self.inner.isUSVString()
def isFloat(self):
return self.inner.isFloat()
@ -1801,7 +1888,7 @@ class IDLNullableType(IDLType):
"be a union type that itself has a nullable "
"type as a member type", [self.location])
self.name = self.inner.name
self.name = self.inner.name + "OrNull"
return self
def unroll(self):
@ -1824,6 +1911,10 @@ class IDLSequenceType(IDLType):
IDLType.__init__(self, location, parameterType.name)
self.inner = parameterType
self.builtin = False
# Need to set self.name up front if our inner type is already complete,
# since in that case our .complete() won't be called.
if self.inner.isComplete():
self.name = self.inner.name + "Sequence"
def __eq__(self, other):
return isinstance(other, IDLSequenceType) and self.inner == other.inner
@ -1846,7 +1937,7 @@ class IDLSequenceType(IDLType):
def isDOMString(self):
return False
def isScalarValueString(self):
def isUSVString(self):
return False
def isVoid(self):
@ -1885,7 +1976,7 @@ class IDLSequenceType(IDLType):
def complete(self, scope):
self.inner = self.inner.complete(scope)
self.name = self.inner.name
self.name = self.inner.name + "Sequence"
return self
def unroll(self):
@ -1896,7 +1987,8 @@ class IDLSequenceType(IDLType):
# Just forward to the union; it'll deal
return other.isDistinguishableFrom(self)
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isDate() or other.isNonCallbackInterface() or other.isMozMap())
other.isDate() or other.isInterface() or other.isDictionary() or
other.isCallback() or other.isMozMap())
def _getDependentObjects(self):
return self.inner._getDependentObjects()
@ -1911,6 +2003,10 @@ class IDLMozMapType(IDLType):
IDLType.__init__(self, location, parameterType.name)
self.inner = parameterType
self.builtin = False
# Need to set self.name up front if our inner type is already complete,
# since in that case our .complete() won't be called.
if self.inner.isComplete():
self.name = self.inner.name + "MozMap"
def __eq__(self, other):
return isinstance(other, IDLMozMapType) and self.inner == other.inner
@ -1936,7 +2032,7 @@ class IDLMozMapType(IDLType):
def complete(self, scope):
self.inner = self.inner.complete(scope)
self.name = self.inner.name
self.name = self.inner.name + "MozMap"
return self
def unroll(self):
@ -1970,6 +2066,10 @@ class IDLUnionType(IDLType):
def __eq__(self, other):
return isinstance(other, IDLUnionType) and self.memberTypes == other.memberTypes
def __hash__(self):
assert self.isComplete()
return self.name.__hash__()
def isVoid(self):
return False
@ -2001,9 +2101,6 @@ class IDLUnionType(IDLType):
return typeName(type._identifier.object())
if isinstance(type, IDLObjectWithIdentifier):
return typeName(type.identifier)
if (isinstance(type, IDLType) and
(type.isArray() or type.isSequence() or type.isMozMap)):
return str(type)
return type.name
for (i, type) in enumerate(self.memberTypes):
@ -2114,7 +2211,7 @@ class IDLArrayType(IDLType):
def isDOMString(self):
return False
def isScalarValueString(self):
def isUSVString(self):
return False
def isVoid(self):
@ -2212,8 +2309,8 @@ class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
def isDOMString(self):
return self.inner.isDOMString()
def isScalarValueString(self):
return self.inner.isScalarValueString()
def isUSVString(self):
return self.inner.isUSVString()
def isVoid(self):
return self.inner.isVoid()
@ -2313,7 +2410,7 @@ class IDLWrapperType(IDLType):
def isDOMString(self):
return False
def isScalarValueString(self):
def isUSVString(self):
return False
def isVoid(self):
@ -2387,7 +2484,8 @@ class IDLWrapperType(IDLType):
other.isDate())
if self.isDictionary() and other.nullable():
return False
if other.isPrimitive() or other.isString() or other.isEnum() or other.isDate():
if (other.isPrimitive() or other.isString() or other.isEnum() or
other.isDate() or other.isSequence()):
return True
if self.isDictionary():
return other.isNonCallbackInterface()
@ -2405,7 +2503,7 @@ class IDLWrapperType(IDLType):
(self.isNonCallbackInterface() or
other.isNonCallbackInterface()))
if (other.isDictionary() or other.isCallback() or
other.isSequence() or other.isMozMap() or other.isArray()):
other.isMozMap() or other.isArray()):
return self.isNonCallbackInterface()
# Not much else |other| can be
@ -2441,6 +2539,13 @@ class IDLWrapperType(IDLType):
# Bindings.conf, which is still a global dependency.
# 2) Changing an interface to a dictionary (or vice versa) with the
# same identifier should be incredibly rare.
#
# On the other hand, if our type is a dictionary, we should
# depend on it, because the member types of a dictionary
# affect whether a method taking the dictionary as an argument
# takes a JSContext* argument or not.
if self.isDictionary():
return set([self.inner])
return set()
class IDLBuiltinType(IDLType):
@ -2466,7 +2571,7 @@ class IDLBuiltinType(IDLType):
'any',
'domstring',
'bytestring',
'scalarvaluestring',
'usvstring',
'object',
'date',
'void',
@ -2501,7 +2606,7 @@ class IDLBuiltinType(IDLType):
Types.any: IDLType.Tags.any,
Types.domstring: IDLType.Tags.domstring,
Types.bytestring: IDLType.Tags.bytestring,
Types.scalarvaluestring: IDLType.Tags.scalarvaluestring,
Types.usvstring: IDLType.Tags.usvstring,
Types.object: IDLType.Tags.object,
Types.date: IDLType.Tags.date,
Types.void: IDLType.Tags.void,
@ -2535,7 +2640,7 @@ class IDLBuiltinType(IDLType):
def isString(self):
return self._typeTag == IDLBuiltinType.Types.domstring or \
self._typeTag == IDLBuiltinType.Types.bytestring or \
self._typeTag == IDLBuiltinType.Types.scalarvaluestring
self._typeTag == IDLBuiltinType.Types.usvstring
def isByteString(self):
return self._typeTag == IDLBuiltinType.Types.bytestring
@ -2543,8 +2648,8 @@ class IDLBuiltinType(IDLType):
def isDOMString(self):
return self._typeTag == IDLBuiltinType.Types.domstring
def isScalarValueString(self):
return self._typeTag == IDLBuiltinType.Types.scalarvaluestring
def isUSVString(self):
return self._typeTag == IDLBuiltinType.Types.usvstring
def isInteger(self):
return self._typeTag <= IDLBuiltinType.Types.unsigned_long_long
@ -2698,9 +2803,9 @@ BuiltinTypes = {
IDLBuiltinType.Types.bytestring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "ByteString",
IDLBuiltinType.Types.bytestring),
IDLBuiltinType.Types.scalarvaluestring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "ScalarValueString",
IDLBuiltinType.Types.scalarvaluestring),
IDLBuiltinType.Types.usvstring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "USVString",
IDLBuiltinType.Types.usvstring),
IDLBuiltinType.Types.object:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Object",
IDLBuiltinType.Types.object),
@ -2835,10 +2940,10 @@ class IDLValue(IDLObject):
raise WebIDLError("Trying to convert unrestricted value %s to non-unrestricted"
% self.value, [location]);
return self
elif self.type.isString() and type.isScalarValueString():
# Allow ScalarValueStrings to use default value just like
elif self.type.isString() and type.isUSVString():
# Allow USVStrings to use default value just like
# DOMString. No coercion is required in this case as Codegen.py
# treats ScalarValueString just like DOMString, but with an
# treats USVString just like DOMString, but with an
# extra normalization step.
assert self.type.isDOMString()
return self
@ -2923,7 +3028,7 @@ class IDLUndefinedValue(IDLObject):
def _getDependentObjects(self):
return set()
class IDLInterfaceMember(IDLObjectWithIdentifier):
class IDLInterfaceMember(IDLObjectWithIdentifier, IDLExposureMixins):
Tags = enum(
'Const',
@ -2936,15 +3041,14 @@ class IDLInterfaceMember(IDLObjectWithIdentifier):
'Stringifier'
)
AffectsValues = ("Nothing", "Everything")
DependsOnValues = ("Nothing", "DOMState", "DeviceState", "Everything")
def __init__(self, location, identifier, tag):
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
IDLExposureMixins.__init__(self, location)
self.tag = tag
self._extendedAttrDict = {}
# _exposureGlobalNames are the global names listed in our [Exposed]
# extended attribute. exposureSet is the exposure set as defined in the
# Web IDL spec: it contains interface names.
self._exposureGlobalNames = set()
self.exposureSet = set()
def isMethod(self):
return self.tag == IDLInterfaceMember.Tags.Method
@ -2968,21 +3072,53 @@ class IDLInterfaceMember(IDLObjectWithIdentifier):
return self._extendedAttrDict.get(name, None)
def finish(self, scope):
for globalName in self._exposureGlobalNames:
if globalName not in scope.globalNames:
raise WebIDLError("Unknown [Exposed] value %s" % globalName,
[self.location])
globalNameSetToExposureSet(scope, self._exposureGlobalNames,
self.exposureSet)
self._scope = scope
# We better be exposed _somewhere_.
if (len(self._exposureGlobalNames) == 0):
print self.identifier.name
assert len(self._exposureGlobalNames) != 0
IDLExposureMixins.finish(self, scope)
def validate(self):
if (self.getExtendedAttribute("Pref") and
self.exposureSet != set([self._scope.primaryGlobalName])):
self.exposureSet != set([self._globalScope.primaryGlobalName])):
raise WebIDLError("[Pref] used on an interface member that is not "
"%s-only" % self._scope.primaryGlobalName,
"%s-only" % self._globalScope.primaryGlobalName,
[self.location])
if (self.getExtendedAttribute("CheckPermissions") and
self.exposureSet != set([self._globalScope.primaryGlobalName])):
raise WebIDLError("[CheckPermissions] used on an interface member "
"that is not %s-only" %
self._globalScope.primaryGlobalName,
[self.location])
if self.isAttr() or self.isMethod():
if self.affects == "Everything" and self.dependsOn != "Everything":
raise WebIDLError("Interface member is flagged as affecting "
"everything but not depending on everything. "
"That seems rather unlikely.",
[self.location])
def _setDependsOn(self, dependsOn):
if self.dependsOn != "Everything":
raise WebIDLError("Trying to specify multiple different DependsOn, "
"Pure, or Constant extended attributes for "
"attribute", [self.location])
if dependsOn not in IDLInterfaceMember.DependsOnValues:
raise WebIDLError("Invalid [DependsOn=%s] on attribute" % dependsOn,
[self.location])
self.dependsOn = dependsOn
def _setAffects(self, affects):
if self.affects != "Everything":
raise WebIDLError("Trying to specify multiple different Affects, "
"Pure, or Constant extended attributes for "
"attribute", [self.location])
if affects not in IDLInterfaceMember.AffectsValues:
raise WebIDLError("Invalid [Affects=%s] on attribute" % dependsOn,
[self.location])
self.affects = affects
class IDLConst(IDLInterfaceMember):
def __init__(self, location, identifier, type, value):
IDLInterfaceMember.__init__(self, location, identifier,
@ -3061,6 +3197,8 @@ class IDLAttribute(IDLInterfaceMember):
self.enforceRange = False
self.clamp = False
self.slotIndex = None
self.dependsOn = "Everything"
self.affects = "Everything"
if static and identifier.name == "prototype":
raise WebIDLError("The identifier of a static attribute must not be 'prototype'",
@ -3129,11 +3267,11 @@ class IDLAttribute(IDLInterfaceMember):
if ((self.getExtendedAttribute("Cached") or
self.getExtendedAttribute("StoreInSlot")) and
not self.getExtendedAttribute("Constant") and
not self.getExtendedAttribute("Pure")):
not self.affects == "Nothing"):
raise WebIDLError("Cached attributes and attributes stored in "
"slots must be constant or pure, since the "
"getter won't always be called.",
"slots must be Constant or Pure or "
"Affects=Nothing, since the getter won't always "
"be called.",
[self.location])
if self.getExtendedAttribute("Frozen"):
if (not self.type.isSequence() and not self.type.isDictionary() and
@ -3158,8 +3296,7 @@ class IDLAttribute(IDLInterfaceMember):
(identifier == "StoreInSlot" and
(self.getExtendedAttribute("Throws") or
self.getExtendedAttribute("GetterThrows")))):
raise WebIDLError("Throwing things can't be [Pure] or [Constant] "
"or [SameObject] or [StoreInSlot]",
raise WebIDLError("Throwing things can't be [StoreInSlot]",
[attr.location])
elif identifier == "LenientThis":
if not attr.noArguments():
@ -3203,6 +3340,15 @@ class IDLAttribute(IDLInterfaceMember):
raise WebIDLError("[PutForwards] takes an identifier",
[attr.location, self.location])
elif identifier == "Replaceable":
if not attr.noArguments():
raise WebIDLError("[Replaceable] must take no arguments",
[attr.location])
if not self.readonly:
raise WebIDLError("[Replaceable] is only allowed on readonly "
"attributes", [attr.location, self.location])
if self.isStatic():
raise WebIDLError("[Replaceable] is only allowed on non-static "
"attributes", [attr.location, self.location])
if self.getExtendedAttribute("PutForwards") is not None:
raise WebIDLError("[PutForwards] and [Replaceable] can't both "
"appear on the same attribute",
@ -3250,18 +3396,43 @@ class IDLAttribute(IDLInterfaceMember):
[attr.location, self.location])
elif identifier == "Exposed":
convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames)
elif identifier == "Pure":
if not attr.noArguments():
raise WebIDLError("[Pure] must take no arguments",
[attr.location])
self._setDependsOn("DOMState")
self._setAffects("Nothing")
elif identifier == "Constant" or identifier == "SameObject":
if not attr.noArguments():
raise WebIDLError("[%s] must take no arguments" % identifier,
[attr.location])
self._setDependsOn("Nothing")
self._setAffects("Nothing")
elif identifier == "Affects":
if not attr.hasValue():
raise WebIDLError("[Affects] takes an identifier",
[attr.location])
self._setAffects(attr.value())
elif identifier == "DependsOn":
if not attr.hasValue():
raise WebIDLError("[DependsOn] takes an identifier",
[attr.location])
if (attr.value() != "Everything" and attr.value() != "DOMState" and
not self.readonly):
raise WebIDLError("[DependsOn=%s] only allowed on "
"readonly attributes" % attr.value(),
[attr.location, self.location])
self._setDependsOn(attr.value())
elif (identifier == "Pref" or
identifier == "SetterThrows" or
identifier == "Pure" or
identifier == "Throws" or
identifier == "GetterThrows" or
identifier == "ChromeOnly" or
identifier == "SameObject" or
identifier == "Constant" or
identifier == "Func" or
identifier == "Frozen" or
identifier == "AvailableIn" or
identifier == "NewObject" or
identifier == "UnsafeInPrerendering" or
identifier == "CheckPermissions" or
identifier == "BinaryName"):
# Known attributes that we don't need to do anything with here
@ -3306,6 +3477,7 @@ class IDLArgument(IDLObjectWithIdentifier):
self._allowTreatNonCallableAsNull = False
assert not variadic or optional
assert not variadic or not defaultValue
def addExtendedAttributes(self, attrs):
attrs = self.checkForStringHandlingExtendedAttributes(
@ -3354,9 +3526,9 @@ class IDLArgument(IDLObjectWithIdentifier):
if ((self.type.isDictionary() or
self.type.isUnion() and self.type.unroll().hasDictionaryType) and
self.optional and not self.defaultValue):
# Default optional dictionaries to null, for simplicity,
# so the codegen doesn't have to special-case this.
self.optional and not self.defaultValue and not self.variadic):
# Default optional non-variadic dictionaries to null,
# for simplicity, so the codegen doesn't have to special-case this.
self.defaultValue = IDLNullValue(self.location)
elif self.type.isAny():
assert (self.defaultValue is None or
@ -3383,6 +3555,9 @@ class IDLArgument(IDLObjectWithIdentifier):
deps.add(self.defaultValue)
return deps
def canHaveMissingValue(self):
return self.optional and not self.defaultValue
class IDLCallbackType(IDLType, IDLObjectWithScope):
def __init__(self, location, parentScope, identifier, returnType, arguments):
assert isinstance(returnType, IDLType)
@ -3442,7 +3617,8 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
# Just forward to the union; it'll deal
return other.isDistinguishableFrom(self)
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isNonCallbackInterface() or other.isDate())
other.isNonCallbackInterface() or other.isDate() or
other.isSequence())
def addExtendedAttributes(self, attrs):
unhandledAttrs = []
@ -3538,6 +3714,8 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
self._jsonifier = jsonifier
self._specialType = specialType
self._unforgeable = False
self.dependsOn = "Everything"
self.affects = "Everything"
if static and identifier.name == "prototype":
raise WebIDLError("The identifier of a static operation must not be 'prototype'",
@ -3618,7 +3796,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
return self._hasOverloads
def isIdentifierLess(self):
return self.identifier.name[:2] == "__" and self.identifier.name != "__noSuchMethod__"
return self.identifier.name[:2] == "__"
def resolve(self, parentScope):
assert isinstance(parentScope, IDLScope)
@ -3849,16 +4027,32 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
[attr.location, self.location])
elif identifier == "Exposed":
convertExposedAttrToGlobalNameSet(attr, self._exposureGlobalNames)
elif (identifier == "Pure" or
identifier == "CrossOriginCallable" or
elif (identifier == "CrossOriginCallable" or
identifier == "WebGLHandlesContextLoss"):
# Known no-argument attributes.
if not attr.noArguments():
raise WebIDLError("[%s] must take no arguments" % identifier,
[attr.location])
elif identifier == "Pure":
if not attr.noArguments():
raise WebIDLError("[Pure] must take no arguments",
[attr.location])
self._setDependsOn("DOMState")
self._setAffects("Nothing")
elif identifier == "Affects":
if not attr.hasValue():
raise WebIDLError("[Affects] takes an identifier",
[attr.location])
self._setAffects(attr.value())
elif identifier == "DependsOn":
if not attr.hasValue():
raise WebIDLError("[DependsOn] takes an identifier",
[attr.location])
self._setDependsOn(attr.value())
elif (identifier == "Throws" or
identifier == "NewObject" or
identifier == "ChromeOnly" or
identifier == "UnsafeInPrerendering" or
identifier == "Pref" or
identifier == "Func" or
identifier == "AvailableIn" or
@ -3880,7 +4074,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
def _getDependentObjects(self):
deps = set()
for overload in self._overloads:
deps.union(overload._getDependentObjects())
deps.update(overload._getDependentObjects())
return deps
class IDLImplementsStatement(IDLObject):
@ -3888,8 +4082,11 @@ class IDLImplementsStatement(IDLObject):
IDLObject.__init__(self, location)
self.implementor = implementor;
self.implementee = implementee
self._finished = False
def finish(self, scope):
if self._finished:
return
assert(isinstance(self.implementor, IDLIdentifierPlaceholder))
assert(isinstance(self.implementee, IDLIdentifierPlaceholder))
implementor = self.implementor.finish(scope)
@ -3914,6 +4111,8 @@ class IDLImplementsStatement(IDLObject):
"interface",
[self.implementee.location])
implementor.addImplementedInterface(implementee)
self.implementor = implementor
self.implementee = implementee
def validate(self):
pass
@ -4044,7 +4243,7 @@ class Tokenizer(object):
"Date": "DATE",
"DOMString": "DOMSTRING",
"ByteString": "BYTESTRING",
"ScalarValueString": "SCALARVALUESTRING",
"USVString": "USVSTRING",
"any": "ANY",
"boolean": "BOOLEAN",
"byte": "BYTE",
@ -4053,8 +4252,8 @@ class Tokenizer(object):
"long": "LONG",
"object": "OBJECT",
"octet": "OCTET",
"optional": "OPTIONAL",
"Promise": "PROMISE",
"required": "REQUIRED",
"sequence": "SEQUENCE",
"MozMap": "MOZMAP",
"short": "SHORT",
@ -4339,15 +4538,21 @@ class Parser(Tokenizer):
def p_DictionaryMember(self, p):
"""
DictionaryMember : Type IDENTIFIER Default SEMICOLON
DictionaryMember : Required Type IDENTIFIER Default SEMICOLON
"""
# These quack a lot like optional arguments, so just treat them that way.
t = p[1]
t = p[2]
assert isinstance(t, IDLType)
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
defaultValue = p[3]
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3])
defaultValue = p[4]
optional = not p[1]
p[0] = IDLArgument(self.getLocation(p, 2), identifier, t, optional=True,
if not optional and defaultValue:
raise WebIDLError("Required dictionary members can't have a default value.",
[self.getLocation(p, 4)])
p[0] = IDLArgument(self.getLocation(p, 3), identifier, t,
optional=optional,
defaultValue=defaultValue, variadic=False,
dictionaryMember=True)
@ -4545,7 +4750,7 @@ class Parser(Tokenizer):
def p_AttributeRest(self, p):
"""
AttributeRest : ReadOnly ATTRIBUTE Type IDENTIFIER SEMICOLON
AttributeRest : ReadOnly ATTRIBUTE Type AttributeName SEMICOLON
"""
location = self.getLocation(p, 2)
readonly = p[1]
@ -4874,6 +5079,7 @@ class Parser(Tokenizer):
| INTERFACE
| LEGACYCALLER
| PARTIAL
| REQUIRED
| SERIALIZER
| SETTER
| STATIC
@ -4884,6 +5090,13 @@ class Parser(Tokenizer):
"""
p[0] = p[1]
def p_AttributeName(self, p):
"""
AttributeName : IDENTIFIER
| REQUIRED
"""
p[0] = p[1]
def p_Optional(self, p):
"""
Optional : OPTIONAL
@ -4896,6 +5109,18 @@ class Parser(Tokenizer):
"""
p[0] = False
def p_Required(self, p):
"""
Required : REQUIRED
"""
p[0] = True
def p_RequiredEmpty(self, p):
"""
Required :
"""
p[0] = False
def p_Ellipsis(self, p):
"""
Ellipsis : ELLIPSIS
@ -4982,7 +5207,7 @@ class Parser(Tokenizer):
| DATE
| DOMSTRING
| BYTESTRING
| SCALARVALUESTRING
| USVSTRING
| ANY
| ATTRIBUTE
| BOOLEAN
@ -5255,11 +5480,11 @@ class Parser(Tokenizer):
"""
p[0] = IDLBuiltinType.Types.bytestring
def p_PrimitiveOrStringTypeScalarValueString(self, p):
def p_PrimitiveOrStringTypeUSVString(self, p):
"""
PrimitiveOrStringType : SCALARVALUESTRING
PrimitiveOrStringType : USVSTRING
"""
p[0] = IDLBuiltinType.Types.scalarvaluestring
p[0] = IDLBuiltinType.Types.usvstring
def p_UnsignedIntegerTypeUnsigned(self, p):
"""
@ -5473,6 +5698,10 @@ class Parser(Tokenizer):
self._globalScope.primaryGlobalName = "FakeTestPrimaryGlobal"
self._globalScope.globalNames.add("FakeTestPrimaryGlobal")
self._globalScope.globalNameMapping["FakeTestPrimaryGlobal"].add("FakeTestPrimaryGlobal")
# And we add the special-cased "System" global name, which
# doesn't have any corresponding interfaces.
self._globalScope.globalNames.add("System")
self._globalScope.globalNameMapping["System"].add("BackstagePass")
self._installBuiltins(self._globalScope)
self._productions = []
@ -5548,6 +5777,7 @@ class Parser(Tokenizer):
# Builtin IDL defined by WebIDL
_builtins = """
typedef unsigned long long DOMTimeStamp;
typedef (ArrayBufferView or ArrayBuffer) BufferSource;
"""
def main():

View file

@ -1,16 +1,18 @@
--- WebIDL.py
+++ WebIDL.py
@@ -450,44 +450,8 @@ class IDLIdentifierPlaceholder(IDLObjectWithIdentifier):
@@ -505,46 +505,8 @@ class IDLExposureMixins():
class IDLExternalInterface(IDLObjectWithIdentifier):
class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
def __init__(self, location, parentScope, identifier):
- assert isinstance(identifier, IDLUnresolvedIdentifier)
- assert isinstance(parentScope, IDLScope)
- self.parent = None
- IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier)
- IDLExposureMixins.__init__(self, location)
- IDLObjectWithIdentifier.resolve(self, parentScope)
-
- def finish(self, scope):
- IDLExposureMixins.finish(self, scope)
- pass
-
- def validate(self):

View file

@ -1,15 +1,16 @@
--- WebIDL.py
+++ WebIDL.py
@@ -1422,6 +1422,9 @@ class IDLDictionary(IDLObjectWithScope):
@@ -1506,6 +1506,9 @@ class IDLDictionary(IDLObjectWithScope):
self.identifier.name,
[member.location] + locations)
+ def module(self):
+ return self.location.filename().split('/')[-1].split('.webidl')[0] + 'Binding'
+
def addExtendedAttributes(self, attrs):
assert len(attrs) == 0
@@ -3398,6 +3398,9 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
@@ -3574,6 +3577,9 @@ class IDLCallbackType(IDLType, IDLObjectWithScope):
self._treatNonCallableAsNull = False
self._treatNonObjectAsNull = False

View file

@ -19,6 +19,7 @@
//! | float | `f32` |
//! | double | `f64` |
//! | DOMString | `DOMString` |
//! | USVString | `USVString` |
//! | ByteString | `ByteString` |
//! | object | `*mut JSObject` |
//! | interface types | `JSRef<T>` | `Temporary<T>` |
@ -31,7 +32,7 @@
use dom::bindings::codegen::PrototypeList;
use dom::bindings::js::{JSRef, Root, Unrooted};
use dom::bindings::str::ByteString;
use dom::bindings::str::{ByteString, USVString};
use dom::bindings::utils::{Reflectable, Reflector, DOMClass};
use util::str::DOMString;
@ -306,6 +307,7 @@ pub fn jsstring_to_str(cx: *mut JSContext, s: *mut JSString) -> DOMString {
unsafe {
let mut length = 0;
let chars = JS_GetStringCharsAndLength(cx, s, &mut length);
assert!(!chars.is_null());
let char_vec = slice::from_raw_parts(chars, length as usize);
String::from_utf16(char_vec).unwrap()
}
@ -339,6 +341,32 @@ impl FromJSValConvertible for DOMString {
}
}
impl ToJSValConvertible for USVString {
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
self.0.to_jsval(cx)
}
}
impl FromJSValConvertible for USVString {
type Config = ();
fn from_jsval(cx: *mut JSContext, value: JSVal, _: ())
-> Result<USVString, ()> {
let jsstr = unsafe { JS_ValueToString(cx, value) };
if jsstr.is_null() {
debug!("JS_ValueToString failed");
Err(())
} else {
unsafe {
let mut length = 0;
let chars = JS_GetStringCharsAndLength(cx, jsstr, &mut length);
assert!(!chars.is_null());
let char_vec = slice::from_raw_parts(chars, length as usize);
Ok(USVString(String::from_utf16_lossy(char_vec)))
}
}
}
}
impl ToJSValConvertible for ByteString {
fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
unsafe {

View file

@ -157,3 +157,7 @@ impl FromStr for ByteString {
Ok(ByteString::new(s.to_owned().into_bytes()))
}
}
/// A string that is constructed from a UCS-2 buffer by replacing invalid code
/// points with the replacement character.
pub struct USVString(pub String);

View file

@ -6,6 +6,7 @@ use dom::bindings::codegen::Bindings::LocationBinding;
use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, JSRef, Temporary};
use dom::bindings::str::USVString;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::urlhelper::UrlHelper;
use dom::window::Window;
@ -41,19 +42,19 @@ impl<'a> LocationMethods for JSRef<'a, Location> {
self.window.root().r().load_url(url);
}
fn Href(self) -> DOMString {
fn Href(self) -> USVString {
UrlHelper::Href(&self.get_url())
}
fn Stringify(self) -> DOMString {
self.Href()
self.Href().0
}
fn Search(self) -> DOMString {
fn Search(self) -> USVString {
UrlHelper::Search(&self.get_url())
}
fn Hash(self) -> DOMString {
fn Hash(self) -> USVString {
UrlHelper::Hash(&self.get_url())
}
}

View file

@ -14,7 +14,7 @@ use dom::bindings::codegen::UnionTypes::HTMLElementOrLong;
use dom::bindings::codegen::UnionTypes::HTMLElementOrLong::eLong;
use dom::bindings::global::GlobalField;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::str::ByteString;
use dom::bindings::str::{ByteString, USVString};
use dom::bindings::utils::{Reflector, Reflectable};
use dom::blob::Blob;
use util::str::DOMString;
@ -55,6 +55,8 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
fn SetDoubleAttribute(self, _: f64) {}
fn StringAttribute(self) -> DOMString { "".to_owned() }
fn SetStringAttribute(self, _: DOMString) {}
fn UsvstringAttribute(self) -> USVString { USVString("".to_owned()) }
fn SetUsvstringAttribute(self, _: USVString) {}
fn ByteStringAttribute(self) -> ByteString { ByteString::new(vec!()) }
fn SetByteStringAttribute(self, _: ByteString) {}
fn EnumAttribute(self) -> TestEnum { _empty }
@ -98,6 +100,8 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
fn SetByteStringAttributeNullable(self, _: Option<ByteString>) {}
fn GetStringAttributeNullable(self) -> Option<DOMString> { Some("".to_owned()) }
fn SetStringAttributeNullable(self, _: Option<DOMString>) {}
fn GetUsvstringAttributeNullable(self) -> Option<USVString> { Some(USVString("".to_owned())) }
fn SetUsvstringAttributeNullable(self, _: Option<USVString>) {}
fn SetBinaryRenamedAttribute(self, _: DOMString) {}
fn BinaryRenamedAttribute(self) -> DOMString { "".to_owned() }
fn GetEnumAttributeNullable(self) -> Option<TestEnum> { Some(_empty) }
@ -124,6 +128,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
fn ReceiveFloat(self) -> f32 { 0. }
fn ReceiveDouble(self) -> f64 { 0. }
fn ReceiveString(self) -> DOMString { "".to_owned() }
fn ReceiveUsvstring(self) -> USVString { USVString("".to_owned()) }
fn ReceiveByteString(self) -> ByteString { ByteString::new(vec!()) }
fn ReceiveEnum(self) -> TestEnum { _empty }
fn ReceiveInterface(self) -> Temporary<Blob> {
@ -146,6 +151,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
fn ReceiveNullableFloat(self) -> Option<f32> { Some(0.) }
fn ReceiveNullableDouble(self) -> Option<f64> { Some(0.) }
fn ReceiveNullableString(self) -> Option<DOMString> { Some("".to_owned()) }
fn ReceiveNullableUsvstring(self) -> Option<USVString> { Some(USVString("".to_owned())) }
fn ReceiveNullableByteString(self) -> Option<ByteString> { Some(ByteString::new(vec!())) }
fn ReceiveNullableEnum(self) -> Option<TestEnum> { Some(_empty) }
fn ReceiveNullableInterface(self) -> Option<Temporary<Blob>> {
@ -167,6 +173,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
fn PassFloat(self, _: f32) {}
fn PassDouble(self, _: f64) {}
fn PassString(self, _: DOMString) {}
fn PassUsvstring(self, _: USVString) {}
fn PassByteString(self, _: ByteString) {}
fn PassEnum(self, _: TestEnum) {}
fn PassInterface(self, _: JSRef<Blob>) {}
@ -189,6 +196,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
fn PassNullableFloat(self, _: Option<f32>) {}
fn PassNullableDouble(self, _: Option<f64>) {}
fn PassNullableString(self, _: Option<DOMString>) {}
fn PassNullableUsvstring(self, _: Option<USVString>) {}
fn PassNullableByteString(self, _: Option<ByteString>) {}
// fn PassNullableEnum(self, _: Option<TestEnum>) {}
fn PassNullableInterface(self, _: Option<JSRef<Blob>>) {}
@ -209,6 +217,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
fn PassOptionalFloat(self, _: Option<f32>) {}
fn PassOptionalDouble(self, _: Option<f64>) {}
fn PassOptionalString(self, _: Option<DOMString>) {}
fn PassOptionalUsvstring(self, _: Option<USVString>) {}
fn PassOptionalByteString(self, _: Option<ByteString>) {}
fn PassOptionalEnum(self, _: Option<TestEnum>) {}
fn PassOptionalInterface(self, _: Option<JSRef<Blob>>) {}
@ -230,6 +239,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
fn PassOptionalNullableFloat(self, _: Option<Option<f32>>) {}
fn PassOptionalNullableDouble(self, _: Option<Option<f64>>) {}
fn PassOptionalNullableString(self, _: Option<Option<DOMString>>) {}
fn PassOptionalNullableUsvstring(self, _: Option<Option<USVString>>) {}
fn PassOptionalNullableByteString(self, _: Option<Option<ByteString>>) {}
// fn PassOptionalNullableEnum(self, _: Option<Option<TestEnum>>) {}
fn PassOptionalNullableInterface(self, _: Option<Option<JSRef<Blob>>>) {}
@ -248,6 +258,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
fn PassOptionalLongLongWithDefault(self, _: i64) {}
fn PassOptionalUnsignedLongLongWithDefault(self, _: u64) {}
fn PassOptionalStringWithDefault(self, _: DOMString) {}
fn PassOptionalUsvstringWithDefault(self, _: USVString) {}
fn PassOptionalEnumWithDefault(self, _: TestEnum) {}
fn PassOptionalNullableBooleanWithDefault(self, _: Option<bool>) {}
@ -262,6 +273,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
// fn PassOptionalNullableFloatWithDefault(self, _: Option<f32>) {}
// fn PassOptionalNullableDoubleWithDefault(self, _: Option<f64>) {}
fn PassOptionalNullableStringWithDefault(self, _: Option<DOMString>) {}
fn PassOptionalNullableUsvstringWithDefault(self, _: Option<USVString>) {}
fn PassOptionalNullableByteStringWithDefault(self, _: Option<ByteString>) {}
// fn PassOptionalNullableEnumWithDefault(self, _: Option<TestEnum>) {}
fn PassOptionalNullableInterfaceWithDefault(self, _: Option<JSRef<Blob>>) {}
@ -283,6 +295,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
// fn PassOptionalNullableFloatWithNonNullDefault(self, _: Option<f32>) {}
// fn PassOptionalNullableDoubleWithNonNullDefault(self, _: Option<f64>) {}
fn PassOptionalNullableStringWithNonNullDefault(self, _: Option<DOMString>) {}
fn PassOptionalNullableUsvstringWithNonNullDefault(self, _: Option<USVString>) {}
// fn PassOptionalNullableEnumWithNonNullDefault(self, _: Option<TestEnum>) {}
fn PassVariadicBoolean(self, _: Vec<bool>) {}
@ -297,6 +310,7 @@ impl<'a> TestBindingMethods for JSRef<'a, TestBinding> {
fn PassVariadicFloat(self, _: Vec<f32>) {}
fn PassVariadicDouble(self, _: Vec<f64>) {}
fn PassVariadicString(self, _: Vec<DOMString>) {}
fn PassVariadicUsvstring(self, _: Vec<USVString>) {}
fn PassVariadicByteString(self, _: Vec<ByteString>) {}
fn PassVariadicEnum(self, _: Vec<TestEnum>) {}
// fn PassVariadicInterface(self, _: Vec<JSRef<Blob>>) {}

View file

@ -2,7 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use util::str::DOMString;
use dom::bindings::str::USVString;
use url::Url;
use std::borrow::ToOwned;
@ -10,24 +11,24 @@ use std::borrow::ToOwned;
pub struct UrlHelper;
impl UrlHelper {
pub fn Href(url: &Url) -> DOMString {
url.serialize()
pub fn Href(url: &Url) -> USVString {
USVString(url.serialize())
}
pub fn Search(url: &Url) -> DOMString {
match url.query {
pub fn Search(url: &Url) -> USVString {
USVString(match url.query {
None => "".to_owned(),
Some(ref query) if query.as_slice() == "" => "".to_owned(),
Some(ref query) => format!("?{}", query)
}
})
}
pub fn Hash(url: &Url) -> DOMString {
match url.fragment {
pub fn Hash(url: &Url) -> USVString {
USVString(match url.fragment {
None => "".to_owned(),
Some(ref hash) if hash.as_slice() == "" => "".to_owned(),
Some(ref hash) => format!("#{}", hash)
}
})
}
/// https://html.spec.whatwg.org/multipage/browsers.html#same-origin

View file

@ -17,6 +17,7 @@ dictionary TestDictionary {
float floatValue;
double doubleValue;
DOMString stringValue;
USVString usvstringValue;
TestEnum enumValue;
Blob interfaceValue;
any anyValue;
@ -35,6 +36,7 @@ dictionary TestDictionaryDefaults {
// float floatValue = 7.0;
// double doubleValue = 7.0;
DOMString stringValue = "foo";
USVString usvstringValue = "foo";
TestEnum enumValue = "bar";
any anyValue = null;
@ -50,6 +52,7 @@ dictionary TestDictionaryDefaults {
// float? nullableFloatValue = 7.0;
// double? nullableDoubleValue = 7.0;
DOMString? nullableStringValue = "foo";
USVString? nullableUsvstringValue = "foo";
// TestEnum? nullableEnumValue = "bar";
};
@ -66,6 +69,7 @@ interface TestBinding {
attribute float floatAttribute;
attribute double doubleAttribute;
attribute DOMString stringAttribute;
attribute USVString usvstringAttribute;
attribute ByteString byteStringAttribute;
attribute TestEnum enumAttribute;
attribute Blob interfaceAttribute;
@ -86,6 +90,7 @@ interface TestBinding {
attribute float? floatAttributeNullable;
attribute double? doubleAttributeNullable;
attribute DOMString? stringAttributeNullable;
attribute USVString? usvstringAttributeNullable;
attribute ByteString? byteStringAttributeNullable;
readonly attribute TestEnum? enumAttributeNullable;
attribute Blob? interfaceAttributeNullable;
@ -107,6 +112,7 @@ interface TestBinding {
float receiveFloat();
double receiveDouble();
DOMString receiveString();
USVString receiveUsvstring();
ByteString receiveByteString();
TestEnum receiveEnum();
Blob receiveInterface();
@ -126,6 +132,7 @@ interface TestBinding {
float? receiveNullableFloat();
double? receiveNullableDouble();
DOMString? receiveNullableString();
USVString? receiveNullableUsvstring();
ByteString? receiveNullableByteString();
TestEnum? receiveNullableEnum();
Blob? receiveNullableInterface();
@ -144,6 +151,7 @@ interface TestBinding {
void passFloat(float arg);
void passDouble(double arg);
void passString(DOMString arg);
void passUsvstring(USVString arg);
void passByteString(ByteString arg);
void passEnum(TestEnum arg);
void passInterface(Blob arg);
@ -166,6 +174,7 @@ interface TestBinding {
void passNullableFloat(float? arg);
void passNullableDouble(double? arg);
void passNullableString(DOMString? arg);
void passNullableUsvstring(USVString? arg);
void passNullableByteString(ByteString? arg);
// void passNullableEnum(TestEnum? arg);
void passNullableInterface(Blob? arg);
@ -186,6 +195,7 @@ interface TestBinding {
void passOptionalFloat(optional float arg);
void passOptionalDouble(optional double arg);
void passOptionalString(optional DOMString arg);
void passOptionalUsvstring(optional USVString arg);
void passOptionalByteString(optional ByteString arg);
void passOptionalEnum(optional TestEnum arg);
void passOptionalInterface(optional Blob arg);
@ -207,6 +217,7 @@ interface TestBinding {
void passOptionalNullableFloat(optional float? arg);
void passOptionalNullableDouble(optional double? arg);
void passOptionalNullableString(optional DOMString? arg);
void passOptionalNullableUsvstring(optional USVString? arg);
void passOptionalNullableByteString(optional ByteString? arg);
// void passOptionalNullableEnum(optional TestEnum? arg);
void passOptionalNullableInterface(optional Blob? arg);
@ -225,6 +236,7 @@ interface TestBinding {
void passOptionalLongLongWithDefault(optional long long arg = -12);
void passOptionalUnsignedLongLongWithDefault(optional unsigned long long arg = 17);
void passOptionalStringWithDefault(optional DOMString arg = "x");
void passOptionalUsvstringWithDefault(optional USVString arg = "x");
void passOptionalEnumWithDefault(optional TestEnum arg = "foo");
// void passOptionalUnionWithDefault(optional (HTMLElement or long) arg = 9);
// void passOptionalUnion2WithDefault(optional(Event or DOMString)? data = "foo");
@ -239,6 +251,7 @@ interface TestBinding {
void passOptionalNullableLongLongWithDefault(optional long long? arg = null);
void passOptionalNullableUnsignedLongLongWithDefault(optional unsigned long long? arg = null);
void passOptionalNullableStringWithDefault(optional DOMString? arg = null);
void passOptionalNullableUsvstringWithDefault(optional USVString? arg = null);
void passOptionalNullableByteStringWithDefault(optional ByteString? arg = null);
// void passOptionalNullableEnumWithDefault(optional TestEnum? arg = null);
void passOptionalNullableInterfaceWithDefault(optional Blob? arg = null);
@ -260,6 +273,7 @@ interface TestBinding {
// void passOptionalNullableFloatWithNonNullDefault(optional float? arg = 0.0);
// void passOptionalNullableDoubleWithNonNullDefault(optional double? arg = 0.0);
void passOptionalNullableStringWithNonNullDefault(optional DOMString? arg = "x");
void passOptionalNullableUsvstringWithNonNullDefault(optional USVString? arg = "x");
// void passOptionalNullableEnumWithNonNullDefault(optional TestEnum? arg = "foo");
// void passOptionalNullableUnionWithNonNullDefault(optional (HTMLElement or long)? arg = 7);
// void passOptionalNullableUnion2WithNonNullDefault(optional (Event or DOMString)? data = "foo");
@ -276,6 +290,7 @@ interface TestBinding {
void passVariadicFloat(float... args);
void passVariadicDouble(double... args);
void passVariadicString(DOMString... args);
void passVariadicUsvstring(USVString... args);
void passVariadicByteString(ByteString... args);
void passVariadicEnum(TestEnum... args);
// void passVariadicInterface(Blob... args);

View file

@ -8,7 +8,7 @@
*/
interface TreeWalker {
[SameObject,Constant]
[SameObject]
readonly attribute Node root;
[Constant]
readonly attribute unsigned long whatToShow;

View file

@ -6,21 +6,21 @@
// http://url.spec.whatwg.org/#urlutils
[NoInterfaceObject]
interface URLUtils {
//stringifier attribute ScalarValueString href;
readonly attribute DOMString href;
//readonly attribute ScalarValueString origin;
// attribute ScalarValueString protocol;
// attribute ScalarValueString username;
// attribute ScalarValueString password;
// attribute ScalarValueString host;
// attribute ScalarValueString hostname;
// attribute ScalarValueString port;
// attribute ScalarValueString pathname;
// attribute ScalarValueString search;
readonly attribute DOMString search;
//stringifier attribute USVString href;
readonly attribute USVString href;
//readonly attribute USVString origin;
// attribute USVString protocol;
// attribute USVString username;
// attribute USVString password;
// attribute USVString host;
// attribute USVString hostname;
// attribute USVString port;
// attribute USVString pathname;
// attribute USVString search;
readonly attribute USVString search;
// attribute URLSearchParams searchParams;
// attribute ScalarValueString hash;
readonly attribute DOMString hash;
// attribute USVString hash;
readonly attribute USVString hash;
// This is only doing as well as gecko right now, bug 824857 is on file for
// adding attribute stringifier support.

View file

@ -7,17 +7,15 @@
[NoInterfaceObject/*,
Exposed=(Window,Worker)*/]
interface URLUtilsReadOnly {
//stringifier readonly attribute ScalarValueString href;
readonly attribute DOMString href;
//readonly attribute ScalarValueString origin;
//stringifier readonly attribute USVString href;
readonly attribute USVString href;
//readonly attribute USVString origin;
//readonly attribute ScalarValueString protocol;
//readonly attribute ScalarValueString host;
//readonly attribute ScalarValueString hostname;
//readonly attribute ScalarValueString port;
//readonly attribute ScalarValueString pathname;
//readonly attribute ScalarValueString search;
readonly attribute DOMString search;
//readonly attribute ScalarValueString hash;
readonly attribute DOMString hash;
//readonly attribute USVString protocol;
//readonly attribute USVString host;
//readonly attribute USVString hostname;
//readonly attribute USVString port;
//readonly attribute USVString pathname;
readonly attribute USVString search;
readonly attribute USVString hash;
};

View file

@ -6,12 +6,11 @@ use dom::bindings::codegen::Bindings::WorkerLocationBinding;
use dom::bindings::codegen::Bindings::WorkerLocationBinding::WorkerLocationMethods;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::global::GlobalRef;
use dom::bindings::str::USVString;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::urlhelper::UrlHelper;
use dom::workerglobalscope::WorkerGlobalScope;
use util::str::DOMString;
use url::Url;
#[dom_struct]
@ -36,15 +35,15 @@ impl WorkerLocation {
}
impl<'a> WorkerLocationMethods for JSRef<'a, WorkerLocation> {
fn Href(self) -> DOMString {
fn Href(self) -> USVString {
UrlHelper::Href(&self.url)
}
fn Search(self) -> DOMString {
fn Search(self) -> USVString {
UrlHelper::Search(&self.url)
}
fn Hash(self) -> DOMString {
fn Hash(self) -> USVString {
UrlHelper::Hash(&self.url)
}
}