aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py69
-rw-r--r--components/script/dom/bindings/codegen/parser/WebIDL.py304
-rw-r--r--components/script/dom/bindings/codegen/parser/bytestring.patch29
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_array.py18
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_array_of_interface.py13
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py29
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_attr.py166
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_bytestring.py41
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py9
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_method.py16
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py10
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_union.py3
-rw-r--r--components/script/dom/bindings/codegen/parser/union-typedef.patch22
-rwxr-xr-xcomponents/script/dom/bindings/codegen/parser/update.sh2
-rw-r--r--components/script/dom/bindings/global.rs87
-rw-r--r--components/script/dom/bindings/proxyhandler.rs2
-rw-r--r--components/script/dom/bluetooth.rs63
-rw-r--r--components/script/dom/bluetoothremotegattcharacteristic.rs89
-rw-r--r--components/script/dom/bluetoothremotegattdescriptor.rs53
-rw-r--r--components/script/dom/bluetoothremotegattserver.rs95
-rw-r--r--components/script/dom/bluetoothremotegattservice.rs101
-rw-r--r--components/script/dom/bluetoothuuid.rs95
-rw-r--r--components/script/dom/browsingcontext.rs2
-rw-r--r--components/script/dom/dedicatedworkerglobalscope.rs66
-rw-r--r--components/script/dom/document.rs18
-rw-r--r--components/script/dom/headers.rs4
-rw-r--r--components/script/dom/htmllinkelement.rs105
-rw-r--r--components/script/dom/htmlscriptelement.rs12
-rw-r--r--components/script/dom/request.rs116
-rw-r--r--components/script/dom/response.rs107
-rw-r--r--components/script/dom/serviceworkerglobalscope.rs13
-rw-r--r--components/script/dom/webglprogram.rs70
-rw-r--r--components/script/dom/webglrenderingcontext.rs160
-rw-r--r--components/script/dom/webidls/Bluetooth.webidl4
-rw-r--r--components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl16
-rw-r--r--components/script/dom/webidls/BluetoothRemoteGATTDescriptor.webidl6
-rw-r--r--components/script/dom/webidls/BluetoothRemoteGATTServer.webidl12
-rw-r--r--components/script/dom/webidls/BluetoothRemoteGATTService.webidl19
-rw-r--r--components/script/dom/webidls/Body.webidl9
-rw-r--r--components/script/dom/webidls/EventSource.webidl3
-rw-r--r--components/script/dom/webidls/Fetch.webidl11
-rw-r--r--components/script/dom/webidls/Response.webidl3
-rw-r--r--components/script/dom/webidls/WebGLRenderingContext.webidl6
-rw-r--r--components/script/dom/webidls/WindowOrWorkerGlobalScope.webidl30
-rw-r--r--components/script/dom/window.rs77
-rw-r--r--components/script/dom/worker.rs2
-rw-r--r--components/script/dom/workerglobalscope.rs69
-rw-r--r--components/script/dom/xmlhttprequest.rs3
48 files changed, 1153 insertions, 1106 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 711f44b4cd4..7c6b2fe3718 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -462,8 +462,7 @@ class CGMethodCall(CGThing):
pickFirstSignature("%s.get().is_object() && is_array_like(cx, %s)" %
(distinguishingArg, distinguishingArg),
lambda s:
- (s[1][distinguishingIndex].type.isArray() or
- s[1][distinguishingIndex].type.isSequence() or
+ (s[1][distinguishingIndex].type.isSequence() or
s[1][distinguishingIndex].type.isObject()))
# Check for Date objects
@@ -537,9 +536,6 @@ def typeIsSequenceOrHasSequenceMember(type):
type = type.inner
if type.isSequence():
return True
- if type.isArray():
- elementType = type.inner
- return typeIsSequenceOrHasSequenceMember(elementType)
if type.isDictionary():
return dictionaryHasSequenceMember(type.inner)
if type.isUnion():
@@ -732,9 +728,6 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
assert not (isEnforceRange and isClamp) # These are mutually exclusive
- if type.isArray():
- raise TypeError("Can't handle array arguments yet")
-
if type.isSequence() or type.isMozMap():
innerInfo = getJSToNativeConversionInfo(innerContainerType(type),
descriptorProvider,
@@ -1309,7 +1302,7 @@ def typeNeedsCx(type, retVal=False):
return False
if type.nullable():
type = type.inner
- if type.isSequence() or type.isArray():
+ if type.isSequence():
type = type.inner
if type.isUnion():
return any(typeNeedsCx(t) for t in type.unroll().flatMemberTypes)
@@ -1612,7 +1605,7 @@ class MethodDefiner(PropertyDefiner):
"name": "forEach",
"methodInfo": False,
"selfHostedName": "ArrayForEach",
- "length": 0,
+ "length": 1,
"condition": PropertyDefiner.getControllingCondition(m,
descriptor)
})
@@ -3809,9 +3802,6 @@ class CGMemberJITInfo(CGThing):
if t.isVoid():
# No return, every time
return "JSVAL_TYPE_UNDEFINED"
- if t.isArray():
- # No idea yet
- assert False
if t.isSequence():
return "JSVAL_TYPE_OBJECT"
if t.isMozMap():
@@ -3887,9 +3877,6 @@ class CGMemberJITInfo(CGThing):
if t.nullable():
# Sometimes it might return null, sometimes not
return "JSJitInfo_ArgType::Null as i32 | %s" % CGMemberJITInfo.getJSArgType(t.inner)
- if t.isArray():
- # No idea yet
- assert False
if t.isSequence():
return "JSJitInfo_ArgType::Object as i32"
if t.isGeckoInterface():
@@ -4153,7 +4140,7 @@ class CGUnionConversionStruct(CGThing):
else:
interfaceObject = None
- arrayObjectMemberTypes = filter(lambda t: t.isArray() or t.isSequence(), memberTypes)
+ arrayObjectMemberTypes = filter(lambda t: t.isSequence(), memberTypes)
if len(arrayObjectMemberTypes) > 0:
assert len(arrayObjectMemberTypes) == 1
typeName = arrayObjectMemberTypes[0].name
@@ -4767,7 +4754,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
def __init__(self, descriptor):
args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'),
Argument('HandleId', 'id'),
- Argument('MutableHandle<PropertyDescriptor>', 'desc', mutable=True)]
+ Argument('MutableHandle<PropertyDescriptor>', 'desc')]
CGAbstractExternMethod.__init__(self, descriptor, "getOwnPropertyDescriptor",
"bool", args)
self.descriptor = descriptor
@@ -4786,7 +4773,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
attrs += " | JSPROP_READONLY"
# FIXME(#11868) Should assign to desc.value, desc.get() is a copy.
fillDescriptor = ("desc.get().value = result_root.get();\n"
- "fill_property_descriptor(&mut desc, proxy.get(), %s);\n"
+ "fill_property_descriptor(desc, proxy.get(), %s);\n"
"return true;" % attrs)
templateValues = {
'jsvalRef': 'result_root.handle_mut()',
@@ -4812,7 +4799,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
attrs = "0"
# FIXME(#11868) Should assign to desc.value, desc.get() is a copy.
fillDescriptor = ("desc.get().value = result_root.get();\n"
- "fill_property_descriptor(&mut desc, proxy.get(), %s);\n"
+ "fill_property_descriptor(desc, proxy.get(), %s);\n"
"return true;" % attrs)
templateValues = {
'jsvalRef': 'result_root.handle_mut()',
@@ -5641,13 +5628,6 @@ class CGDescriptor(CGThing):
return name
cgThings = []
- if not descriptor.interface.isCallback() and not descriptor.interface.isNamespace():
- cgThings.append(CGGetProtoObjectMethod(descriptor))
- reexports.append('GetProtoObject')
- if (descriptor.interface.hasInterfaceObject() and
- descriptor.shouldHaveGetConstructorObjectMethod()):
- cgThings.append(CGGetConstructorObjectMethod(descriptor))
- reexports.append('GetConstructorObject')
unscopableNames = []
for m in descriptor.interface.members:
@@ -5694,17 +5674,6 @@ class CGDescriptor(CGThing):
cgThings.append(CGClassFinalizeHook(descriptor))
cgThings.append(CGClassTraceHook(descriptor))
- if descriptor.interface.hasInterfaceObject():
- if descriptor.interface.ctor():
- cgThings.append(CGClassConstructHook(descriptor))
- for ctor in descriptor.interface.namedConstructors:
- cgThings.append(CGClassConstructHook(descriptor, ctor))
- if not descriptor.interface.isCallback():
- cgThings.append(CGInterfaceObjectJSClass(descriptor))
-
- if not descriptor.interface.isCallback() and not descriptor.interface.isNamespace():
- cgThings.append(CGPrototypeJSClass(descriptor))
-
# If there are no constant members, don't make a module for constants
constMembers = [m for m in descriptor.interface.members if m.isConst()]
if constMembers:
@@ -5713,11 +5682,6 @@ class CGDescriptor(CGThing):
public=True))
reexports.append(descriptor.name + 'Constants')
- if descriptor.interface.hasInterfaceObject() and descriptor.register:
- cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
- reexports.append('DefineDOMInterface')
- cgThings.append(CGConstructorEnabled(descriptor))
-
if descriptor.proxy:
cgThings.append(CGDefineProxyHandler(descriptor))
@@ -5779,6 +5743,25 @@ class CGDescriptor(CGThing):
cgThings.append(CGWeakReferenceableTrait(descriptor))
cgThings.append(CGGeneric(str(properties)))
+
+ if not descriptor.interface.isCallback() and not descriptor.interface.isNamespace():
+ cgThings.append(CGGetProtoObjectMethod(descriptor))
+ reexports.append('GetProtoObject')
+ cgThings.append(CGPrototypeJSClass(descriptor))
+ if descriptor.interface.hasInterfaceObject():
+ if descriptor.interface.ctor():
+ cgThings.append(CGClassConstructHook(descriptor))
+ for ctor in descriptor.interface.namedConstructors:
+ cgThings.append(CGClassConstructHook(descriptor, ctor))
+ if not descriptor.interface.isCallback():
+ cgThings.append(CGInterfaceObjectJSClass(descriptor))
+ if descriptor.shouldHaveGetConstructorObjectMethod():
+ cgThings.append(CGGetConstructorObjectMethod(descriptor))
+ reexports.append('GetConstructorObject')
+ if descriptor.register:
+ cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
+ reexports.append('DefineDOMInterface')
+ cgThings.append(CGConstructorEnabled(descriptor))
cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties, haveUnscopables))
cgThings = generate_imports(config, CGList(cgThings, '\n'), [descriptor])
diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py
index 878c221f01c..2894bbeb82e 100644
--- a/components/script/dom/bindings/codegen/parser/WebIDL.py
+++ b/components/script/dom/bindings/codegen/parser/WebIDL.py
@@ -9,6 +9,7 @@ import re
import os
import traceback
import math
+import string
from collections import defaultdict
# Machinery
@@ -1850,7 +1851,6 @@ class IDLDictionary(IDLObjectWithScope):
"""
if (memberType.nullable() or
- memberType.isArray() or
memberType.isSequence() or
memberType.isMozMap()):
return typeContainsDictionary(memberType.inner, dictionary)
@@ -1973,8 +1973,7 @@ class IDLType(IDLObject):
'callback',
'union',
'sequence',
- 'mozmap',
- 'array'
+ 'mozmap'
)
def __init__(self, location, name):
@@ -2027,9 +2026,6 @@ class IDLType(IDLObject):
def isMozMap(self):
return False
- def isArray(self):
- return False
-
def isArrayBuffer(self):
return False
@@ -2255,9 +2251,6 @@ class IDLNullableType(IDLParameterizedType):
def isMozMap(self):
return self.inner.isMozMap()
- def isArray(self):
- return self.inner.isArray()
-
def isArrayBuffer(self):
return self.inner.isArrayBuffer()
@@ -2360,9 +2353,6 @@ class IDLSequenceType(IDLParameterizedType):
def isSequence(self):
return True
- def isArray(self):
- return False
-
def isDictionary(self):
return False
@@ -2575,106 +2565,6 @@ class IDLUnionType(IDLType):
return set(self.memberTypes)
-class IDLArrayType(IDLType):
- def __init__(self, location, parameterType):
- assert not parameterType.isVoid()
- if parameterType.isSequence():
- raise WebIDLError("Array type cannot parameterize over a sequence type",
- [location])
- if parameterType.isMozMap():
- raise WebIDLError("Array type cannot parameterize over a MozMap type",
- [location])
- if parameterType.isDictionary():
- raise WebIDLError("Array type cannot parameterize over a dictionary type",
- [location])
-
- IDLType.__init__(self, location, parameterType.name)
- self.inner = parameterType
- self.builtin = False
-
- def __eq__(self, other):
- return isinstance(other, IDLArrayType) and self.inner == other.inner
-
- def __str__(self):
- return self.inner.__str__() + "Array"
-
- def nullable(self):
- return False
-
- def isPrimitive(self):
- return False
-
- def isString(self):
- return False
-
- def isByteString(self):
- return False
-
- def isDOMString(self):
- return False
-
- def isUSVString(self):
- return False
-
- def isVoid(self):
- return False
-
- def isSequence(self):
- assert not self.inner.isSequence()
- return False
-
- def isArray(self):
- return True
-
- def isDictionary(self):
- assert not self.inner.isDictionary()
- return False
-
- def isInterface(self):
- return False
-
- def isEnum(self):
- return False
-
- def tag(self):
- return IDLType.Tags.array
-
- def resolveType(self, parentScope):
- assert isinstance(parentScope, IDLScope)
- self.inner.resolveType(parentScope)
-
- def isComplete(self):
- return self.inner.isComplete()
-
- def complete(self, scope):
- self.inner = self.inner.complete(scope)
- self.name = self.inner.name
-
- if self.inner.isDictionary():
- raise WebIDLError("Array type must not contain "
- "dictionary as element type.",
- [self.inner.location])
-
- assert not self.inner.isSequence()
-
- return self
-
- def unroll(self):
- return self.inner.unroll()
-
- def isDistinguishableFrom(self, other):
- if other.isPromise():
- return False
- if other.isUnion():
- # 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())
-
- def _getDependentObjects(self):
- return self.inner._getDependentObjects()
-
-
class IDLTypedefType(IDLType):
def __init__(self, location, innerType, name):
IDLType.__init__(self, location, name)
@@ -2720,9 +2610,6 @@ class IDLTypedefType(IDLType):
def isMozMap(self):
return self.inner.isMozMap()
- def isArray(self):
- return self.inner.isArray()
-
def isDictionary(self):
return self.inner.isDictionary()
@@ -2838,9 +2725,6 @@ class IDLWrapperType(IDLType):
def isSequence(self):
return False
- def isArray(self):
- return False
-
def isDictionary(self):
return isinstance(self.inner, IDLDictionary)
@@ -2907,8 +2791,7 @@ class IDLWrapperType(IDLType):
if self.isEnum():
return (other.isPrimitive() or other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isArray() or
- other.isDate())
+ other.isSequence() or other.isMozMap() or other.isDate())
if self.isDictionary() and other.nullable():
return False
if (other.isPrimitive() or other.isString() or other.isEnum() or
@@ -2930,7 +2813,7 @@ class IDLWrapperType(IDLType):
(self.isNonCallbackInterface() or
other.isNonCallbackInterface()))
if (other.isDictionary() or other.isCallback() or
- other.isMozMap() or other.isArray()):
+ other.isMozMap()):
return self.isNonCallbackInterface()
# Not much else |other| can be
@@ -3140,20 +3023,17 @@ class IDLBuiltinType(IDLType):
return (other.isNumeric() or other.isString() or other.isEnum() or
other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isArray() or
- other.isDate())
+ other.isSequence() or other.isMozMap() or other.isDate())
if self.isNumeric():
return (other.isBoolean() or other.isString() or other.isEnum() or
other.isInterface() or other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isArray() or
- other.isDate())
+ other.isSequence() or other.isMozMap() or other.isDate())
if self.isString():
return (other.isPrimitive() or other.isInterface() or
other.isObject() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isArray() or
- other.isDate())
+ other.isSequence() or other.isMozMap() or other.isDate())
if self.isAny():
# Can't tell "any" apart from anything
return False
@@ -3163,7 +3043,7 @@ class IDLBuiltinType(IDLType):
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isInterface() or other.isCallback() or
other.isDictionary() or other.isSequence() or
- other.isMozMap() or other.isArray())
+ other.isMozMap())
if self.isVoid():
return not other.isVoid()
# Not much else we could be!
@@ -3171,8 +3051,7 @@ class IDLBuiltinType(IDLType):
# Like interfaces, but we know we're not a callback
return (other.isPrimitive() or other.isString() or other.isEnum() or
other.isCallback() or other.isDictionary() or
- other.isSequence() or other.isMozMap() or other.isArray() or
- other.isDate() or
+ other.isSequence() or other.isMozMap() or other.isDate() or
(other.isInterface() and (
# ArrayBuffer is distinguishable from everything
# that's not an ArrayBuffer or a callback interface
@@ -3311,6 +3190,11 @@ def matchIntegerValueToType(value):
return None
+class NoCoercionFoundError(WebIDLError):
+ """
+ A class we use to indicate generic coercion failures because none of the
+ types worked out in IDLValue.coerceToType.
+ """
class IDLValue(IDLObject):
def __init__(self, location, type, value):
@@ -3338,8 +3222,18 @@ class IDLValue(IDLObject):
# use the value's type when it is a default value of a
# union, and the union cares about the exact float type.
return IDLValue(self.location, subtype, coercedValue.value)
- except:
- pass
+ except Exception as e:
+ # Make sure to propagate out WebIDLErrors that are not the
+ # generic "hey, we could not coerce to this type at all"
+ # exception, because those are specific "coercion failed for
+ # reason X" exceptions. Note that we want to swallow
+ # non-WebIDLErrors here, because those can just happen if
+ # "type" is not something that can have a default value at
+ # all.
+ if (isinstance(e, WebIDLError) and
+ not isinstance(e, NoCoercionFoundError)):
+ raise e
+
# If the type allows null, rerun this matching on the inner type, except
# nullable enums. We handle those specially, because we want our
# default string values to stay strings even when assigned to a nullable
@@ -3388,12 +3282,21 @@ class IDLValue(IDLObject):
assert self.type.isDOMString()
return self
elif self.type.isString() and type.isByteString():
- # Allow ByteStrings to use default value just like
- # DOMString. No coercion is required here.
- assert self.type.isDOMString()
- return self
- raise WebIDLError("Cannot coerce type %s to type %s." %
- (self.type, type), [location])
+ # Allow ByteStrings to use a default value like DOMString.
+ # No coercion is required as Codegen.py will handle the
+ # extra steps. We want to make sure that our string contains
+ # only valid characters, so we check that here.
+ valid_ascii_lit = " " + string.ascii_letters + string.digits + string.punctuation
+ for idx, c in enumerate(self.value):
+ if c not in valid_ascii_lit:
+ raise WebIDLError("Coercing this string literal %s to a ByteString is not supported yet. "
+ "Coercion failed due to an unsupported byte %d at index %d."
+ % (self.value.__repr__(), ord(c), idx), [location])
+
+ return IDLValue(self.location, type, self.value)
+
+ raise NoCoercionFoundError("Cannot coerce type %s to type %s." %
+ (self.type, type), [location])
def _getDependentObjects(self):
return set()
@@ -4568,12 +4471,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
base=IDLInterfaceMember.Special
)
- TypeSuffixModifier = enum(
- 'None',
- 'QMark',
- 'Brackets'
- )
-
NamedOrIndexed = enum(
'Neither',
'Named',
@@ -5743,14 +5640,6 @@ class Parser(Tokenizer):
booleanType = BuiltinTypes[IDLBuiltinType.Types.boolean]
p[0] = IDLValue(location, booleanType, p[1])
- def p_ConstValueByteString(self, p):
- """
- ConstValue : BYTESTRING
- """
- location = self.getLocation(p, 1)
- bytestringType = BuiltinTypes[IDLBuiltinType.Types.bytestring]
- p[0] = IDLValue(location, bytestringType, p[1])
-
def p_ConstValueInteger(self, p):
"""
ConstValue : INTEGER
@@ -6383,9 +6272,9 @@ class Parser(Tokenizer):
def p_TypeUnionType(self, p):
"""
- Type : UnionType TypeSuffix
+ Type : UnionType Null
"""
- p[0] = self.handleModifiers(p[1], p[2])
+ p[0] = self.handleNullable(p[1], p[2])
def p_SingleTypeNonAnyType(self, p):
"""
@@ -6395,9 +6284,9 @@ class Parser(Tokenizer):
def p_SingleTypeAnyType(self, p):
"""
- SingleType : ANY TypeSuffixStartingWithArray
+ SingleType : ANY
"""
- p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.any], p[2])
+ p[0] = BuiltinTypes[IDLBuiltinType.Types.any]
def p_UnionType(self, p):
"""
@@ -6413,19 +6302,11 @@ class Parser(Tokenizer):
"""
p[0] = p[1]
- def p_UnionMemberTypeArrayOfAny(self, p):
- """
- UnionMemberTypeArrayOfAny : ANY LBRACKET RBRACKET
- """
- p[0] = IDLArrayType(self.getLocation(p, 2),
- BuiltinTypes[IDLBuiltinType.Types.any])
-
def p_UnionMemberType(self, p):
"""
- UnionMemberType : UnionType TypeSuffix
- | UnionMemberTypeArrayOfAny TypeSuffix
+ UnionMemberType : UnionType Null
"""
- p[0] = self.handleModifiers(p[1], p[2])
+ p[0] = self.handleNullable(p[1], p[2])
def p_UnionMemberTypes(self, p):
"""
@@ -6442,10 +6323,10 @@ class Parser(Tokenizer):
def p_NonAnyType(self, p):
"""
- NonAnyType : PrimitiveOrStringType TypeSuffix
- | ARRAYBUFFER TypeSuffix
- | SHAREDARRAYBUFFER TypeSuffix
- | OBJECT TypeSuffix
+ NonAnyType : PrimitiveOrStringType Null
+ | ARRAYBUFFER Null
+ | SHAREDARRAYBUFFER Null
+ | OBJECT Null
"""
if p[1] == "object":
type = BuiltinTypes[IDLBuiltinType.Types.object]
@@ -6456,7 +6337,7 @@ class Parser(Tokenizer):
else:
type = BuiltinTypes[p[1]]
- p[0] = self.handleModifiers(type, p[2])
+ p[0] = self.handleNullable(type, p[2])
def p_NonAnyTypeSequenceType(self, p):
"""
@@ -6464,9 +6345,7 @@ class Parser(Tokenizer):
"""
innerType = p[3]
type = IDLSequenceType(self.getLocation(p, 1), innerType)
- if p[5]:
- type = IDLNullableType(self.getLocation(p, 5), type)
- p[0] = type
+ p[0] = self.handleNullable(type, p[5])
# Note: Promise<void> is allowed, so we want to parametrize on
# ReturnType, not Type. Also, we want this to end up picking up
@@ -6478,9 +6357,7 @@ class Parser(Tokenizer):
innerType = p[3]
promiseIdent = IDLUnresolvedIdentifier(self.getLocation(p, 1), "Promise")
type = IDLUnresolvedType(self.getLocation(p, 1), promiseIdent, p[3])
- if p[5]:
- type = IDLNullableType(self.getLocation(p, 5), type)
- p[0] = type
+ p[0] = self.handleNullable(type, p[5])
def p_NonAnyTypeMozMapType(self, p):
"""
@@ -6488,13 +6365,11 @@ class Parser(Tokenizer):
"""
innerType = p[3]
type = IDLMozMapType(self.getLocation(p, 1), innerType)
- if p[5]:
- type = IDLNullableType(self.getLocation(p, 5), type)
- p[0] = type
+ p[0] = self.handleNullable(type, p[5])
def p_NonAnyTypeScopedName(self, p):
"""
- NonAnyType : ScopedName TypeSuffix
+ NonAnyType : ScopedName Null
"""
assert isinstance(p[1], IDLUnresolvedIdentifier)
@@ -6516,29 +6391,27 @@ class Parser(Tokenizer):
type = IDLCallbackType(obj.location, obj)
else:
type = IDLWrapperType(self.getLocation(p, 1), p[1])
- p[0] = self.handleModifiers(type, p[2])
+ p[0] = self.handleNullable(type, p[2])
return
except:
pass
type = IDLUnresolvedType(self.getLocation(p, 1), p[1])
- p[0] = self.handleModifiers(type, p[2])
+ p[0] = self.handleNullable(type, p[2])
def p_NonAnyTypeDate(self, p):
"""
- NonAnyType : DATE TypeSuffix
+ NonAnyType : DATE Null
"""
- p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.date],
- p[2])
+ p[0] = self.handleNullable(BuiltinTypes[IDLBuiltinType.Types.date],
+ p[2])
def p_ConstType(self, p):
"""
ConstType : PrimitiveOrStringType Null
"""
type = BuiltinTypes[p[1]]
- if p[2]:
- type = IDLNullableType(self.getLocation(p, 1), type)
- p[0] = type
+ p[0] = self.handleNullable(type, p[2])
def p_ConstTypeIdentifier(self, p):
"""
@@ -6547,9 +6420,7 @@ class Parser(Tokenizer):
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1])
type = IDLUnresolvedType(self.getLocation(p, 1), identifier)
- if p[2]:
- type = IDLNullableType(self.getLocation(p, 1), type)
- p[0] = type
+ p[0] = self.handleNullable(type, p[2])
def p_PrimitiveOrStringTypeUint(self, p):
"""
@@ -6657,48 +6528,15 @@ class Parser(Tokenizer):
"""
p[0] = False
- def p_TypeSuffixBrackets(self, p):
- """
- TypeSuffix : LBRACKET RBRACKET TypeSuffix
- """
- p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))]
- p[0].extend(p[3])
-
- def p_TypeSuffixQMark(self, p):
- """
- TypeSuffix : QUESTIONMARK TypeSuffixStartingWithArray
- """
- p[0] = [(IDLMethod.TypeSuffixModifier.QMark, self.getLocation(p, 1))]
- p[0].extend(p[2])
-
- def p_TypeSuffixEmpty(self, p):
- """
- TypeSuffix :
- """
- p[0] = []
-
- def p_TypeSuffixStartingWithArray(self, p):
- """
- TypeSuffixStartingWithArray : LBRACKET RBRACKET TypeSuffix
- """
- p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))]
- p[0].extend(p[3])
-
- def p_TypeSuffixStartingWithArrayEmpty(self, p):
- """
- TypeSuffixStartingWithArray :
- """
- p[0] = []
-
def p_Null(self, p):
"""
Null : QUESTIONMARK
|
"""
if len(p) > 1:
- p[0] = True
+ p[0] = self.getLocation(p, 1)
else:
- p[0] = False
+ p[0] = None
def p_ReturnTypeType(self, p):
"""
@@ -6857,15 +6695,9 @@ class Parser(Tokenizer):
typedef = IDLTypedef(BuiltinLocation("<builtin type>"), scope, builtin, name)
@ staticmethod
- def handleModifiers(type, modifiers):
- for (modifier, modifierLocation) in modifiers:
- assert (modifier == IDLMethod.TypeSuffixModifier.QMark or
- modifier == IDLMethod.TypeSuffixModifier.Brackets)
-
- if modifier == IDLMethod.TypeSuffixModifier.QMark:
- type = IDLNullableType(modifierLocation, type)
- elif modifier == IDLMethod.TypeSuffixModifier.Brackets:
- type = IDLArrayType(modifierLocation, type)
+ def handleNullable(type, questionMarkLocation):
+ if questionMarkLocation is not None:
+ type = IDLNullableType(questionMarkLocation, type)
return type
diff --git a/components/script/dom/bindings/codegen/parser/bytestring.patch b/components/script/dom/bindings/codegen/parser/bytestring.patch
deleted file mode 100644
index 823f14cf996..00000000000
--- a/components/script/dom/bindings/codegen/parser/bytestring.patch
+++ /dev/null
@@ -1,29 +0,0 @@
---- WebIDL.py
-+++ WebIDL.py
-@@ -3391,6 +3391,11 @@ class IDLValue(IDLObject):
- # extra normalization step.
- assert self.type.isDOMString()
- return self
-+ elif self.type.isString() and type.isByteString():
-+ # Allow ByteStrings to use default value just like
-+ # DOMString. No coercion is required here.
-+ assert self.type.isDOMString()
-+ return self
- raise WebIDLError("Cannot coerce type %s to type %s." %
- (self.type, type), [location])
-
-@@ -5759,6 +5764,14 @@ class Parser(Tokenizer):
- booleanType = BuiltinTypes[IDLBuiltinType.Types.boolean]
- p[0] = IDLValue(location, booleanType, p[1])
-
-+ def p_ConstValueByteString(self, p):
-+ """
-+ ConstValue : BYTESTRING
-+ """
-+ location = self.getLocation(p, 1)
-+ bytestringType = BuiltinTypes[IDLBuiltinType.Types.bytestring]
-+ p[0] = IDLValue(location, bytestringType, p[1])
-+
- def p_ConstValueInteger(self, p):
- """
- ConstValue : INTEGER
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_array.py b/components/script/dom/bindings/codegen/parser/tests/test_array.py
deleted file mode 100644
index 8f9e9c96854..00000000000
--- a/components/script/dom/bindings/codegen/parser/tests/test_array.py
+++ /dev/null
@@ -1,18 +0,0 @@
-def WebIDLTest(parser, harness):
- threw = False
- try:
- parser.parse("""
- dictionary Foo {
- short a;
- };
-
- dictionary Foo1 {
- Foo[] b;
- };
- """)
- results = parser.finish()
- except:
- threw = True
-
- harness.ok(threw, "Array must not contain dictionary "
- "as element type.")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_array_of_interface.py b/components/script/dom/bindings/codegen/parser/tests/test_array_of_interface.py
deleted file mode 100644
index 26528984595..00000000000
--- a/components/script/dom/bindings/codegen/parser/tests/test_array_of_interface.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import WebIDL
-
-def WebIDLTest(parser, harness):
- parser.parse("""
- interface A {
- attribute long a;
- };
-
- interface B {
- attribute A[] b;
- };
- """);
- parser.finish()
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py b/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py
index 5b8e56f86ca..4a96c0ff512 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_arraybuffer.py
@@ -4,37 +4,37 @@ def WebIDLTest(parser, harness):
parser.parse("""
interface TestArrayBuffer {
attribute ArrayBuffer bufferAttr;
- void bufferMethod(ArrayBuffer arg1, ArrayBuffer? arg2, ArrayBuffer[] arg3, sequence<ArrayBuffer> arg4);
+ void bufferMethod(ArrayBuffer arg1, ArrayBuffer? arg2, sequence<ArrayBuffer> arg3);
attribute ArrayBufferView viewAttr;
- void viewMethod(ArrayBufferView arg1, ArrayBufferView? arg2, ArrayBufferView[] arg3, sequence<ArrayBufferView> arg4);
+ void viewMethod(ArrayBufferView arg1, ArrayBufferView? arg2, sequence<ArrayBufferView> arg3);
attribute Int8Array int8ArrayAttr;
- void int8ArrayMethod(Int8Array arg1, Int8Array? arg2, Int8Array[] arg3, sequence<Int8Array> arg4);
+ void int8ArrayMethod(Int8Array arg1, Int8Array? arg2, sequence<Int8Array> arg3);
attribute Uint8Array uint8ArrayAttr;
- void uint8ArrayMethod(Uint8Array arg1, Uint8Array? arg2, Uint8Array[] arg3, sequence<Uint8Array> arg4);
+ void uint8ArrayMethod(Uint8Array arg1, Uint8Array? arg2, sequence<Uint8Array> arg3);
attribute Uint8ClampedArray uint8ClampedArrayAttr;
- void uint8ClampedArrayMethod(Uint8ClampedArray arg1, Uint8ClampedArray? arg2, Uint8ClampedArray[] arg3, sequence<Uint8ClampedArray> arg4);
+ void uint8ClampedArrayMethod(Uint8ClampedArray arg1, Uint8ClampedArray? arg2, sequence<Uint8ClampedArray> arg3);
attribute Int16Array int16ArrayAttr;
- void int16ArrayMethod(Int16Array arg1, Int16Array? arg2, Int16Array[] arg3, sequence<Int16Array> arg4);
+ void int16ArrayMethod(Int16Array arg1, Int16Array? arg2, sequence<Int16Array> arg3);
attribute Uint16Array uint16ArrayAttr;
- void uint16ArrayMethod(Uint16Array arg1, Uint16Array? arg2, Uint16Array[] arg3, sequence<Uint16Array> arg4);
+ void uint16ArrayMethod(Uint16Array arg1, Uint16Array? arg2, sequence<Uint16Array> arg3);
attribute Int32Array int32ArrayAttr;
- void int32ArrayMethod(Int32Array arg1, Int32Array? arg2, Int32Array[] arg3, sequence<Int32Array> arg4);
+ void int32ArrayMethod(Int32Array arg1, Int32Array? arg2, sequence<Int32Array> arg3);
attribute Uint32Array uint32ArrayAttr;
- void uint32ArrayMethod(Uint32Array arg1, Uint32Array? arg2, Uint32Array[] arg3, sequence<Uint32Array> arg4);
+ void uint32ArrayMethod(Uint32Array arg1, Uint32Array? arg2, sequence<Uint32Array> arg3);
attribute Float32Array float32ArrayAttr;
- void float32ArrayMethod(Float32Array arg1, Float32Array? arg2, Float32Array[] arg3, sequence<Float32Array> arg4);
+ void float32ArrayMethod(Float32Array arg1, Float32Array? arg2, sequence<Float32Array> arg3);
attribute Float64Array float64ArrayAttr;
- void float64ArrayMethod(Float64Array arg1, Float64Array? arg2, Float64Array[] arg3, sequence<Float64Array> arg4);
+ void float64ArrayMethod(Float64Array arg1, Float64Array? arg2, sequence<Float64Array> arg3);
};
""")
@@ -56,7 +56,7 @@ def WebIDLTest(parser, harness):
(retType, arguments) = method.signatures()[0]
harness.ok(retType.isVoid(), "Should have a void return type")
- harness.check(len(arguments), 4, "Expect 4 arguments")
+ harness.check(len(arguments), 3, "Expect 3 arguments")
harness.check(str(arguments[0].type), t, "Expect an ArrayBuffer type")
harness.ok(arguments[0].type.isSpiderMonkeyInterface(), "Should test as a js interface")
@@ -64,12 +64,9 @@ def WebIDLTest(parser, harness):
harness.check(str(arguments[1].type), t + "OrNull", "Expect an ArrayBuffer type")
harness.ok(arguments[1].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
- harness.check(str(arguments[2].type), t + "Array", "Expect an ArrayBuffer type")
+ harness.check(str(arguments[2].type), t + "Sequence", "Expect an ArrayBuffer type")
harness.ok(arguments[2].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
- harness.check(str(arguments[3].type), t + "Sequence", "Expect an ArrayBuffer type")
- harness.ok(arguments[3].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
-
checkStuff(members[0], members[1], "ArrayBuffer")
checkStuff(members[2], members[3], "ArrayBufferView")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_attr.py b/components/script/dom/bindings/codegen/parser/tests/test_attr.py
index fb0c9196460..ad7aabc1918 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_attr.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_attr.py
@@ -77,110 +77,6 @@ def WebIDLTest(parser, harness):
attribute float? f;
readonly attribute float? rf;
};
-
- interface TestAttrArray {
- attribute byte[] b;
- readonly attribute byte[] rb;
- attribute octet[] o;
- readonly attribute octet[] ro;
- attribute short[] s;
- readonly attribute short[] rs;
- attribute unsigned short[] us;
- readonly attribute unsigned short[] rus;
- attribute long[] l;
- readonly attribute long[] rl;
- attribute unsigned long[] ul;
- readonly attribute unsigned long[] rul;
- attribute long long[] ll;
- readonly attribute long long[] rll;
- attribute unsigned long long[] ull;
- readonly attribute unsigned long long[] rull;
- attribute DOMString[] str;
- readonly attribute DOMString[] rstr;
- attribute object[] obj;
- readonly attribute object[] robj;
- attribute object[] _object;
- attribute float[] f;
- readonly attribute float[] rf;
- };
-
- interface TestAttrNullableArray {
- attribute byte[]? b;
- readonly attribute byte[]? rb;
- attribute octet[]? o;
- readonly attribute octet[]? ro;
- attribute short[]? s;
- readonly attribute short[]? rs;
- attribute unsigned short[]? us;
- readonly attribute unsigned short[]? rus;
- attribute long[]? l;
- readonly attribute long[]? rl;
- attribute unsigned long[]? ul;
- readonly attribute unsigned long[]? rul;
- attribute long long[]? ll;
- readonly attribute long long[]? rll;
- attribute unsigned long long[]? ull;
- readonly attribute unsigned long long[]? rull;
- attribute DOMString[]? str;
- readonly attribute DOMString[]? rstr;
- attribute object[]? obj;
- readonly attribute object[]? robj;
- attribute object[]? _object;
- attribute float[]? f;
- readonly attribute float[]? rf;
- };
-
- interface TestAttrArrayOfNullableTypes {
- attribute byte?[] b;
- readonly attribute byte?[] rb;
- attribute octet?[] o;
- readonly attribute octet?[] ro;
- attribute short?[] s;
- readonly attribute short?[] rs;
- attribute unsigned short?[] us;
- readonly attribute unsigned short?[] rus;
- attribute long?[] l;
- readonly attribute long?[] rl;
- attribute unsigned long?[] ul;
- readonly attribute unsigned long?[] rul;
- attribute long long?[] ll;
- readonly attribute long long?[] rll;
- attribute unsigned long long?[] ull;
- readonly attribute unsigned long long?[] rull;
- attribute DOMString?[] str;
- readonly attribute DOMString?[] rstr;
- attribute object?[] obj;
- readonly attribute object?[] robj;
- attribute object?[] _object;
- attribute float?[] f;
- readonly attribute float?[] rf;
- };
-
- interface TestAttrNullableArrayOfNullableTypes {
- attribute byte?[]? b;
- readonly attribute byte?[]? rb;
- attribute octet?[]? o;
- readonly attribute octet?[]? ro;
- attribute short?[]? s;
- readonly attribute short?[]? rs;
- attribute unsigned short?[]? us;
- readonly attribute unsigned short?[]? rus;
- attribute long?[]? l;
- readonly attribute long?[]? rl;
- attribute unsigned long?[]? ul;
- readonly attribute unsigned long?[]? rul;
- attribute long long?[]? ll;
- readonly attribute long long?[]? rll;
- attribute unsigned long long?[]? ull;
- readonly attribute unsigned long long?[]? rull;
- attribute DOMString?[]? str;
- readonly attribute DOMString?[]? rstr;
- attribute object?[]? obj;
- readonly attribute object?[]? robj;
- attribute object?[]? _object;
- attribute float?[]? f;
- readonly attribute float?[]? rf;
- };
""")
results = parser.finish()
@@ -197,7 +93,7 @@ def WebIDLTest(parser, harness):
harness.check(attr.readonly, readonly, "Attr's readonly state is correct")
harness.ok(True, "TestAttr interface parsed without error.")
- harness.check(len(results), 6, "Should be six productions.")
+ harness.check(len(results), 2, "Should be two productions.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
@@ -228,66 +124,6 @@ def WebIDLTest(parser, harness):
(QName, name, type, readonly) = data
checkAttr(attr, QName % "Nullable", name, type % "OrNull", readonly)
- iface = results[2]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestAttrArray", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestAttrArray", "Interface has the right name")
- harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
- attrs = iface.members
-
- for i in range(len(attrs)):
- data = testData[i]
- attr = attrs[i]
- (QName, name, type, readonly) = data
- checkAttr(attr, QName % "Array", name, type % "Array", readonly)
-
- iface = results[3]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestAttrNullableArray", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestAttrNullableArray", "Interface has the right name")
- harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
- attrs = iface.members
-
- for i in range(len(attrs)):
- data = testData[i]
- attr = attrs[i]
- (QName, name, type, readonly) = data
- checkAttr(attr, QName % "NullableArray", name, type % "ArrayOrNull", readonly)
-
- iface = results[4]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestAttrArrayOfNullableTypes", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestAttrArrayOfNullableTypes", "Interface has the right name")
- harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
- attrs = iface.members
-
- for i in range(len(attrs)):
- data = testData[i]
- attr = attrs[i]
- (QName, name, type, readonly) = data
- checkAttr(attr, QName % "ArrayOfNullableTypes", name, type % "OrNullArray", readonly)
-
- iface = results[5]
- harness.ok(isinstance(iface, WebIDL.IDLInterface),
- "Should be an IDLInterface")
- harness.check(iface.identifier.QName(), "::TestAttrNullableArrayOfNullableTypes", "Interface has the right QName")
- harness.check(iface.identifier.name, "TestAttrNullableArrayOfNullableTypes", "Interface has the right name")
- harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
-
- attrs = iface.members
-
- for i in range(len(attrs)):
- data = testData[i]
- attr = attrs[i]
- (QName, name, type, readonly) = data
- checkAttr(attr, QName % "NullableArrayOfNullableTypes", name, type % "OrNullArrayOrNull", readonly)
-
parser = parser.reset()
threw = False
try:
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py b/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py
index d73455f8812..fa83e9e2d57 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py
@@ -13,7 +13,7 @@ def WebIDLTest(parser, harness):
results = parser.finish();
harness.ok(True, "TestByteString interface parsed without error.")
-
+
harness.check(len(results), 1, "Should be one production")
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
"Should be an IDLInterface")
@@ -54,10 +54,9 @@ def WebIDLTest(parser, harness):
""")
except WebIDL.WebIDLError:
threw = True
- harness.ok(threw, "Should have thrown a WebIDL error")
+ harness.ok(threw, "Should have thrown a WebIDL error for ByteString default in interface")
- # Cannot have optional ByteStrings with default values
- threw = False
+ # Can have optional ByteStrings with default values
try:
parser.parse("""
interface OptionalByteString {
@@ -65,8 +64,36 @@ def WebIDLTest(parser, harness):
};
""")
results2 = parser.finish();
- except WebIDL.WebIDLError:
- threw = True
+ except WebIDL.WebIDLError as e:
+ harness.ok(False,
+ "Should not have thrown a WebIDL error for ByteString "
+ "default in dictionary. " + str(e))
- harness.ok(threw, "Should have thrown a WebIDL error")
+ # Can have a default ByteString value in a dictionary
+ try:
+ parser.parse("""
+ dictionary OptionalByteStringDict {
+ ByteString item = "some string";
+ };
+ """)
+ results3 = parser.finish();
+ except WebIDL.WebIDLError as e:
+ harness.ok(False,
+ "Should not have thrown a WebIDL error for ByteString "
+ "default in dictionary. " + str(e))
+
+ # Don't allow control characters in ByteString literals
+ threw = False
+ try:
+ parser.parse("""
+ dictionary OptionalByteStringDict2 {
+ ByteString item = "\x03";
+ };
+ """)
+ results4 = parser.finish()
+ except WebIDL.WebIDLError as e:
+ threw = True
+ harness.ok(threw,
+ "Should have thrown a WebIDL error for invalid ByteString "
+ "default in dictionary")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py b/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py
index 866816f2e0c..d7780c1ffa1 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py
@@ -159,7 +159,7 @@ def WebIDLTest(parser, harness):
"object", "Callback", "Callback2", "optional Dict",
"optional Dict2", "sequence<long>", "sequence<short>",
"MozMap<object>", "MozMap<Dict>", "MozMap<long>",
- "long[]", "short[]", "Date", "Date?", "any",
+ "Date", "Date?", "any",
"Promise<any>", "Promise<any>?",
"USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer",
"Uint8Array", "Uint16Array" ]
@@ -187,7 +187,6 @@ def WebIDLTest(parser, harness):
"Date?", "any", "Promise<any>?"]
dates = [ "Date", "Date?" ]
sequences = [ "sequence<long>", "sequence<short>" ]
- arrays = [ "long[]", "short[]" ]
nonUserObjects = nonObjects + interfaces + dates + sequences
otherObjects = allBut(argTypes, nonUserObjects + ["object"])
notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
@@ -229,14 +228,12 @@ def WebIDLTest(parser, harness):
setDistinguishable("optional Dict", allBut(nonUserObjects, nullables))
setDistinguishable("optional Dict2", allBut(nonUserObjects, nullables))
setDistinguishable("sequence<long>",
- allBut(argTypes, sequences + arrays + ["object"]))
+ allBut(argTypes, sequences + ["object"]))
setDistinguishable("sequence<short>",
- allBut(argTypes, sequences + arrays + ["object"]))
+ allBut(argTypes, sequences + ["object"]))
setDistinguishable("MozMap<object>", nonUserObjects)
setDistinguishable("MozMap<Dict>", nonUserObjects)
setDistinguishable("MozMap<long>", nonUserObjects)
- setDistinguishable("long[]", allBut(nonUserObjects, sequences))
- setDistinguishable("short[]", allBut(nonUserObjects, sequences))
setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
setDistinguishable("any", [])
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_method.py b/components/script/dom/bindings/codegen/parser/tests/test_method.py
index f6f54c33ab6..cf7f1b40d76 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_method.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_method.py
@@ -11,7 +11,6 @@ def WebIDLTest(parser, harness):
boolean basicBooleanWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
void optionalArg(optional byte? arg1, optional sequence<byte> arg2);
void variadicArg(byte?... arg1);
- void crazyTypes(sequence<long?[]>? arg1, boolean?[][]? arg2);
object getObject();
void setObject(object arg1);
void setAny(any arg1);
@@ -28,7 +27,7 @@ def WebIDLTest(parser, harness):
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestMethods", "Interface has the right QName")
harness.check(iface.identifier.name, "TestMethods", "Interface has the right name")
- harness.check(len(iface.members), 13, "Expect 13 members")
+ harness.check(len(iface.members), 12, "Expect 12 members")
methods = iface.members
@@ -98,22 +97,17 @@ def WebIDLTest(parser, harness):
"variadicArg",
[("Void",
[("::TestMethods::variadicArg::arg1", "arg1", "ByteOrNull", True, True)])])
- checkMethod(methods[8], "::TestMethods::crazyTypes",
- "crazyTypes",
- [("Void",
- [("::TestMethods::crazyTypes::arg1", "arg1", "LongOrNullArraySequenceOrNull", False, False),
- ("::TestMethods::crazyTypes::arg2", "arg2", "BooleanOrNullArrayArrayOrNull", False, False)])])
- checkMethod(methods[9], "::TestMethods::getObject",
+ checkMethod(methods[8], "::TestMethods::getObject",
"getObject", [("Object", [])])
- checkMethod(methods[10], "::TestMethods::setObject",
+ checkMethod(methods[9], "::TestMethods::setObject",
"setObject",
[("Void",
[("::TestMethods::setObject::arg1", "arg1", "Object", False, False)])])
- checkMethod(methods[11], "::TestMethods::setAny",
+ checkMethod(methods[10], "::TestMethods::setAny",
"setAny",
[("Void",
[("::TestMethods::setAny::arg1", "arg1", "Any", False, False)])])
- checkMethod(methods[12], "::TestMethods::doFloats",
+ checkMethod(methods[11], "::TestMethods::doFloats",
"doFloats",
[("Float",
[("::TestMethods::doFloats::arg1", "arg1", "Float", False, False)])])
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py b/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py
index 1f72b2c6e67..2b48b615dd4 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_nullable_equivalency.py
@@ -53,16 +53,6 @@ def WebIDLTest(parser, harness):
attribute object a;
attribute object? b;
};
-
- interface TestNullableEquivalency11 {
- attribute double[] a;
- attribute double[]? b;
- };
-
- interface TestNullableEquivalency12 {
- attribute TestNullableEquivalency9[] a;
- attribute TestNullableEquivalency9[]? b;
- };
""")
for decl in parser.finish():
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_union.py b/components/script/dom/bindings/codegen/parser/tests/test_union.py
index 36cacf3ccf4..9c4f2a56ab6 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_union.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_union.py
@@ -139,9 +139,6 @@ def WebIDLTest(parser, harness):
void method${i}(${type} arg);
${type} returnMethod${i}();
attribute ${type} attr${i};
- void arrayMethod${i}(${type}[] arg);
- ${type}[] arrayReturnMethod${i}();
- attribute ${type}[] arrayAttr${i};
void optionalMethod${i}(${type}? arg);
""").substitute(i=i, type=type)
interface += """
diff --git a/components/script/dom/bindings/codegen/parser/union-typedef.patch b/components/script/dom/bindings/codegen/parser/union-typedef.patch
new file mode 100644
index 00000000000..3021e14193f
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/union-typedef.patch
@@ -0,0 +1,22 @@
+--- WebIDL.py
++++ WebIDL.py
+@@ -2481,10 +2481,18 @@ class IDLUnionType(IDLType):
+ return type.name
+
+ for (i, type) in enumerate(self.memberTypes):
++ # Exclude typedefs because if given "typedef (B or C) test",
++ # we want AOrTest, not AOrBOrC
++ if not type.isComplete() and not isinstance(type, IDLTypedefType):
++ self.memberTypes[i] = type.complete(scope)
++
++ self.name = "Or".join(typeName(type) for type in self.memberTypes)
++
++ # We do this again to complete the typedef types
++ for (i, type) in enumerate(self.memberTypes):
+ if not type.isComplete():
+ self.memberTypes[i] = type.complete(scope)
+
+- self.name = "Or".join(typeName(type) for type in self.memberTypes)
+ self.flatMemberTypes = list(self.memberTypes)
+ i = 0
+ while i < len(self.flatMemberTypes):
diff --git a/components/script/dom/bindings/codegen/parser/update.sh b/components/script/dom/bindings/codegen/parser/update.sh
index ef1da728b13..6bf56cead30 100755
--- a/components/script/dom/bindings/codegen/parser/update.sh
+++ b/components/script/dom/bindings/codegen/parser/update.sh
@@ -3,7 +3,7 @@ patch < abstract.patch
patch < debug.patch
patch < pref-main-thread.patch
patch < callback-location.patch
-patch < bytestring.patch
+patch < union-typedef.patch
wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz
rm -r tests
diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs
index 9b4125bdc6a..5d679cce2e9 100644
--- a/components/script/dom/bindings/global.rs
+++ b/components/script/dom/bindings/global.rs
@@ -10,25 +10,29 @@
use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId};
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::root_from_object;
-use dom::bindings::error::ErrorInfo;
+use dom::bindings::error::{ErrorInfo, report_pending_exception};
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflectable, Reflector};
use dom::console::TimerSet;
-use dom::window::{self, ScriptHelpers};
+use dom::window;
use dom::workerglobalscope::WorkerGlobalScope;
use ipc_channel::ipc::IpcSender;
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
use js::glue::{IsWrapper, UnwrapObject};
-use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment};
-use js::jsapi::{JSContext, JSObject, JS_GetClass, MutableHandleValue};
-use js::jsapi::HandleValue;
+use js::jsapi::{CurrentGlobalOrNull, Evaluate2, GetGlobalForObjectCrossCompartment};
+use js::jsapi::{HandleValue, JS_GetClass, JSAutoCompartment, JSContext};
+use js::jsapi::{JSObject, MutableHandleValue};
+use js::rust::CompileOptionsWrapper;
+use libc;
use msg::constellation_msg::PipelineId;
use net_traits::{CoreResourceThread, IpcSend, ResourceThreads};
use profile_traits::{mem, time};
-use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, EnqueuedPromiseCallback};
+use script_runtime::{CommonScriptMsg, EnqueuedPromiseCallback, ScriptChan};
+use script_runtime::{ScriptPort, maybe_take_panic_result};
use script_thread::{MainThreadScriptChan, RunnableWrapper, ScriptThread};
use script_traits::{MsDuration, ScriptMsg as ConstellationMsg, TimerEventRequest};
-use task_source::dom_manipulation::DOMManipulationTaskSource;
+use std::ffi::CString;
+use std::panic;
use task_source::file_reading::FileReadingTaskSource;
use timers::{OneshotTimerCallback, OneshotTimerHandle};
use url::Url;
@@ -181,15 +185,6 @@ impl<'a> GlobalRef<'a> {
}
}
- /// `TaskSource` used to queue DOM manipulation messages to the event loop of this global's
- /// thread.
- pub fn dom_manipulation_task_source(&self) -> DOMManipulationTaskSource {
- match *self {
- GlobalRef::Window(ref window) => window.dom_manipulation_task_source(),
- GlobalRef::Worker(_) => unimplemented!(),
- }
- }
-
/// `ScriptChan` used to send messages to the event loop of this global's
/// thread.
pub fn networking_task_source(&self) -> Box<ScriptChan + Send> {
@@ -201,15 +196,6 @@ impl<'a> GlobalRef<'a> {
/// `ScriptChan` used to send messages to the event loop of this global's
/// thread.
- pub fn history_traversal_task_source(&self) -> Box<ScriptChan + Send> {
- match *self {
- GlobalRef::Window(ref window) => window.history_traversal_task_source(),
- GlobalRef::Worker(ref worker) => worker.script_chan(),
- }
- }
-
- /// `ScriptChan` used to send messages to the event loop of this global's
- /// thread.
pub fn file_reading_task_source(&self) -> FileReadingTaskSource {
match *self {
GlobalRef::Window(ref window) => window.file_reading_task_source(),
@@ -236,12 +222,51 @@ impl<'a> GlobalRef<'a> {
}
}
- /// Evaluate the JS messages on the `RootedValue` of this global
- pub fn evaluate_js_on_global_with_result(&self, code: &str, rval: MutableHandleValue) {
- match *self {
- GlobalRef::Window(window) => window.evaluate_js_on_global_with_result(code, rval),
- GlobalRef::Worker(worker) => worker.evaluate_js_on_global_with_result(code, rval),
- }
+ /// Evaluate JS code on this global.
+ pub fn evaluate_js_on_global_with_result(
+ &self, code: &str, rval: MutableHandleValue) {
+ self.evaluate_script_on_global_with_result(code, "", rval)
+ }
+
+ /// Evaluate a JS script on this global.
+ #[allow(unsafe_code)]
+ pub fn evaluate_script_on_global_with_result(
+ &self, code: &str, filename: &str, rval: MutableHandleValue) {
+ let metadata = time::TimerMetadata {
+ url: if filename.is_empty() {
+ self.get_url().as_str().into()
+ } else {
+ filename.into()
+ },
+ iframe: time::TimerMetadataFrameType::RootWindow,
+ incremental: time::TimerMetadataReflowType::FirstReflow,
+ };
+ time::profile(
+ time::ProfilerCategory::ScriptEvaluate,
+ Some(metadata),
+ self.time_profiler_chan().clone(),
+ || {
+ let cx = self.get_cx();
+ let globalhandle = self.reflector().get_jsobject();
+ let code: Vec<u16> = code.encode_utf16().collect();
+ let filename = CString::new(filename).unwrap();
+
+ let _ac = JSAutoCompartment::new(cx, globalhandle.get());
+ let options = CompileOptionsWrapper::new(cx, filename.as_ptr(), 1);
+ unsafe {
+ if !Evaluate2(cx, options.ptr, code.as_ptr(),
+ code.len() as libc::size_t,
+ rval) {
+ debug!("error evaluating JS string");
+ report_pending_exception(cx, true);
+ }
+ }
+
+ if let Some(error) = maybe_take_panic_result() {
+ panic::resume_unwind(error);
+ }
+ }
+ )
}
/// Set the `bool` value to indicate whether developer tools has requested
diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs
index cacac064376..b5230b1b81a 100644
--- a/components/script/dom/bindings/proxyhandler.rs
+++ b/components/script/dom/bindings/proxyhandler.rs
@@ -186,7 +186,7 @@ pub fn ensure_expando_object(cx: *mut JSContext, obj: HandleObject) -> *mut JSOb
/// Set the property descriptor's object to `obj` and set it to enumerable,
/// and writable if `readonly` is true.
-pub fn fill_property_descriptor(desc: &mut PropertyDescriptor,
+pub fn fill_property_descriptor(mut desc: MutableHandle<PropertyDescriptor>,
obj: *mut JSObject,
attrs: u32) {
desc.obj = obj;
diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs
index 2940a211bf3..42ad4c2730a 100644
--- a/components/script/dom/bluetooth.rs
+++ b/components/script/dom/bluetooth.rs
@@ -15,10 +15,13 @@ use dom::bindings::str::DOMString;
use dom::bluetoothadvertisingdata::BluetoothAdvertisingData;
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID};
+use dom::promise::Promise;
use ipc_channel::ipc::{self, IpcSender};
+use js::conversions::ToJSValConvertible;
use net_traits::bluetooth_scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence};
use net_traits::bluetooth_scanfilter::{RequestDeviceoptions, ServiceUUIDSequence};
use net_traits::bluetooth_thread::{BluetoothError, BluetoothMethodMsg};
+use std::rc::Rc;
const FILTER_EMPTY_ERROR: &'static str = "'filters' member, if present, must be nonempty to find any devices.";
const FILTER_ERROR: &'static str = "A filter must restrict the devices in some way.";
@@ -61,6 +64,22 @@ impl Bluetooth {
global_ref.as_window().bluetooth_thread()
}
+ fn request_device(&self, option: &RequestDeviceOptions) -> Fallible<Root<BluetoothDevice>> {
+ // Step 1.
+ // TODO(#4282): Reject promise.
+ if (option.filters.is_some() && option.acceptAllDevices) ||
+ (option.filters.is_none() && !option.acceptAllDevices) {
+ return Err(Type(OPTIONS_ERROR.to_owned()));
+ }
+ // Step 2.
+ if !option.acceptAllDevices {
+ return self.request_bluetooth_devices(&option.filters, &option.optionalServices);
+ }
+
+ self.request_bluetooth_devices(&None, &option.optionalServices)
+ // TODO(#4282): Step 3-5: Reject and resolve promise.
+ }
+
// https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices
fn request_bluetooth_devices(&self,
filters: &Option<Vec<BluetoothRequestDeviceFilter>>,
@@ -69,7 +88,7 @@ impl Bluetooth {
// TODO: Step 1: Triggered by user activation.
// Step 2.
- let option = try!(convert_request_device_options(self.global().r(), filters, optional_services));
+ let option = try!(convert_request_device_options(filters, optional_services));
// TODO: Step 3-5: Implement the permission API.
@@ -104,8 +123,7 @@ impl Bluetooth {
}
// https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices
-fn convert_request_device_options(global: GlobalRef,
- filters: &Option<Vec<BluetoothRequestDeviceFilter>>,
+fn convert_request_device_options(filters: &Option<Vec<BluetoothRequestDeviceFilter>>,
optional_services: &Option<Vec<BluetoothServiceUUID>>)
-> Fallible<RequestDeviceoptions> {
// Step 2.2: There is no requiredServiceUUIDS, we scan for all devices.
@@ -122,7 +140,7 @@ fn convert_request_device_options(global: GlobalRef,
// Step 2.4.
for filter in filters {
// Step 2.4.8.
- uuid_filters.push(try!(canonicalize_filter(&filter, global)));
+ uuid_filters.push(try!(canonicalize_filter(&filter)));
}
}
@@ -130,7 +148,7 @@ fn convert_request_device_options(global: GlobalRef,
if let &Some(ref opt_services) = optional_services {
for opt_service in opt_services {
// Step 2.5 - 2.6.
- let uuid = try!(BluetoothUUID::GetService(global, opt_service.clone())).to_string();
+ let uuid = try!(BluetoothUUID::service(opt_service.clone())).to_string();
// Step 2.7.
// Note: What we are doing here is adding the not blacklisted UUIDs to the result vector,
@@ -146,7 +164,7 @@ fn convert_request_device_options(global: GlobalRef,
}
// https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices
-fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter, global: GlobalRef) -> Fallible<BluetoothScanfilter> {
+fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter) -> Fallible<BluetoothScanfilter> {
// Step 2.4.1.
if filter.services.is_none() &&
filter.name.is_none() &&
@@ -171,7 +189,7 @@ fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter, global: GlobalRef)
for service in services {
// Step 2.4.3.2 - 2.4.3.3.
- let uuid = try!(BluetoothUUID::GetService(global, service.clone())).to_string();
+ let uuid = try!(BluetoothUUID::service(service.clone())).to_string();
// Step 2.4.3.4.
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
@@ -232,7 +250,7 @@ fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter, global: GlobalRef)
let service_data_uuid = match filter.serviceDataUUID {
Some(ref service_data_uuid) => {
// Step 2.4.7.1 - 2.4.7.2.
- let uuid = try!(BluetoothUUID::GetService(global, service_data_uuid.clone())).to_string();
+ let uuid = try!(BluetoothUUID::service(service_data_uuid.clone())).to_string();
// Step 2.4.7.3.
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
@@ -252,6 +270,18 @@ fn canonicalize_filter(filter: &BluetoothRequestDeviceFilter, global: GlobalRef)
service_data_uuid))
}
+#[allow(unrooted_must_root)]
+pub fn result_to_promise<T: ToJSValConvertible>(global_ref: GlobalRef,
+ bluetooth_result: Fallible<T>)
+ -> Rc<Promise> {
+ let p = Promise::new(global_ref);
+ match bluetooth_result {
+ Ok(v) => p.resolve_native(p.global().r().get_cx(), &v),
+ Err(e) => p.reject_error(p.global().r().get_cx(), e),
+ }
+ p
+}
+
impl From<BluetoothError> for Error {
fn from(error: BluetoothError) -> Self {
match error {
@@ -265,20 +295,9 @@ impl From<BluetoothError> for Error {
}
impl BluetoothMethods for Bluetooth {
+ #[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
- fn RequestDevice(&self, option: &RequestDeviceOptions) -> Fallible<Root<BluetoothDevice>> {
- // Step 1.
- // TODO(#4282): Reject promise.
- if (option.filters.is_some() && option.acceptAllDevices) ||
- (option.filters.is_none() && !option.acceptAllDevices) {
- return Err(Type(OPTIONS_ERROR.to_owned()));
- }
- // Step 2.
- if !option.acceptAllDevices {
- return self.request_bluetooth_devices(&option.filters, &option.optionalServices);
- }
-
- self.request_bluetooth_devices(&None, &option.optionalServices)
- // TODO(#4282): Step 3-5: Reject and resolve promise.
+ fn RequestDevice(&self, option: &RequestDeviceOptions) -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.request_device(option))
}
}
diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs
index 15ca7af2235..6b7ba1dcfad 100644
--- a/components/script/dom/bluetoothremotegattcharacteristic.rs
+++ b/components/script/dom/bluetoothremotegattcharacteristic.rs
@@ -18,12 +18,15 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, DOMString};
+use dom::bluetooth::result_to_promise;
use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties;
use dom::bluetoothremotegattdescriptor::BluetoothRemoteGATTDescriptor;
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
use dom::bluetoothuuid::{BluetoothDescriptorUUID, BluetoothUUID};
+use dom::promise::Promise;
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_thread::BluetoothMethodMsg;
+use std::rc::Rc;
// Maximum length of an attribute value.
// https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=286439 (Vol. 3, page 2169)
@@ -79,27 +82,10 @@ impl BluetoothRemoteGATTCharacteristic {
fn get_instance_id(&self) -> String {
self.instance_id.clone()
}
-}
-
-impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteristic {
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-properties
- fn Properties(&self) -> Root<BluetoothCharacteristicProperties> {
- self.properties.get()
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-service
- fn Service(&self) -> Root<BluetoothRemoteGATTService> {
- self.service.get()
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-uuid
- fn Uuid(&self) -> DOMString {
- self.uuid.clone()
- }
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor
- fn GetDescriptor(&self, descriptor: BluetoothDescriptorUUID) -> Fallible<Root<BluetoothRemoteGATTDescriptor>> {
- let uuid = try!(BluetoothUUID::GetDescriptor(self.global().r(), descriptor)).to_string();
+ fn get_descriptor(&self, descriptor: BluetoothDescriptorUUID) -> Fallible<Root<BluetoothRemoteGATTDescriptor>> {
+ let uuid = try!(BluetoothUUID::descriptor(descriptor)).to_string();
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
return Err(Security)
}
@@ -121,12 +107,12 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors
- fn GetDescriptors(&self,
- descriptor: Option<BluetoothDescriptorUUID>)
- -> Fallible<Vec<Root<BluetoothRemoteGATTDescriptor>>> {
+ fn get_descriptors(&self,
+ descriptor: Option<BluetoothDescriptorUUID>)
+ -> Fallible<Vec<Root<BluetoothRemoteGATTDescriptor>>> {
let mut uuid: Option<String> = None;
if let Some(d) = descriptor {
- uuid = Some(try!(BluetoothUUID::GetDescriptor(self.global().r(), d)).to_string());
+ uuid = Some(try!(BluetoothUUID::descriptor(d)).to_string());
if let Some(ref uuid) = uuid {
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
return Err(Security)
@@ -152,13 +138,8 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
}
}
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-value
- fn GetValue(&self) -> Option<ByteString> {
- self.value.borrow().clone()
- }
-
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue
- fn ReadValue(&self) -> Fallible<ByteString> {
+ fn read_value(&self) -> Fallible<ByteString> {
if uuid_is_blacklisted(self.uuid.as_ref(), Blacklist::Reads) {
return Err(Security)
}
@@ -185,7 +166,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue
- fn WriteValue(&self, value: Vec<u8>) -> ErrorResult {
+ fn write_value(&self, value: Vec<u8>) -> ErrorResult {
if uuid_is_blacklisted(self.uuid.as_ref(), Blacklist::Writes) {
return Err(Security)
}
@@ -213,3 +194,51 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
}
}
}
+
+impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteristic {
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-properties
+ fn Properties(&self) -> Root<BluetoothCharacteristicProperties> {
+ self.properties.get()
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-service
+ fn Service(&self) -> Root<BluetoothRemoteGATTService> {
+ self.service.get()
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-uuid
+ fn Uuid(&self) -> DOMString {
+ self.uuid.clone()
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor
+ fn GetDescriptor(&self, descriptor: BluetoothDescriptorUUID) -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.get_descriptor(descriptor))
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors
+ fn GetDescriptors(&self,
+ descriptor: Option<BluetoothDescriptorUUID>)
+ -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.get_descriptors(descriptor))
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-value
+ fn GetValue(&self) -> Option<ByteString> {
+ self.value.borrow().clone()
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue
+ fn ReadValue(&self) -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.read_value())
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue
+ fn WriteValue(&self, value: Vec<u8>) -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.write_value(value))
+ }
+}
diff --git a/components/script/dom/bluetoothremotegattdescriptor.rs b/components/script/dom/bluetoothremotegattdescriptor.rs
index 99065a9aec0..d036f8bd9ea 100644
--- a/components/script/dom/bluetoothremotegattdescriptor.rs
+++ b/components/script/dom/bluetoothremotegattdescriptor.rs
@@ -17,9 +17,12 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, DOMString};
+use dom::bluetooth::result_to_promise;
use dom::bluetoothremotegattcharacteristic::{BluetoothRemoteGATTCharacteristic, MAXIMUM_ATTRIBUTE_LENGTH};
+use dom::promise::Promise;
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_thread::BluetoothMethodMsg;
+use std::rc::Rc;
// http://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattdescriptor
#[dom_struct]
@@ -66,26 +69,9 @@ impl BluetoothRemoteGATTDescriptor {
fn get_instance_id(&self) -> String {
self.instance_id.clone()
}
-}
-
-impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-characteristic
- fn Characteristic(&self) -> Root<BluetoothRemoteGATTCharacteristic> {
- self.characteristic.get()
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-uuid
- fn Uuid(&self) -> DOMString {
- self.uuid.clone()
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-value
- fn GetValue(&self) -> Option<ByteString> {
- self.value.borrow().clone()
- }
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue
- fn ReadValue(&self) -> Fallible<ByteString> {
+ fn read_value(&self) -> Fallible<ByteString> {
if uuid_is_blacklisted(self.uuid.as_ref(), Blacklist::Reads) {
return Err(Security)
}
@@ -109,7 +95,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue
- fn WriteValue(&self, value: Vec<u8>) -> ErrorResult {
+ fn write_value(&self, value: Vec<u8>) -> ErrorResult {
if uuid_is_blacklisted(self.uuid.as_ref(), Blacklist::Writes) {
return Err(Security)
}
@@ -131,3 +117,32 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
}
}
}
+
+impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-characteristic
+ fn Characteristic(&self) -> Root<BluetoothRemoteGATTCharacteristic> {
+ self.characteristic.get()
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-uuid
+ fn Uuid(&self) -> DOMString {
+ self.uuid.clone()
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-value
+ fn GetValue(&self) -> Option<ByteString> {
+ self.value.borrow().clone()
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue
+ fn ReadValue(&self) -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.read_value())
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue
+ fn WriteValue(&self, value: Vec<u8>) -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.write_value(value))
+ }
+}
diff --git a/components/script/dom/bluetoothremotegattserver.rs b/components/script/dom/bluetoothremotegattserver.rs
index 615094623e9..3439ba53350 100644
--- a/components/script/dom/bluetoothremotegattserver.rs
+++ b/components/script/dom/bluetoothremotegattserver.rs
@@ -12,12 +12,15 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
+use dom::bluetooth::result_to_promise;
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID};
+use dom::promise::Promise;
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_thread::BluetoothMethodMsg;
use std::cell::Cell;
+use std::rc::Rc;
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattserver
#[dom_struct]
@@ -47,21 +50,9 @@ impl BluetoothRemoteGATTServer {
let global_ref = global_root.r();
global_ref.as_window().bluetooth_thread()
}
-}
-
-impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-device
- fn Device(&self) -> Root<BluetoothDevice> {
- self.device.get()
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connected
- fn Connected(&self) -> bool {
- self.connected.get()
- }
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect
- fn Connect(&self) -> Fallible<Root<BluetoothRemoteGATTServer>> {
+ fn connect(&self) -> Fallible<Root<BluetoothRemoteGATTServer>> {
let (sender, receiver) = ipc::channel().unwrap();
self.get_bluetooth_thread().send(
BluetoothMethodMsg::GATTServerConnect(String::from(self.Device().Id()), sender)).unwrap();
@@ -77,26 +68,9 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
}
}
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-disconnect
- fn Disconnect(&self) -> ErrorResult {
- let (sender, receiver) = ipc::channel().unwrap();
- self.get_bluetooth_thread().send(
- BluetoothMethodMsg::GATTServerDisconnect(String::from(self.Device().Id()), sender)).unwrap();
- let server = receiver.recv().unwrap();
- match server {
- Ok(connected) => {
- self.connected.set(connected);
- Ok(())
- },
- Err(error) => {
- Err(Error::from(error))
- },
- }
- }
-
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice
- fn GetPrimaryService(&self, service: BluetoothServiceUUID) -> Fallible<Root<BluetoothRemoteGATTService>> {
- let uuid = try!(BluetoothUUID::GetService(self.global().r(), service)).to_string();
+ fn get_primary_service(&self, service: BluetoothServiceUUID) -> Fallible<Root<BluetoothRemoteGATTService>> {
+ let uuid = try!(BluetoothUUID::service(service)).to_string();
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
return Err(Security)
}
@@ -119,12 +93,12 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices
- fn GetPrimaryServices(&self,
- service: Option<BluetoothServiceUUID>)
- -> Fallible<Vec<Root<BluetoothRemoteGATTService>>> {
+ fn get_primary_services(&self,
+ service: Option<BluetoothServiceUUID>)
+ -> Fallible<Vec<Root<BluetoothRemoteGATTService>>> {
let mut uuid: Option<String> = None;
if let Some(s) = service {
- uuid = Some(try!(BluetoothUUID::GetService(self.global().r(), s)).to_string());
+ uuid = Some(try!(BluetoothUUID::service(s)).to_string());
if let Some(ref uuid) = uuid {
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
return Err(Security)
@@ -151,3 +125,52 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
}
}
}
+
+impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-device
+ fn Device(&self) -> Root<BluetoothDevice> {
+ self.device.get()
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connected
+ fn Connected(&self) -> bool {
+ self.connected.get()
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect
+ fn Connect(&self) -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.connect())
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-disconnect
+ fn Disconnect(&self) -> ErrorResult {
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.get_bluetooth_thread().send(
+ BluetoothMethodMsg::GATTServerDisconnect(String::from(self.Device().Id()), sender)).unwrap();
+ let server = receiver.recv().unwrap();
+ match server {
+ Ok(connected) => {
+ self.connected.set(connected);
+ Ok(())
+ },
+ Err(error) => {
+ Err(Error::from(error))
+ },
+ }
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice
+ fn GetPrimaryService(&self, service: BluetoothServiceUUID) -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.get_primary_service(service))
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices
+ fn GetPrimaryServices(&self,
+ service: Option<BluetoothServiceUUID>)
+ -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.get_primary_services(service))
+ }
+}
diff --git a/components/script/dom/bluetoothremotegattservice.rs b/components/script/dom/bluetoothremotegattservice.rs
index a39bb4fdfd5..3ece2507cd3 100644
--- a/components/script/dom/bluetoothremotegattservice.rs
+++ b/components/script/dom/bluetoothremotegattservice.rs
@@ -11,12 +11,15 @@ use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
+use dom::bluetooth::result_to_promise;
use dom::bluetoothcharacteristicproperties::BluetoothCharacteristicProperties;
use dom::bluetoothdevice::BluetoothDevice;
use dom::bluetoothremotegattcharacteristic::BluetoothRemoteGATTCharacteristic;
use dom::bluetoothuuid::{BluetoothCharacteristicUUID, BluetoothServiceUUID, BluetoothUUID};
+use dom::promise::Promise;
use ipc_channel::ipc::{self, IpcSender};
use net_traits::bluetooth_thread::BluetoothMethodMsg;
+use std::rc::Rc;
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattservice
#[dom_struct]
@@ -66,29 +69,12 @@ impl BluetoothRemoteGATTService {
fn get_instance_id(&self) -> String {
self.instance_id.clone()
}
-}
-
-impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-device
- fn Device(&self) -> Root<BluetoothDevice> {
- self.device.get()
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-isprimary
- fn IsPrimary(&self) -> bool {
- self.is_primary
- }
-
- // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-uuid
- fn Uuid(&self) -> DOMString {
- self.uuid.clone()
- }
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic
- fn GetCharacteristic(&self,
- characteristic: BluetoothCharacteristicUUID)
- -> Fallible<Root<BluetoothRemoteGATTCharacteristic>> {
- let uuid = try!(BluetoothUUID::GetCharacteristic(self.global().r(), characteristic)).to_string();
+ fn get_characteristic(&self,
+ characteristic: BluetoothCharacteristicUUID)
+ -> Fallible<Root<BluetoothRemoteGATTCharacteristic>> {
+ let uuid = try!(BluetoothUUID::characteristic(characteristic)).to_string();
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
return Err(Security)
}
@@ -121,12 +107,12 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristics
- fn GetCharacteristics(&self,
- characteristic: Option<BluetoothCharacteristicUUID>)
- -> Fallible<Vec<Root<BluetoothRemoteGATTCharacteristic>>> {
+ fn get_characteristics(&self,
+ characteristic: Option<BluetoothCharacteristicUUID>)
+ -> Fallible<Vec<Root<BluetoothRemoteGATTCharacteristic>>> {
let mut uuid: Option<String> = None;
if let Some(c) = characteristic {
- uuid = Some(try!(BluetoothUUID::GetCharacteristic(self.global().r(), c)).to_string());
+ uuid = Some(try!(BluetoothUUID::characteristic(c)).to_string());
if let Some(ref uuid) = uuid {
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
return Err(Security)
@@ -166,10 +152,10 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservice
- fn GetIncludedService(&self,
- service: BluetoothServiceUUID)
- -> Fallible<Root<BluetoothRemoteGATTService>> {
- let uuid = try!(BluetoothUUID::GetService(self.global().r(), service)).to_string();
+ fn get_included_service(&self,
+ service: BluetoothServiceUUID)
+ -> Fallible<Root<BluetoothRemoteGATTService>> {
+ let uuid = try!(BluetoothUUID::service(service)).to_string();
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
return Err(Security)
}
@@ -194,12 +180,12 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservices
- fn GetIncludedServices(&self,
- service: Option<BluetoothServiceUUID>)
- -> Fallible<Vec<Root<BluetoothRemoteGATTService>>> {
+ fn get_included_services(&self,
+ service: Option<BluetoothServiceUUID>)
+ -> Fallible<Vec<Root<BluetoothRemoteGATTService>>> {
let mut uuid: Option<String> = None;
if let Some(s) = service {
- uuid = Some(try!(BluetoothUUID::GetService(self.global().r(), s)).to_string());
+ uuid = Some(try!(BluetoothUUID::service(s)).to_string());
if let Some(ref uuid) = uuid {
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
return Err(Security)
@@ -228,3 +214,52 @@ impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
}
}
}
+
+impl BluetoothRemoteGATTServiceMethods for BluetoothRemoteGATTService {
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-device
+ fn Device(&self) -> Root<BluetoothDevice> {
+ self.device.get()
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-isprimary
+ fn IsPrimary(&self) -> bool {
+ self.is_primary
+ }
+
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-uuid
+ fn Uuid(&self) -> DOMString {
+ self.uuid.clone()
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic
+ fn GetCharacteristic(&self,
+ characteristic: BluetoothCharacteristicUUID)
+ -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.get_characteristic(characteristic))
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristics
+ fn GetCharacteristics(&self,
+ characteristic: Option<BluetoothCharacteristicUUID>)
+ -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.get_characteristics(characteristic))
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservice
+ fn GetIncludedService(&self,
+ service: BluetoothServiceUUID)
+ -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.get_included_service(service))
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getincludedservices
+ fn GetIncludedServices(&self,
+ service: Option<BluetoothServiceUUID>)
+ -> Rc<Promise> {
+ result_to_promise(self.global().r(), self.get_included_services(service))
+ }
+}
diff --git a/components/script/dom/bluetoothuuid.rs b/components/script/dom/bluetoothuuid.rs
index dafda71a12b..e9669cc8acb 100644
--- a/components/script/dom/bluetoothuuid.rs
+++ b/components/script/dom/bluetoothuuid.rs
@@ -272,60 +272,36 @@ const VALID_UUID_REGEX: &'static str = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-
impl BluetoothUUID {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-canonicaluuid
pub fn CanonicalUUID(_: GlobalRef, alias: u32) -> UUID {
- DOMString::from(format!("{:08x}", &alias) + BASE_UUID)
+ canonical_uuid(alias)
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-getservice
- pub fn GetService(globalref: GlobalRef, name: BluetoothServiceUUID) -> Fallible<UUID> {
- BluetoothUUID::resolve_uuid_name(globalref,
- name,
- BLUETOOTH_ASSIGNED_SERVICES,
- DOMString::from(SERVICE_PREFIX))
+ pub fn GetService(_: GlobalRef, name: BluetoothServiceUUID) -> Fallible<UUID> {
+ Self::service(name)
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-getcharacteristic
- pub fn GetCharacteristic(globalref: GlobalRef, name: BluetoothCharacteristicUUID) -> Fallible<UUID> {
- BluetoothUUID::resolve_uuid_name(globalref,
- name,
- BLUETOOTH_ASSIGNED_CHARCTERISTICS,
- DOMString::from(CHARACTERISTIC_PREFIX))
+ pub fn GetCharacteristic(_: GlobalRef, name: BluetoothCharacteristicUUID) -> Fallible<UUID> {
+ Self::characteristic(name)
}
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothuuid-getdescriptor
- pub fn GetDescriptor(globalref: GlobalRef, name: BluetoothDescriptorUUID) -> Fallible<UUID> {
- BluetoothUUID::resolve_uuid_name(globalref,
- name,
- BLUETOOTH_ASSIGNED_DESCRIPTORS,
- DOMString::from(DESCRIPTOR_PREFIX))
+ pub fn GetDescriptor(_: GlobalRef, name: BluetoothDescriptorUUID) -> Fallible<UUID> {
+ Self::descriptor(name)
}
+}
- // https://webbluetoothcg.github.io/web-bluetooth/#resolveuuidname
- pub fn resolve_uuid_name(globalref: GlobalRef,
- name: StringOrUnsignedLong,
- assigned_numbers_table: &'static [(&'static str, u32)],
- prefix: DOMString)
- -> Fallible<DOMString> {
- match name {
- // Step 1
- StringOrUnsignedLong::UnsignedLong(unsigned32) => {
- Ok(BluetoothUUID::CanonicalUUID(globalref, unsigned32))
- },
- StringOrUnsignedLong::String(dstring) => {
- // Step 2
- let regex = Regex::new(VALID_UUID_REGEX).unwrap();
- if regex.is_match(&*dstring) {
- Ok(dstring)
- } else {
- // Step 3
- let concatenated = format!("{}.{}", prefix, dstring);
- let is_in_table = assigned_numbers_table.iter().find(|p| p.0 == concatenated);
- match is_in_table {
- Some(&(_, alias)) => Ok(BluetoothUUID::CanonicalUUID(globalref, alias)),
- None => Err(Syntax),
- }
- }
- },
- }
+impl BluetoothUUID {
+ pub fn service(name: BluetoothServiceUUID) -> Fallible<UUID> {
+ resolve_uuid_name(name, BLUETOOTH_ASSIGNED_SERVICES, SERVICE_PREFIX)
+ }
+
+ pub fn characteristic(name: BluetoothServiceUUID) -> Fallible<UUID> {
+ resolve_uuid_name(name, BLUETOOTH_ASSIGNED_CHARCTERISTICS, CHARACTERISTIC_PREFIX)
+ }
+
+ pub fn descriptor(name: BluetoothDescriptorUUID) -> Fallible<UUID> {
+ resolve_uuid_name(name, BLUETOOTH_ASSIGNED_DESCRIPTORS, DESCRIPTOR_PREFIX)
}
}
@@ -337,3 +313,36 @@ impl Clone for StringOrUnsignedLong {
}
}
}
+
+fn canonical_uuid(alias: u32) -> UUID {
+ UUID::from(format!("{:08x}", &alias) + BASE_UUID)
+}
+
+// https://webbluetoothcg.github.io/web-bluetooth/#resolveuuidname
+fn resolve_uuid_name(
+ name: StringOrUnsignedLong,
+ assigned_numbers_table: &'static [(&'static str, u32)],
+ prefix: &str)
+ -> Fallible<DOMString> {
+ match name {
+ // Step 1
+ StringOrUnsignedLong::UnsignedLong(unsigned32) => {
+ Ok(canonical_uuid(unsigned32))
+ },
+ StringOrUnsignedLong::String(dstring) => {
+ // Step 2
+ let regex = Regex::new(VALID_UUID_REGEX).unwrap();
+ if regex.is_match(&*dstring) {
+ Ok(dstring)
+ } else {
+ // Step 3
+ let concatenated = format!("{}.{}", prefix, dstring);
+ let is_in_table = assigned_numbers_table.iter().find(|p| p.0 == concatenated);
+ match is_in_table {
+ Some(&(_, alias)) => Ok(canonical_uuid(alias)),
+ None => Err(Syntax),
+ }
+ }
+ },
+ }
+}
diff --git a/components/script/dom/browsingcontext.rs b/components/script/dom/browsingcontext.rs
index 02d153296ae..36179279967 100644
--- a/components/script/dom/browsingcontext.rs
+++ b/components/script/dom/browsingcontext.rs
@@ -256,7 +256,7 @@ unsafe extern "C" fn getOwnPropertyDescriptor(cx: *mut JSContext,
rooted!(in(cx) let mut val = UndefinedValue());
window.to_jsval(cx, val.handle_mut());
desc.value = val.get();
- fill_property_descriptor(&mut desc, proxy.get(), JSPROP_READONLY);
+ fill_property_descriptor(desc, proxy.get(), JSPROP_READONLY);
return true;
}
diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs
index c425c38b86b..49a46b88575 100644
--- a/components/script/dom/dedicatedworkerglobalscope.rs
+++ b/components/script/dom/dedicatedworkerglobalscope.rs
@@ -17,10 +17,6 @@ use dom::bindings::js::{Root, RootCollection};
use dom::bindings::reflector::Reflectable;
use dom::bindings::str::DOMString;
use dom::bindings::structuredclone::StructuredCloneData;
-use dom::errorevent::ErrorEvent;
-use dom::event::{Event, EventBubbles, EventCancelable};
-use dom::eventdispatcher::EventStatus;
-use dom::eventtarget::EventTarget;
use dom::messageevent::MessageEvent;
use dom::worker::{TrustedWorkerAddress, WorkerErrorHandler, WorkerMessageHandler};
use dom::workerglobalscope::WorkerGlobalScope;
@@ -36,7 +32,6 @@ use rand::random;
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, StackRootTLS, get_reports, new_rt_and_cx};
use script_runtime::ScriptThreadEventCategory::WorkerEvent;
use script_traits::{TimerEvent, TimerSource, WorkerGlobalScopeInit, WorkerScriptLoadOrigin};
-use std::cell::Cell;
use std::mem::replace;
use std::sync::{Arc, Mutex};
use std::sync::atomic::AtomicBool;
@@ -81,7 +76,6 @@ enum MixedMessage {
#[dom_struct]
pub struct DedicatedWorkerGlobalScope {
workerglobalscope: WorkerGlobalScope,
- id: PipelineId,
#[ignore_heap_size_of = "Defined in std"]
receiver: Receiver<(TrustedWorkerAddress, WorkerScriptMsg)>,
#[ignore_heap_size_of = "Defined in std"]
@@ -93,14 +87,11 @@ pub struct DedicatedWorkerGlobalScope {
#[ignore_heap_size_of = "Can't measure trait objects"]
/// Sender to the parent thread.
parent_sender: Box<ScriptChan + Send>,
- /// https://html.spec.whatwg.org/multipage/#in-error-reporting-mode
- in_error_reporting_mode: Cell<bool>
}
impl DedicatedWorkerGlobalScope {
fn new_inherited(init: WorkerGlobalScopeInit,
worker_url: Url,
- id: PipelineId,
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
runtime: Runtime,
parent_sender: Box<ScriptChan + Send>,
@@ -117,19 +108,16 @@ impl DedicatedWorkerGlobalScope {
from_devtools_receiver,
timer_event_chan,
Some(closing)),
- id: id,
receiver: receiver,
own_sender: own_sender,
timer_event_port: timer_event_port,
parent_sender: parent_sender,
worker: DOMRefCell::new(None),
- in_error_reporting_mode: Cell::new(false),
}
}
pub fn new(init: WorkerGlobalScopeInit,
worker_url: Url,
- id: PipelineId,
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
runtime: Runtime,
parent_sender: Box<ScriptChan + Send>,
@@ -142,7 +130,6 @@ impl DedicatedWorkerGlobalScope {
let cx = runtime.cx();
let scope = box DedicatedWorkerGlobalScope::new_inherited(init,
worker_url,
- id,
from_devtools_receiver,
runtime,
parent_sender,
@@ -157,7 +144,6 @@ impl DedicatedWorkerGlobalScope {
#[allow(unsafe_code)]
pub fn run_worker_scope(init: WorkerGlobalScopeInit,
worker_url: Url,
- id: PipelineId,
from_devtools_receiver: IpcReceiver<DevtoolScriptControlMsg>,
worker_rt_for_mainthread: Arc<Mutex<Option<SharedRt>>>,
worker: TrustedWorkerAddress,
@@ -170,7 +156,7 @@ impl DedicatedWorkerGlobalScope {
let name = format!("WebWorker for {}", serialized_worker_url);
spawn_named(name, move || {
thread_state::initialize(thread_state::SCRIPT | thread_state::IN_WORKER);
- PipelineId::install(id);
+ PipelineId::install(init.pipeline_id);
let roots = RootCollection::new();
let _stack_roots_tls = StackRootTLS::new(&roots);
@@ -204,7 +190,7 @@ impl DedicatedWorkerGlobalScope {
});
let global = DedicatedWorkerGlobalScope::new(
- init, url, id, devtools_mpsc_port, runtime,
+ init, url, devtools_mpsc_port, runtime,
parent_sender.clone(), own_sender, receiver,
timer_ipc_chan, timer_rx, closing);
// FIXME(njn): workers currently don't have a unique ID suitable for using in reporter
@@ -244,10 +230,6 @@ impl DedicatedWorkerGlobalScope {
}
}
- pub fn pipeline_id(&self) -> PipelineId {
- self.id
- }
-
pub fn new_script_pair(&self) -> (Box<ScriptChan + Send>, Box<ScriptPort + Send>) {
let (tx, rx) = channel();
let chan = box SendableWorkerScriptChan {
@@ -348,43 +330,13 @@ impl DedicatedWorkerGlobalScope {
}
}
- /// https://html.spec.whatwg.org/multipage/#report-the-error
- pub fn report_an_error(&self, error_info: ErrorInfo, value: HandleValue) {
- // Step 1.
- if self.in_error_reporting_mode.get() {
- return;
- }
-
- // Step 2.
- self.in_error_reporting_mode.set(true);
-
- // Steps 3-12.
- // FIXME(#13195): muted errors.
- let event = ErrorEvent::new(GlobalRef::Worker(self.upcast()),
- atom!("error"),
- EventBubbles::DoesNotBubble,
- EventCancelable::Cancelable,
- error_info.message.as_str().into(),
- error_info.filename.as_str().into(),
- error_info.lineno,
- error_info.column,
- value);
-
- // Step 13.
- let event_status = event.upcast::<Event>().fire(self.upcast::<EventTarget>());
-
- // Step 15
- if event_status == EventStatus::NotCanceled {
- let worker = self.worker.borrow().as_ref().unwrap().clone();
- // TODO: Should use the DOM manipulation task source.
- self.parent_sender
- .send(CommonScriptMsg::RunnableMsg(WorkerEvent,
- box WorkerErrorHandler::new(worker, error_info)))
- .unwrap();
- }
-
- // Step 14
- self.in_error_reporting_mode.set(false);
+ pub fn forward_error_to_worker_object(&self, error_info: ErrorInfo) {
+ let worker = self.worker.borrow().as_ref().unwrap().clone();
+ // TODO: Should use the DOM manipulation task source.
+ self.parent_sender
+ .send(CommonScriptMsg::RunnableMsg(WorkerEvent,
+ box WorkerErrorHandler::new(worker, error_info)))
+ .unwrap();
}
}
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 1b91e743a78..f8238d645e1 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -96,7 +96,7 @@ use js::jsapi::JS_GetRuntime;
use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
use msg::constellation_msg::{Key, KeyModifiers, KeyState};
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
-use net_traits::{AsyncResponseTarget, FetchResponseMsg, IpcSend, PendingAsyncLoad};
+use net_traits::{AsyncResponseTarget, FetchResponseMsg, IpcSend};
use net_traits::CookieSource::NonHTTP;
use net_traits::CoreResourceMsg::{GetCookiesForUrl, SetCookiesForUrl};
use net_traits::request::RequestInit;
@@ -1423,17 +1423,6 @@ impl Document {
ReflowReason::RequestAnimationFrame);
}
- /// Add a load to the list of loads blocking this document's load.
- pub fn add_blocking_load(&self, load: LoadType) {
- let mut loader = self.loader.borrow_mut();
- loader.add_blocking_load(load)
- }
-
- pub fn prepare_async_load(&self, load: LoadType, referrer_policy: Option<ReferrerPolicy>) -> PendingAsyncLoad {
- let mut loader = self.loader.borrow_mut();
- loader.prepare_async_load(load, self, referrer_policy)
- }
-
pub fn load_async(&self, load: LoadType, listener: AsyncResponseTarget, referrer_policy: Option<ReferrerPolicy>) {
let mut loader = self.loader.borrow_mut();
loader.load_async(load, listener, self, referrer_policy);
@@ -1441,10 +1430,9 @@ impl Document {
pub fn fetch_async(&self, load: LoadType,
request: RequestInit,
- fetch_target: IpcSender<FetchResponseMsg>,
- referrer_policy: Option<ReferrerPolicy>) {
+ fetch_target: IpcSender<FetchResponseMsg>) {
let mut loader = self.loader.borrow_mut();
- loader.fetch_async(load, request, fetch_target, self, referrer_policy);
+ loader.fetch_async(load, request, fetch_target);
}
pub fn finish_load(&self, load: LoadType) {
diff --git a/components/script/dom/headers.rs b/components/script/dom/headers.rs
index 4b832121654..7f43dd6b07a 100644
--- a/components/script/dom/headers.rs
+++ b/components/script/dom/headers.rs
@@ -229,6 +229,10 @@ impl Headers {
*self.header_list.borrow_mut() = HyperHeaders::new();
}
+ pub fn set_headers(&self, hyper_headers: HyperHeaders) {
+ *self.header_list.borrow_mut() = hyper_headers;
+ }
+
// https://fetch.spec.whatwg.org/#concept-header-extract-mime-type
pub fn extract_mime_type(&self) -> Vec<u8> {
self.header_list.borrow().get_raw("content-type").map_or(vec![], |v| v[0].clone())
diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs
index 1c84fbba784..7c6cabd345e 100644
--- a/components/script/dom/htmllinkelement.rs
+++ b/components/script/dom/htmllinkelement.rs
@@ -154,7 +154,9 @@ impl VirtualMethods for HTMLLinkElement {
},
&atom!("media") => {
if string_is_stylesheet(&rel) {
- self.handle_stylesheet_url(&attr.value());
+ if let Some(href) = self.upcast::<Element>().get_attribute(&ns!(), &atom!("href")) {
+ self.handle_stylesheet_url(&href.value());
+ }
}
},
_ => {},
@@ -195,62 +197,69 @@ impl VirtualMethods for HTMLLinkElement {
impl HTMLLinkElement {
+ /// https://html.spec.whatwg.org/multipage/#concept-link-obtain
fn handle_stylesheet_url(&self, href: &str) {
let document = document_from_node(self);
if document.browsing_context().is_none() {
return;
}
- match document.base_url().join(href) {
- Ok(url) => {
- let element = self.upcast::<Element>();
-
- let mq_attribute = element.get_attribute(&ns!(), &atom!("media"));
- let value = mq_attribute.r().map(|a| a.value());
- let mq_str = match value {
- Some(ref value) => &***value,
- None => "",
- };
- let mut css_parser = CssParser::new(&mq_str);
- let media = parse_media_query_list(&mut css_parser);
-
- // TODO: #8085 - Don't load external stylesheets if the node's mq doesn't match.
- let elem = Trusted::new(self);
-
- let context = Arc::new(Mutex::new(StylesheetContext {
- elem: elem,
- media: Some(media),
- data: vec!(),
- metadata: None,
- url: url.clone(),
- }));
-
- let (action_sender, action_receiver) = ipc::channel().unwrap();
- let listener = NetworkListener {
- context: context,
- script_chan: document.window().networking_task_source(),
- wrapper: Some(document.window().get_runnable_wrapper()),
- };
- let response_target = AsyncResponseTarget {
- sender: action_sender,
- };
- ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
- listener.notify_action(message.to().unwrap());
- });
+ // Step 1.
+ if href.is_empty() {
+ return;
+ }
- if self.parser_inserted.get() {
- document.increment_script_blocking_stylesheet_count();
- }
+ // Step 2.
+ let url = match document.base_url().join(href) {
+ Err(e) => return debug!("Parsing url {} failed: {}", href, e),
+ Ok(url) => url,
+ };
+
+ let element = self.upcast::<Element>();
+
+ let mq_attribute = element.get_attribute(&ns!(), &atom!("media"));
+ let value = mq_attribute.r().map(|a| a.value());
+ let mq_str = match value {
+ Some(ref value) => &***value,
+ None => "",
+ };
+ let mut css_parser = CssParser::new(&mq_str);
+ let media = parse_media_query_list(&mut css_parser);
+
+ // TODO: #8085 - Don't load external stylesheets if the node's mq doesn't match.
+ let elem = Trusted::new(self);
+
+ let context = Arc::new(Mutex::new(StylesheetContext {
+ elem: elem,
+ media: Some(media),
+ data: vec!(),
+ metadata: None,
+ url: url.clone(),
+ }));
+
+ let (action_sender, action_receiver) = ipc::channel().unwrap();
+ let listener = NetworkListener {
+ context: context,
+ script_chan: document.window().networking_task_source(),
+ wrapper: Some(document.window().get_runnable_wrapper()),
+ };
+ let response_target = AsyncResponseTarget {
+ sender: action_sender,
+ };
+ ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
+ listener.notify_action(message.to().unwrap());
+ });
+
+ if self.parser_inserted.get() {
+ document.increment_script_blocking_stylesheet_count();
+ }
- let referrer_policy = match self.RelList().Contains("noreferrer".into()) {
- true => Some(ReferrerPolicy::NoReferrer),
- false => None,
- };
+ let referrer_policy = match self.RelList().Contains("noreferrer".into()) {
+ true => Some(ReferrerPolicy::NoReferrer),
+ false => None,
+ };
- document.load_async(LoadType::Stylesheet(url), response_target, referrer_policy);
- }
- Err(e) => debug!("Parsing url {} failed: {}", href, e)
- }
+ document.load_async(LoadType::Stylesheet(url), response_target, referrer_policy);
}
fn handle_favicon_url(&self, rel: &str, href: &str, sizes: &Option<String>) {
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index 4b16908968f..e96ceb6d834 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -25,7 +25,6 @@ use dom::htmlelement::HTMLElement;
use dom::node::{ChildrenMutation, CloneChildrenFlag, Node};
use dom::node::{document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
-use dom::window::ScriptHelpers;
use encoding::label::encoding_from_whatwg_label;
use encoding::types::{DecoderTrap, EncodingRef};
use html5ever::tree_builder::NextParserState;
@@ -244,8 +243,6 @@ fn fetch_a_classic_script(script: &HTMLScriptElement,
},
origin: doc.url().clone(),
pipeline_id: Some(script.global().r().pipeline_id()),
- // FIXME: Set to true for now, discussion in https://github.com/whatwg/fetch/issues/381
- same_origin_data: true,
referrer_url: Some(doc.url().clone()),
referrer_policy: doc.get_referrer_policy(),
.. RequestInit::default()
@@ -262,8 +259,6 @@ fn fetch_a_classic_script(script: &HTMLScriptElement,
status: Ok(())
}));
- let doc = document_from_node(script);
-
let (action_sender, action_receiver) = ipc::channel().unwrap();
let listener = NetworkListener {
context: context,
@@ -274,7 +269,7 @@ fn fetch_a_classic_script(script: &HTMLScriptElement,
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
listener.notify_fetch(message.to().unwrap());
});
- doc.fetch_async(LoadType::Script(url), request, action_sender, None);
+ doc.fetch_async(LoadType::Script(url), request, action_sender);
}
impl HTMLScriptElement {
@@ -509,9 +504,8 @@ impl HTMLScriptElement {
// Step 5.a.2.
let window = window_from_node(self);
rooted!(in(window.get_cx()) let mut rval = UndefinedValue());
- window.evaluate_script_on_global_with_result(&script.text,
- script.url.as_str(),
- rval.handle_mut());
+ GlobalRef::Window(&window).evaluate_script_on_global_with_result(
+ &script.text, script.url.as_str(), rval.handle_mut());
// Step 6.
document.set_current_script(old_script.r());
diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs
index 149c61c96ee..ba15f565c27 100644
--- a/components/script/dom/request.rs
+++ b/components/script/dom/request.rs
@@ -2,8 +2,9 @@
* 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 body::{BodyOperations, BodyType, consume_body};
use dom::bindings::cell::DOMRefCell;
-use dom::bindings::codegen::Bindings::HeadersBinding::HeadersInit;
+use dom::bindings::codegen::Bindings::HeadersBinding::{HeadersInit, HeadersMethods};
use dom::bindings::codegen::Bindings::RequestBinding;
use dom::bindings::codegen::Bindings::RequestBinding::ReferrerPolicy;
use dom::bindings::codegen::Bindings::RequestBinding::RequestCache;
@@ -21,7 +22,9 @@ use dom::bindings::js::{JS, MutNullableHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, DOMString, USVString};
use dom::headers::{Guard, Headers};
-use hyper;
+use dom::promise::Promise;
+use dom::xmlhttprequest::Extractable;
+use hyper::method::Method as HttpMethod;
use msg::constellation_msg::ReferrerPolicy as MsgReferrerPolicy;
use net_traits::request::{Origin, Window};
use net_traits::request::CacheMode as NetTraitsRequestCache;
@@ -33,6 +36,9 @@ use net_traits::request::Request as NetTraitsRequest;
use net_traits::request::RequestMode as NetTraitsRequestMode;
use net_traits::request::Type as NetTraitsRequestType;
use std::cell::Cell;
+use std::mem;
+use std::rc::Rc;
+use style::refcell::Ref;
use url::Url;
#[dom_struct]
@@ -153,7 +159,6 @@ impl Request {
// TODO: `entry settings object` is not implemented in Servo yet.
*request.origin.borrow_mut() = Origin::Client;
request.omit_origin_header = temporary_request.omit_origin_header;
- request.same_origin_data.set(true);
request.referrer = temporary_request.referrer;
request.referrer_policy = temporary_request.referrer_policy;
request.mode = temporary_request.mode;
@@ -340,7 +345,7 @@ impl Request {
try!(r.Headers().fill(Some(HeadersInit::Headers(headers_copy))));
// Step 32
- let input_body = if let RequestInfo::Request(ref input_request) = input {
+ let mut input_body = if let RequestInfo::Request(ref input_request) = input {
let input_request_request = input_request.request.borrow();
let body = input_request_request.body.borrow();
body.clone()
@@ -354,9 +359,9 @@ impl Request {
let req = r.request.borrow();
let req_method = req.method.borrow();
match &*req_method {
- &hyper::method::Method::Get => return Err(Error::Type(
+ &HttpMethod::Get => return Err(Error::Type(
"Init's body is non-null, and request method is GET".to_string())),
- &hyper::method::Method::Head => return Err(Error::Type(
+ &HttpMethod::Head => return Err(Error::Type(
"Init's body is non-null, and request method is HEAD".to_string())),
_ => {},
}
@@ -365,6 +370,20 @@ impl Request {
// Step 34
// TODO: `ReadableStream` object is not implemented in Servo yet.
+ if let Some(Some(ref init_body)) = init.body {
+ // Step 34.2
+ let extracted_body_tmp = init_body.extract();
+ input_body = Some(extracted_body_tmp.0);
+ let content_type = extracted_body_tmp.1;
+
+ // Step 34.3
+ if let Some(contents) = content_type {
+ if !r.Headers().Has(ByteString::new(b"Content-Type".to_vec())).unwrap() {
+ try!(r.Headers().Append(ByteString::new(b"Content-Type".to_vec()),
+ ByteString::new(contents.as_bytes().to_vec())));
+ }
+ }
+ }
// Step 35
{
@@ -382,6 +401,13 @@ impl Request {
// Step 38
Ok(r)
}
+
+ // https://fetch.spec.whatwg.org/#concept-body-locked
+ fn locked(&self) -> bool {
+ // TODO: ReadableStream is unimplemented. Just return false
+ // for now.
+ false
+ }
}
impl Request {
@@ -418,6 +444,10 @@ impl Request {
r_clone.Headers().set_guard(headers_guard);
r_clone
}
+
+ pub fn get_request(&self) -> NetTraitsRequest {
+ self.request.borrow().clone()
+ }
}
fn net_request_from_global(global: GlobalRef,
@@ -431,15 +461,15 @@ fn net_request_from_global(global: GlobalRef,
Some(pipeline_id))
}
-fn normalized_method_to_typed_method(m: &str) -> hyper::method::Method {
+fn normalized_method_to_typed_method(m: &str) -> HttpMethod {
match m {
- "DELETE" => hyper::method::Method::Delete,
- "GET" => hyper::method::Method::Get,
- "HEAD" => hyper::method::Method::Head,
- "OPTIONS" => hyper::method::Method::Options,
- "POST" => hyper::method::Method::Post,
- "PUT" => hyper::method::Method::Put,
- a => hyper::method::Method::Extension(a.to_string())
+ "DELETE" => HttpMethod::Delete,
+ "GET" => HttpMethod::Get,
+ "HEAD" => HttpMethod::Head,
+ "OPTIONS" => HttpMethod::Options,
+ "POST" => HttpMethod::Post,
+ "PUT" => HttpMethod::Put,
+ a => HttpMethod::Extension(a.to_string())
}
}
@@ -482,10 +512,10 @@ fn is_forbidden_method(m: &ByteString) -> bool {
}
// https://fetch.spec.whatwg.org/#cors-safelisted-method
-fn is_cors_safelisted_method(m: &hyper::method::Method) -> bool {
- m == &hyper::method::Method::Get ||
- m == &hyper::method::Method::Head ||
- m == &hyper::method::Method::Post
+fn is_cors_safelisted_method(m: &HttpMethod) -> bool {
+ m == &HttpMethod::Get ||
+ m == &HttpMethod::Head ||
+ m == &HttpMethod::Post
}
// https://url.spec.whatwg.org/#include-credentials
@@ -602,6 +632,56 @@ impl RequestMethods for Request {
// Step 2
Ok(Request::clone_from(self))
}
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-text
+ fn Text(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::Text)
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-blob
+ fn Blob(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::Blob)
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-formdata
+ fn FormData(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::FormData)
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-json
+ fn Json(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::Json)
+ }
+}
+
+impl BodyOperations for Request {
+ fn get_body_used(&self) -> bool {
+ self.BodyUsed()
+ }
+
+ fn is_locked(&self) -> bool {
+ self.locked()
+ }
+
+ fn take_body(&self) -> Option<Vec<u8>> {
+ let ref mut net_traits_req = *self.request.borrow_mut();
+ let body: Option<Vec<u8>> = mem::replace(&mut *net_traits_req.body.borrow_mut(), None);
+ match body {
+ Some(_) => {
+ self.body_used.set(true);
+ body
+ },
+ _ => None,
+ }
+ }
+
+ fn get_mime_type(&self) -> Ref<Vec<u8>> {
+ self.mime_type.borrow()
+ }
}
impl Into<NetTraitsRequestCache> for RequestCache {
diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs
index acfc181283a..b8eeb81fb66 100644
--- a/components/script/dom/response.rs
+++ b/components/script/dom/response.rs
@@ -2,11 +2,13 @@
* 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 body::{BodyOperations, BodyType, consume_body};
use core::cell::Cell;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::HeadersBinding::HeadersMethods;
use dom::bindings::codegen::Bindings::ResponseBinding;
use dom::bindings::codegen::Bindings::ResponseBinding::{ResponseMethods, ResponseType as DOMResponseType};
+use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::BodyInit;
use dom::bindings::error::{Error, Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, MutNullableHeap, Root};
@@ -14,9 +16,16 @@ use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::str::{ByteString, USVString};
use dom::headers::{Headers, Guard};
use dom::headers::{is_vchar, is_obs_text};
+use dom::promise::Promise;
+use dom::xmlhttprequest::Extractable;
+use hyper::header::Headers as HyperHeaders;
use hyper::status::StatusCode;
+use hyper_serde::Serde;
use net_traits::response::{ResponseBody as NetTraitsResponseBody};
+use std::mem;
+use std::rc::Rc;
use std::str::FromStr;
+use style::refcell::Ref;
use url::Position;
use url::Url;
@@ -33,8 +42,7 @@ pub struct Response {
response_type: DOMRefCell<DOMResponseType>,
url: DOMRefCell<Option<Url>>,
url_list: DOMRefCell<Vec<Url>>,
- // For now use the existing NetTraitsResponseBody enum, until body
- // is implemented.
+ // For now use the existing NetTraitsResponseBody enum
body: DOMRefCell<NetTraitsResponseBody>,
}
@@ -59,7 +67,7 @@ impl Response {
reflect_dom_object(box Response::new_inherited(), global, ResponseBinding::Wrap)
}
- pub fn Constructor(global: GlobalRef, _body: Option<USVString>, init: &ResponseBinding::ResponseInit)
+ pub fn Constructor(global: GlobalRef, body: Option<BodyInit>, init: &ResponseBinding::ResponseInit)
-> Fallible<Root<Response>> {
// Step 1
if init.status < 200 || init.status > 599 {
@@ -86,11 +94,6 @@ impl Response {
// Step 6
if let Some(ref headers_member) = init.headers {
// Step 6.1
- // TODO: Figure out how/if we should make r's response's
- // header list and r's Headers object the same thing. For
- // now just working with r's Headers object. Also, the
- // header list should already be empty so this step may be
- // unnecessary.
r.Headers().empty_header_list();
// Step 6.2
@@ -98,23 +101,22 @@ impl Response {
}
// Step 7
- if let Some(_) = _body {
+ if let Some(ref body) = body {
// Step 7.1
if is_null_body_status(init.status) {
return Err(Error::Type(
"Body is non-null but init's status member is a null body status".to_string()));
};
- // Step 7.2
- let content_type: Option<ByteString> = None;
-
// Step 7.3
- // TODO: Extract body and implement step 7.3.
+ let (extracted_body, content_type) = body.extract();
+ *r.body.borrow_mut() = NetTraitsResponseBody::Done(extracted_body);
// Step 7.4
if let Some(content_type_contents) = content_type {
if !r.Headers().Has(ByteString::new(b"Content-Type".to_vec())).unwrap() {
- try!(r.Headers().Append(ByteString::new(b"Content-Type".to_vec()), content_type_contents));
+ try!(r.Headers().Append(ByteString::new(b"Content-Type".to_vec()),
+ ByteString::new(content_type_contents.as_bytes().to_vec())));
}
};
}
@@ -178,6 +180,38 @@ impl Response {
// Step 7
Ok(r)
}
+
+ // https://fetch.spec.whatwg.org/#concept-body-locked
+ fn locked(&self) -> bool {
+ // TODO: ReadableStream is unimplemented. Just return false
+ // for now.
+ false
+ }
+}
+
+impl BodyOperations for Response {
+ fn get_body_used(&self) -> bool {
+ self.BodyUsed()
+ }
+
+ fn is_locked(&self) -> bool {
+ self.locked()
+ }
+
+ fn take_body(&self) -> Option<Vec<u8>> {
+ let body: NetTraitsResponseBody = mem::replace(&mut *self.body.borrow_mut(), NetTraitsResponseBody::Empty);
+ match body {
+ NetTraitsResponseBody::Done(bytes) | NetTraitsResponseBody::Receiving(bytes) => {
+ self.body_used.set(true);
+ Some(bytes)
+ },
+ _ => None,
+ }
+ }
+
+ fn get_mime_type(&self) -> Ref<Vec<u8>> {
+ self.mime_type.borrow()
+ }
}
// https://fetch.spec.whatwg.org/#redirect-status
@@ -283,8 +317,53 @@ impl ResponseMethods for Response {
fn BodyUsed(&self) -> bool {
self.body_used.get()
}
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-text
+ fn Text(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::Text)
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-blob
+ fn Blob(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::Blob)
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-formdata
+ fn FormData(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::FormData)
+ }
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#dom-body-json
+ fn Json(&self) -> Rc<Promise> {
+ consume_body(self, BodyType::Json)
+ }
}
fn serialize_without_fragment(url: &Url) -> &str {
&url[..Position::AfterQuery]
}
+
+impl Response {
+ pub fn set_type(&self, new_response_type: DOMResponseType) {
+ *self.response_type.borrow_mut() = new_response_type;
+ }
+
+ pub fn set_headers(&self, option_hyper_headers: Option<Serde<HyperHeaders>>) {
+ self.Headers().set_headers(match option_hyper_headers {
+ Some(hyper_headers) => hyper_headers.into_inner(),
+ None => HyperHeaders::new(),
+ });
+ }
+
+ pub fn set_raw_status(&self, status: Option<(u16, Vec<u8>)>) {
+ *self.raw_status.borrow_mut() = status;
+ }
+
+ pub fn set_final_url(&self, final_url: Url) {
+ *self.url.borrow_mut() = Some(final_url);
+ }
+}
diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs
index f6208b63586..6efd555c909 100644
--- a/components/script/dom/serviceworkerglobalscope.rs
+++ b/components/script/dom/serviceworkerglobalscope.rs
@@ -23,7 +23,6 @@ use ipc_channel::router::ROUTER;
use js::jsapi::{JS_SetInterruptCallback, JSAutoCompartment, JSContext};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
-use msg::constellation_msg::PipelineId;
use net_traits::{LoadContext, load_whole_resource, IpcSend, CustomResponseMediator};
use rand::random;
use script_runtime::{CommonScriptMsg, StackRootTLS, get_reports, new_rt_and_cx, ScriptChan};
@@ -72,7 +71,6 @@ impl ScriptChan for ServiceWorkerChan {
#[dom_struct]
pub struct ServiceWorkerGlobalScope {
workerglobalscope: WorkerGlobalScope,
- id: PipelineId,
#[ignore_heap_size_of = "Defined in std"]
receiver: Receiver<ServiceWorkerScriptMsg>,
#[ignore_heap_size_of = "Defined in std"]
@@ -87,7 +85,6 @@ pub struct ServiceWorkerGlobalScope {
impl ServiceWorkerGlobalScope {
fn new_inherited(init: WorkerGlobalScopeInit,
worker_url: Url,
- id: PipelineId,
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
runtime: Runtime,
own_sender: Sender<ServiceWorkerScriptMsg>,
@@ -104,7 +101,6 @@ impl ServiceWorkerGlobalScope {
from_devtools_receiver,
timer_event_chan,
None),
- id: id,
receiver: receiver,
timer_event_port: timer_event_port,
own_sender: own_sender,
@@ -115,7 +111,6 @@ impl ServiceWorkerGlobalScope {
pub fn new(init: WorkerGlobalScopeInit,
worker_url: Url,
- id: PipelineId,
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
runtime: Runtime,
own_sender: Sender<ServiceWorkerScriptMsg>,
@@ -128,7 +123,6 @@ impl ServiceWorkerGlobalScope {
let cx = runtime.cx();
let scope = box ServiceWorkerGlobalScope::new_inherited(init,
worker_url,
- id,
from_devtools_receiver,
runtime,
own_sender,
@@ -148,7 +142,6 @@ impl ServiceWorkerGlobalScope {
swmanager_sender: IpcSender<ServiceWorkerMsg>,
scope_url: Url) {
let ScopeThings { script_url,
- pipeline_id,
init,
worker_load_origin,
.. } = scope_things;
@@ -179,7 +172,7 @@ impl ServiceWorkerGlobalScope {
let (timer_ipc_chan, _timer_ipc_port) = ipc::channel().unwrap();
let (timer_chan, timer_port) = channel();
let global = ServiceWorkerGlobalScope::new(
- init, url, pipeline_id, devtools_mpsc_port, runtime,
+ init, url, devtools_mpsc_port, runtime,
own_sender, receiver,
timer_ipc_chan, timer_port, swmanager_sender, scope_url);
let scope = global.upcast::<WorkerGlobalScope>();
@@ -298,10 +291,6 @@ impl ServiceWorkerGlobalScope {
}
}
- pub fn pipeline_id(&self) -> PipelineId {
- self.id
- }
-
pub fn process_event(&self, msg: CommonScriptMsg) {
self.handle_script_event(ServiceWorkerScriptMsg::CommonWorker(WorkerScriptMsg::Common(msg)));
}
diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs
index 9ac3f4e1ad4..6382897efb3 100644
--- a/components/script/dom/webglprogram.rs
+++ b/components/script/dom/webglprogram.rs
@@ -24,6 +24,7 @@ pub struct WebGLProgram {
webgl_object: WebGLObject,
id: WebGLProgramId,
is_deleted: Cell<bool>,
+ link_called: Cell<bool>,
linked: Cell<bool>,
fragment_shader: MutNullableHeap<JS<WebGLShader>>,
vertex_shader: MutNullableHeap<JS<WebGLShader>>,
@@ -39,6 +40,7 @@ impl WebGLProgram {
webgl_object: WebGLObject::new_inherited(),
id: id,
is_deleted: Cell::new(false),
+ link_called: Cell::new(false),
linked: Cell::new(false),
fragment_shader: Default::default(),
vertex_shader: Default::default(),
@@ -91,27 +93,38 @@ impl WebGLProgram {
self.is_deleted.get()
}
+ pub fn is_linked(&self) -> bool {
+ self.linked.get()
+ }
+
/// glLinkProgram
- pub fn link(&self) {
+ pub fn link(&self) -> WebGLResult<()> {
+ if self.is_deleted() {
+ return Err(WebGLError::InvalidOperation);
+ }
self.linked.set(false);
+ self.link_called.set(true);
match self.fragment_shader.get() {
Some(ref shader) if shader.successfully_compiled() => {},
- _ => return,
+ _ => return Ok(()), // callers use gl.LINK_STATUS to check link errors
}
match self.vertex_shader.get() {
Some(ref shader) if shader.successfully_compiled() => {},
- _ => return,
+ _ => return Ok(()), // callers use gl.LINK_STATUS to check link errors
}
self.linked.set(true);
-
self.renderer.send(CanvasMsg::WebGL(WebGLCommand::LinkProgram(self.id))).unwrap();
+ Ok(())
}
/// glUseProgram
pub fn use_program(&self) -> WebGLResult<()> {
+ if self.is_deleted() {
+ return Err(WebGLError::InvalidOperation);
+ }
if !self.linked.get() {
return Err(WebGLError::InvalidOperation);
}
@@ -120,8 +133,20 @@ impl WebGLProgram {
Ok(())
}
+ /// glValidateProgram
+ pub fn validate(&self) -> WebGLResult<()> {
+ if self.is_deleted() {
+ return Err(WebGLError::InvalidOperation);
+ }
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::ValidateProgram(self.id))).unwrap();
+ Ok(())
+ }
+
/// glAttachShader
pub fn attach_shader(&self, shader: &WebGLShader) -> WebGLResult<()> {
+ if self.is_deleted() || shader.is_deleted() {
+ return Err(WebGLError::InvalidOperation);
+ }
let shader_slot = match shader.gl_type() {
constants::FRAGMENT_SHADER => &self.fragment_shader,
constants::VERTEX_SHADER => &self.vertex_shader,
@@ -147,6 +172,9 @@ impl WebGLProgram {
/// glDetachShader
pub fn detach_shader(&self, shader: &WebGLShader) -> WebGLResult<()> {
+ if self.is_deleted() {
+ return Err(WebGLError::InvalidOperation);
+ }
let shader_slot = match shader.gl_type() {
constants::FRAGMENT_SHADER => &self.fragment_shader,
constants::VERTEX_SHADER => &self.vertex_shader,
@@ -174,6 +202,9 @@ impl WebGLProgram {
/// glBindAttribLocation
pub fn bind_attrib_location(&self, index: u32, name: DOMString) -> WebGLResult<()> {
+ if self.is_deleted() {
+ return Err(WebGLError::InvalidOperation);
+ }
if name.len() > MAX_UNIFORM_AND_ATTRIBUTE_LEN {
return Err(WebGLError::InvalidValue);
}
@@ -190,6 +221,9 @@ impl WebGLProgram {
}
pub fn get_active_uniform(&self, index: u32) -> WebGLResult<Root<WebGLActiveInfo>> {
+ if self.is_deleted() {
+ return Err(WebGLError::InvalidValue);
+ }
let (sender, receiver) = ipc::channel().unwrap();
self.renderer
.send(CanvasMsg::WebGL(WebGLCommand::GetActiveUniform(self.id, index, sender)))
@@ -201,6 +235,9 @@ impl WebGLProgram {
/// glGetActiveAttrib
pub fn get_active_attrib(&self, index: u32) -> WebGLResult<Root<WebGLActiveInfo>> {
+ if self.is_deleted() {
+ return Err(WebGLError::InvalidValue);
+ }
let (sender, receiver) = ipc::channel().unwrap();
self.renderer
.send(CanvasMsg::WebGL(WebGLCommand::GetActiveAttrib(self.id, index, sender)))
@@ -212,6 +249,9 @@ impl WebGLProgram {
/// glGetAttribLocation
pub fn get_attrib_location(&self, name: DOMString) -> WebGLResult<Option<i32>> {
+ if !self.is_linked() || self.is_deleted() {
+ return Err(WebGLError::InvalidOperation);
+ }
if name.len() > MAX_UNIFORM_AND_ATTRIBUTE_LEN {
return Err(WebGLError::InvalidValue);
}
@@ -234,6 +274,9 @@ impl WebGLProgram {
/// glGetUniformLocation
pub fn get_uniform_location(&self, name: DOMString) -> WebGLResult<Option<i32>> {
+ if !self.is_linked() || self.is_deleted() {
+ return Err(WebGLError::InvalidOperation);
+ }
if name.len() > MAX_UNIFORM_AND_ATTRIBUTE_LEN {
return Err(WebGLError::InvalidValue);
}
@@ -250,6 +293,25 @@ impl WebGLProgram {
Ok(receiver.recv().unwrap())
}
+ /// glGetProgramInfoLog
+ pub fn get_info_log(&self) -> WebGLResult<String> {
+ if self.is_deleted() {
+ return Err(WebGLError::InvalidOperation);
+ }
+ if self.link_called.get() {
+ let shaders_compiled = match (self.fragment_shader.get(), self.vertex_shader.get()) {
+ (Some(fs), Some(vs)) => fs.successfully_compiled() && vs.successfully_compiled(),
+ _ => false
+ };
+ if !shaders_compiled {
+ return Ok("One or more shaders failed to compile".to_string());
+ }
+ }
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.renderer.send(CanvasMsg::WebGL(WebGLCommand::GetProgramInfoLog(self.id, sender))).unwrap();
+ Ok(receiver.recv().unwrap())
+ }
+
/// glGetProgramParameter
pub fn parameter(&self, param_id: u32) -> WebGLResult<WebGLParameter> {
let (sender, receiver) = ipc::channel().unwrap();
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index d1342190f73..b69f11146fd 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -1281,15 +1281,36 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidOperation);
}
- if count <= 0 {
- return self.webgl_error(InvalidOperation);
+ if count < 0 {
+ return self.webgl_error(InvalidValue);
}
if offset < 0 {
return self.webgl_error(InvalidValue);
}
- if self.current_program.get().is_none() || self.bound_buffer_element_array.get().is_none() {
+ if self.current_program.get().is_none() {
+ // From the WebGL spec
+ //
+ // If the CURRENT_PROGRAM is null, an INVALID_OPERATION error will be generated.
+ // WebGL performs additional error checking beyond that specified
+ // in OpenGL ES 2.0 during calls to drawArrays and drawElements.
+ //
+ return self.webgl_error(InvalidOperation);
+ }
+
+ if let Some(array_buffer) = self.bound_buffer_element_array.get() {
+ // WebGL Spec: check buffer overflows, must be a valid multiple of the size.
+ let val = offset as u64 + (count as u64 * type_size as u64);
+ if val > array_buffer.capacity() as u64 {
+ return self.webgl_error(InvalidOperation);
+ }
+ } else {
+ // From the WebGL spec
+ //
+ // a non-null WebGLBuffer must be bound to the ELEMENT_ARRAY_BUFFER binding point
+ // or an INVALID_OPERATION error will be generated.
+ //
return self.webgl_error(InvalidOperation);
}
@@ -1323,25 +1344,68 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
+ fn DisableVertexAttribArray(&self, attrib_id: u32) {
+ if attrib_id > self.limits.max_vertex_attribs {
+ return self.webgl_error(InvalidValue);
+ }
+
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::DisableVertexAttribArray(attrib_id)))
+ .unwrap()
+ }
+
+ // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn GetActiveUniform(&self, program: Option<&WebGLProgram>, index: u32) -> Option<Root<WebGLActiveInfo>> {
- program.and_then(|p| match p.get_active_uniform(index) {
+ let program = match program {
+ Some(program) => program,
+ None => {
+ // Reasons to generate InvalidValue error
+ // From the GLES 2.0 spec
+ //
+ // "INVALID_VALUE is generated if index is greater than or equal
+ // to the number of active uniform variables in program"
+ //
+ // A null program has no uniforms so any index is always greater than the active uniforms
+ // WebGl conformance expects error with null programs. Check tests in get-active-test.html
+ self.webgl_error(InvalidValue);
+ return None;
+ }
+ };
+
+ match program.get_active_uniform(index) {
Ok(ret) => Some(ret),
- Err(error) => {
- self.webgl_error(error);
- None
- },
- })
+ Err(e) => {
+ self.webgl_error(e);
+ return None;
+ }
+ }
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn GetActiveAttrib(&self, program: Option<&WebGLProgram>, index: u32) -> Option<Root<WebGLActiveInfo>> {
- program.and_then(|p| match p.get_active_attrib(index) {
+ let program = match program {
+ Some(program) => program,
+ None => {
+ // Reasons to generate InvalidValue error
+ // From the GLES 2.0 spec
+ //
+ // "INVALID_VALUE is generated if index is greater than or equal
+ // to the number of active attribute variables in program"
+ //
+ // A null program has no attributes so any index is always greater than the active uniforms
+ // WebGl conformance expects error with null programs. Check tests in get-active-test.html
+ self.webgl_error(InvalidValue);
+ return None;
+ }
+ };
+
+ match program.get_active_attrib(index) {
Ok(ret) => Some(ret),
- Err(error) => {
- self.webgl_error(error);
- None
- },
- })
+ Err(e) => {
+ self.webgl_error(e);
+ return None;
+ }
+ }
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -1354,6 +1418,22 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
+ fn GetProgramInfoLog(&self, program: Option<&WebGLProgram>) -> Option<DOMString> {
+ if let Some(program) = program {
+ match program.get_info_log() {
+ Ok(value) => Some(DOMString::from(value)),
+ Err(e) => {
+ self.webgl_error(e);
+ None
+ }
+ }
+ } else {
+ self.webgl_error(WebGLError::InvalidValue);
+ None
+ }
+ }
+
+ // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
fn GetProgramParameter(&self, _: *mut JSContext, program: Option<&WebGLProgram>, param_id: u32) -> JSVal {
if let Some(program) = program {
match handle_potential_webgl_error!(self, program.parameter(param_id), WebGLParameter::Invalid) {
@@ -1699,7 +1779,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
fn LinkProgram(&self, program: Option<&WebGLProgram>) {
if let Some(program) = program {
- program.link()
+ if let Err(e) = program.link() {
+ self.webgl_error(e);
+ }
}
}
@@ -1940,6 +2022,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
}
+ // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
+ fn ValidateProgram(&self, program: Option<&WebGLProgram>) {
+ if let Some(program) = program {
+ if let Err(e) = program.validate() {
+ self.webgl_error(e);
+ }
+ }
+ }
+
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn VertexAttrib1f(&self, indx: u32, x: f32) {
self.vertex_attrib(indx, x, 0f32, 0f32, 1f32)
@@ -2016,13 +2107,38 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidValue);
}
- if let constants::FLOAT = data_type {
- let msg = CanvasMsg::WebGL(
- WebGLCommand::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset as u32));
- self.ipc_renderer.send(msg).unwrap()
- } else {
- panic!("VertexAttribPointer: Data Type not supported")
+ // GLES spec: If offset or stride is negative, an INVALID_VALUE error will be generated
+ // WebGL spec: the maximum supported stride is 255
+ if stride < 0 || stride > 255 || offset < 0 {
+ return self.webgl_error(InvalidValue);
+ }
+ if size < 1 || size > 4 {
+ return self.webgl_error(InvalidValue);
+ }
+ if self.bound_buffer_array.get().is_none() {
+ return self.webgl_error(InvalidOperation);
+ }
+
+ // stride and offset must be multiple of data_type
+ match data_type {
+ constants::BYTE | constants::UNSIGNED_BYTE => {},
+ constants::SHORT | constants::UNSIGNED_SHORT => {
+ if offset % 2 > 0 || stride % 2 > 0 {
+ return self.webgl_error(InvalidOperation);
+ }
+ },
+ constants::FLOAT => {
+ if offset % 4 > 0 || stride % 4 > 0 {
+ return self.webgl_error(InvalidOperation);
+ }
+ },
+ _ => return self.webgl_error(InvalidEnum),
+
}
+
+ let msg = CanvasMsg::WebGL(
+ WebGLCommand::VertexAttribPointer(attrib_id, size, data_type, normalized, stride, offset as u32));
+ self.ipc_renderer.send(msg).unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.4
diff --git a/components/script/dom/webidls/Bluetooth.webidl b/components/script/dom/webidls/Bluetooth.webidl
index 6c575db150c..16c30c770d4 100644
--- a/components/script/dom/webidls/Bluetooth.webidl
+++ b/components/script/dom/webidls/Bluetooth.webidl
@@ -23,9 +23,7 @@ interface Bluetooth {
// [SecureContext]
// readonly attribute BluetoothDevice? referringDevice;
// [SecureContext]
-// Promise<BluetoothDevice> requestDevice(RequestDeviceOptions options);
- [Throws]
- BluetoothDevice requestDevice(optional RequestDeviceOptions options);
+ Promise<BluetoothDevice> requestDevice(optional RequestDeviceOptions options);
};
// Bluetooth implements EventTarget;
diff --git a/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl b/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl
index fdb3afa8b9a..293ac7f742c 100644
--- a/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl
+++ b/components/script/dom/webidls/BluetoothRemoteGATTCharacteristic.webidl
@@ -10,18 +10,12 @@ interface BluetoothRemoteGATTCharacteristic {
readonly attribute DOMString uuid;
readonly attribute BluetoothCharacteristicProperties properties;
readonly attribute ByteString? value;
- [Throws]
- BluetoothRemoteGATTDescriptor getDescriptor(BluetoothDescriptorUUID descriptor);
- [Throws]
- sequence<BluetoothRemoteGATTDescriptor> getDescriptors(optional BluetoothDescriptorUUID descriptor);
- //Promise<BluetoothRemoteGATTDescriptor> getDescriptor(BluetoothDescriptorUUID descriptor);
- //Promise<sequence<BluetoothRemoteGATTDescriptor>>
- //getDescriptors(optional BluetoothDescriptorUUID descriptor);
- [Throws]
- ByteString readValue();
+ Promise<BluetoothRemoteGATTDescriptor> getDescriptor(BluetoothDescriptorUUID descriptor);
+ Promise<sequence<BluetoothRemoteGATTDescriptor>>
+ getDescriptors(optional BluetoothDescriptorUUID descriptor);
+ Promise<ByteString> readValue();
//Promise<DataView> readValue();
- [Throws]
- void writeValue(sequence<octet> value);
+ Promise<void> writeValue(sequence<octet> value);
//Promise<void> writeValue(BufferSource value);
//Promise<void> startNotifications();
//Promise<void> stopNotifications();
diff --git a/components/script/dom/webidls/BluetoothRemoteGATTDescriptor.webidl b/components/script/dom/webidls/BluetoothRemoteGATTDescriptor.webidl
index 8c744929542..7ffd3f2ebb5 100644
--- a/components/script/dom/webidls/BluetoothRemoteGATTDescriptor.webidl
+++ b/components/script/dom/webidls/BluetoothRemoteGATTDescriptor.webidl
@@ -9,10 +9,8 @@ interface BluetoothRemoteGATTDescriptor {
readonly attribute BluetoothRemoteGATTCharacteristic characteristic;
readonly attribute DOMString uuid;
readonly attribute ByteString? value;
- [Throws]
- ByteString readValue();
+ Promise<ByteString> readValue();
//Promise<DataView> readValue();
- [Throws]
- void writeValue(sequence<octet> value);
+ Promise<void> writeValue(sequence<octet> value);
//Promise<void> writeValue(BufferSource value);
};
diff --git a/components/script/dom/webidls/BluetoothRemoteGATTServer.webidl b/components/script/dom/webidls/BluetoothRemoteGATTServer.webidl
index 13314d7c6e1..45e3df198fe 100644
--- a/components/script/dom/webidls/BluetoothRemoteGATTServer.webidl
+++ b/components/script/dom/webidls/BluetoothRemoteGATTServer.webidl
@@ -8,15 +8,9 @@
interface BluetoothRemoteGATTServer {
readonly attribute BluetoothDevice device;
readonly attribute boolean connected;
- [Throws]
- BluetoothRemoteGATTServer connect();
+ Promise<BluetoothRemoteGATTServer> connect();
[Throws]
void disconnect();
- [Throws]
- BluetoothRemoteGATTService getPrimaryService(BluetoothServiceUUID service);
- [Throws]
- sequence<BluetoothRemoteGATTService> getPrimaryServices(optional BluetoothServiceUUID service);
- //Promise<BluetoothRemoteGATTService> getPrimaryService(BluetoothServiceUUID service);
- //Promise<sequence<BluetoothRemoteGATTService>>getPrimaryServices(optional BluetoothServiceUUID service);
- //Promise<BluetoothRemoteGATTServer> connect();
+ Promise<BluetoothRemoteGATTService> getPrimaryService(BluetoothServiceUUID service);
+ Promise<sequence<BluetoothRemoteGATTService>> getPrimaryServices(optional BluetoothServiceUUID service);
};
diff --git a/components/script/dom/webidls/BluetoothRemoteGATTService.webidl b/components/script/dom/webidls/BluetoothRemoteGATTService.webidl
index a7ee941232a..a484ae64f80 100644
--- a/components/script/dom/webidls/BluetoothRemoteGATTService.webidl
+++ b/components/script/dom/webidls/BluetoothRemoteGATTService.webidl
@@ -9,18 +9,9 @@ interface BluetoothRemoteGATTService {
readonly attribute BluetoothDevice device;
readonly attribute DOMString uuid;
readonly attribute boolean isPrimary;
- [Throws]
- BluetoothRemoteGATTCharacteristic getCharacteristic(BluetoothCharacteristicUUID characteristic);
- [Throws]
- sequence<BluetoothRemoteGATTCharacteristic> getCharacteristics
- (optional BluetoothCharacteristicUUID characteristic);
- //Promise<BluetoothRemoteGATTCharacteristic>getCharacteristic(BluetoothCharacteristicUUID characteristic);
- //Promise<sequence<BluetoothRemoteGATTCharacteristic>>
- //getCharacteristics(optional BluetoothCharacteristicUUID characteristic);
- [Throws]
- BluetoothRemoteGATTService getIncludedService(BluetoothServiceUUID service);
- [Throws]
- sequence<BluetoothRemoteGATTService> getIncludedServices(optional BluetoothServiceUUID service);
- //Promise<BluetoothRemoteGATTService>getIncludedService(BluetoothServiceUUID service);
- //Promise<sequence<BluetoothRemoteGATTService>>getIncludedServices(optional BluetoothServiceUUID service);
+ Promise<BluetoothRemoteGATTCharacteristic> getCharacteristic(BluetoothCharacteristicUUID characteristic);
+ Promise<sequence<BluetoothRemoteGATTCharacteristic>>
+ getCharacteristics(optional BluetoothCharacteristicUUID characteristic);
+ Promise<BluetoothRemoteGATTService> getIncludedService(BluetoothServiceUUID service);
+ Promise<sequence<BluetoothRemoteGATTService>> getIncludedServices(optional BluetoothServiceUUID service);
};
diff --git a/components/script/dom/webidls/Body.webidl b/components/script/dom/webidls/Body.webidl
index a020228a01d..bb7aa5c6859 100644
--- a/components/script/dom/webidls/Body.webidl
+++ b/components/script/dom/webidls/Body.webidl
@@ -10,10 +10,9 @@
interface Body {
readonly attribute boolean bodyUsed;
- // Servo does not support Promise at this moment.
// [NewObject] Promise<ArrayBuffer> arrayBuffer();
- // [NewObject] Promise<Blob> blob();
- // [NewObject] Promise<FormData> formData();
- // [NewObject] Promise<JSON> json();
- // [NewObject] Promise<USVString> text();
+ [NewObject] Promise<Blob> blob();
+ [NewObject] Promise<FormData> formData();
+ [NewObject] Promise<any> json();
+ [NewObject] Promise<USVString> text();
};
diff --git a/components/script/dom/webidls/EventSource.webidl b/components/script/dom/webidls/EventSource.webidl
index 11c30e959d4..b9cf82d6a3e 100644
--- a/components/script/dom/webidls/EventSource.webidl
+++ b/components/script/dom/webidls/EventSource.webidl
@@ -7,7 +7,8 @@
*/
[Constructor(DOMString url, optional EventSourceInit eventSourceInitDict),
- Exposed=(Window,Worker)]
+ Exposed=(Window,Worker),
+ Pref="dom.eventsource.enabled"]
interface EventSource : EventTarget {
readonly attribute DOMString url;
readonly attribute boolean withCredentials;
diff --git a/components/script/dom/webidls/Fetch.webidl b/components/script/dom/webidls/Fetch.webidl
new file mode 100644
index 00000000000..fe062994598
--- /dev/null
+++ b/components/script/dom/webidls/Fetch.webidl
@@ -0,0 +1,11 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+// https://fetch.spec.whatwg.org/#fetch-method
+
+[Exposed=(Window,Worker)]
+
+partial interface WindowOrWorkerGlobalScope {
+ [NewObject] Promise<Response> fetch(RequestInfo input, optional RequestInit init);
+};
diff --git a/components/script/dom/webidls/Response.webidl b/components/script/dom/webidls/Response.webidl
index 2052f5c6371..a1b3cf7dd9a 100644
--- a/components/script/dom/webidls/Response.webidl
+++ b/components/script/dom/webidls/Response.webidl
@@ -4,8 +4,7 @@
// https://fetch.spec.whatwg.org/#response-class
-// TODO: pass 'optional ResponseBodyInit? body = null' to constructor in place of USVString
- [Constructor(optional USVString? body = null, optional ResponseInit init),
+ [Constructor(optional BodyInit? body = null, optional ResponseInit init),
Exposed=(Window,Worker)]
interface Response {
[NewObject] static Response error();
diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl
index 06727b3a536..19e5f029168 100644
--- a/components/script/dom/webidls/WebGLRenderingContext.webidl
+++ b/components/script/dom/webidls/WebGLRenderingContext.webidl
@@ -552,7 +552,7 @@ interface WebGLRenderingContextBase
void depthRange(GLclampf zNear, GLclampf zFar);
void detachShader(WebGLProgram? program, WebGLShader? shader);
void disable(GLenum cap);
- //void disableVertexAttribArray(GLuint index);
+ void disableVertexAttribArray(GLuint index);
void drawArrays(GLenum mode, GLint first, GLsizei count);
void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
@@ -583,7 +583,7 @@ interface WebGLRenderingContextBase
//any getFramebufferAttachmentParameter(GLenum target, GLenum attachment,
// GLenum pname);
any getProgramParameter(WebGLProgram? program, GLenum pname);
- //DOMString? getProgramInfoLog(WebGLProgram? program);
+ DOMString? getProgramInfoLog(WebGLProgram? program);
//any getRenderbufferParameter(GLenum target, GLenum pname);
any getShaderParameter(WebGLShader? shader, GLenum pname);
//WebGLShaderPrecisionFormat? getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
@@ -704,7 +704,7 @@ interface WebGLRenderingContextBase
// sequence<GLfloat> value);
void useProgram(WebGLProgram? program);
- //void validateProgram(WebGLProgram? program);
+ void validateProgram(WebGLProgram? program);
// FIXME(dmarcos)
// The code generator doesn't handle Float32Array so we're using 'object'
diff --git a/components/script/dom/webidls/WindowOrWorkerGlobalScope.webidl b/components/script/dom/webidls/WindowOrWorkerGlobalScope.webidl
new file mode 100644
index 00000000000..f0b8218fbe2
--- /dev/null
+++ b/components/script/dom/webidls/WindowOrWorkerGlobalScope.webidl
@@ -0,0 +1,30 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+// https://html.spec.whatwg.org/multipage/#windoworworkerglobalscope
+
+// typedef (DOMString or Function) TimerHandler;
+
+[NoInterfaceObject, Exposed=(Window,Worker)]
+interface WindowOrWorkerGlobalScope {
+ // [Replaceable] readonly attribute USVString origin;
+
+ // base64 utility methods
+ // DOMString btoa(DOMString data);
+ // DOMString atob(DOMString data);
+
+ // timers
+ // long setTimeout(TimerHandler handler, optional long timeout = 0, any... arguments);
+ // void clearTimeout(optional long handle = 0);
+ // long setInterval(TimerHandler handler, optional long timeout = 0, any... arguments);
+ // void clearInterval(optional long handle = 0);
+
+ // ImageBitmap
+ // Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, optional ImageBitmapOptions options);
+ // Promise<ImageBitmap> createImageBitmap(
+ // ImageBitmapSource image, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options);
+};
+
+Window implements WindowOrWorkerGlobalScope;
+WorkerGlobalScope implements WindowOrWorkerGlobalScope;
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 3e841116acd..3ac5c4e37f9 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -12,9 +12,11 @@ use dom::bindings::codegen::Bindings::EventHandlerBinding::OnBeforeUnloadEventHa
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
+use dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
use dom::bindings::codegen::Bindings::WindowBinding::{self, FrameRequestCallback, WindowMethods};
use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions};
-use dom::bindings::error::{Error, ErrorInfo, ErrorResult, Fallible, report_pending_exception};
+use dom::bindings::codegen::UnionTypes::RequestOrUSVString;
+use dom::bindings::error::{Error, ErrorInfo, ErrorResult, Fallible};
use dom::bindings::global::{GlobalRef, global_root_from_object};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, MutNullableHeap, Root};
@@ -40,17 +42,17 @@ use dom::messageevent::MessageEvent;
use dom::navigator::Navigator;
use dom::node::{Node, from_untrusted_node_address, window_from_node};
use dom::performance::Performance;
+use dom::promise::Promise;
use dom::screen::Screen;
use dom::storage::Storage;
use euclid::{Point2D, Rect, Size2D};
+use fetch;
use gfx_traits::LayerId;
use ipc_channel::ipc::{self, IpcSender};
-use js::jsapi::{Evaluate2, HandleObject, HandleValue, JSAutoCompartment, JSContext};
-use js::jsapi::{JS_GC, JS_GetRuntime, MutableHandleValue, SetWindowProxy};
+use js::jsapi::{HandleObject, HandleValue, JSAutoCompartment, JSContext};
+use js::jsapi::{JS_GC, JS_GetRuntime, SetWindowProxy};
use js::jsval::UndefinedValue;
-use js::rust::CompileOptionsWrapper;
use js::rust::Runtime;
-use libc;
use msg::constellation_msg::{FrameType, LoadData, PipelineId, ReferrerPolicy, WindowSizeType};
use net_traits::ResourceThreads;
use net_traits::bluetooth_thread::BluetoothMethodMsg;
@@ -60,15 +62,14 @@ use num_traits::ToPrimitive;
use open;
use origin::Origin;
use profile_traits::mem;
-use profile_traits::time::{ProfilerCategory, TimerMetadata, TimerMetadataFrameType};
-use profile_traits::time::{ProfilerChan, TimerMetadataReflowType, profile};
+use profile_traits::time::ProfilerChan;
use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64};
use script_layout_interface::TrustedNodeAddress;
use script_layout_interface::message::{Msg, Reflow, ReflowQueryType, ScriptReflow};
use script_layout_interface::reporter::CSSErrorReporter;
use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse, LayoutRPC};
use script_layout_interface::rpc::{MarginStyleResponse, ResolvedStyleResponse};
-use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThreadEventCategory, maybe_take_panic_result};
+use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThreadEventCategory};
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, RunnableWrapper};
use script_thread::SendableMainThreadScriptChan;
use script_traits::{ConstellationControlMsg, MozBrowserEvent, UntrustedNodeAddress};
@@ -80,9 +81,7 @@ use std::borrow::ToOwned;
use std::cell::Cell;
use std::collections::{HashMap, HashSet};
use std::default::Default;
-use std::ffi::CString;
use std::io::{Write, stderr, stdout};
-use std::panic;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, Ordering};
@@ -191,7 +190,6 @@ pub struct Window {
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
/// For sending timeline markers. Will be ignored if
/// no devtools server
- #[ignore_heap_size_of = "TODO(#6909) need to measure HashSet"]
devtools_markers: DOMRefCell<HashSet<TimelineMarkerType>>,
#[ignore_heap_size_of = "channels are hard"]
devtools_marker_sender: DOMRefCell<Option<IpcSender<TimelineMarker>>>,
@@ -902,60 +900,11 @@ impl WindowMethods for Window {
Err(e) => Err(Error::Type(format!("Couldn't open URL: {}", e))),
}
}
-}
-
-pub trait ScriptHelpers {
- fn evaluate_js_on_global_with_result(self, code: &str,
- rval: MutableHandleValue);
- fn evaluate_script_on_global_with_result(self, code: &str, filename: &str,
- rval: MutableHandleValue);
-}
-
-impl<'a, T: Reflectable> ScriptHelpers for &'a T {
- fn evaluate_js_on_global_with_result(self, code: &str,
- rval: MutableHandleValue) {
- self.evaluate_script_on_global_with_result(code, "", rval)
- }
-
- #[allow(unsafe_code)]
- fn evaluate_script_on_global_with_result(self, code: &str, filename: &str,
- rval: MutableHandleValue) {
- let global = self.global();
- let metadata = TimerMetadata {
- url: if filename.is_empty() {
- global.r().get_url().as_str().into()
- } else {
- filename.into()
- },
- iframe: TimerMetadataFrameType::RootWindow,
- incremental: TimerMetadataReflowType::FirstReflow,
- };
- profile(
- ProfilerCategory::ScriptEvaluate,
- Some(metadata),
- global.r().time_profiler_chan().clone(),
- || {
- let cx = global.r().get_cx();
- let globalhandle = global.r().reflector().get_jsobject();
- let code: Vec<u16> = code.encode_utf16().collect();
- let filename = CString::new(filename).unwrap();
-
- let _ac = JSAutoCompartment::new(cx, globalhandle.get());
- let options = CompileOptionsWrapper::new(cx, filename.as_ptr(), 1);
- unsafe {
- if !Evaluate2(cx, options.ptr, code.as_ptr(),
- code.len() as libc::size_t,
- rval) {
- debug!("error evaluating JS string");
- report_pending_exception(cx, true);
- }
- }
- if let Some(error) = maybe_take_panic_result() {
- panic::resume_unwind(error);
- }
- }
- )
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#fetch-method
+ fn Fetch(&self, input: RequestOrUSVString, init: &RequestInit) -> Rc<Promise> {
+ fetch::Fetch(self.global().r(), input, init)
}
}
diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs
index 1821b2d2dee..fb6b170ab1d 100644
--- a/components/script/dom/worker.rs
+++ b/components/script/dom/worker.rs
@@ -106,7 +106,7 @@ impl Worker {
let init = prepare_workerscope_init(global, Some(devtools_sender));
DedicatedWorkerGlobalScope::run_worker_scope(
- init, worker_url, global.pipeline_id(), devtools_receiver, worker.runtime.clone(), worker_ref,
+ init, worker_url, devtools_receiver, worker.runtime.clone(), worker_ref,
global.script_chan(), sender, receiver, worker_load_origin, closing);
Ok(worker)
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index 2520f57dbac..9c7768ce5e7 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -5,8 +5,10 @@
use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
+use dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
use dom::bindings::codegen::Bindings::WorkerGlobalScopeBinding::WorkerGlobalScopeMethods;
-use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception, ErrorInfo};
+use dom::bindings::codegen::UnionTypes::RequestOrUSVString;
+use dom::bindings::error::{Error, ErrorInfo, ErrorResult, Fallible, report_pending_exception};
use dom::bindings::global::{GlobalRef, GlobalRoot};
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, MutNullableHeap, Root};
@@ -16,11 +18,16 @@ use dom::bindings::str::DOMString;
use dom::console::TimerSet;
use dom::crypto::Crypto;
use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope;
+use dom::errorevent::ErrorEvent;
+use dom::event::{Event, EventBubbles, EventCancelable};
+use dom::eventdispatcher::EventStatus;
use dom::eventtarget::EventTarget;
+use dom::promise::Promise;
use dom::serviceworkerglobalscope::ServiceWorkerGlobalScope;
use dom::window::{base64_atob, base64_btoa};
use dom::workerlocation::WorkerLocation;
use dom::workernavigator::WorkerNavigator;
+use fetch;
use ipc_channel::ipc::IpcSender;
use js::jsapi::{HandleValue, JSAutoCompartment, JSContext, JSRuntime};
use js::jsval::UndefinedValue;
@@ -62,7 +69,8 @@ pub fn prepare_workerscope_init(global: GlobalRef,
from_devtools_sender: devtools_sender,
constellation_chan: global.constellation_chan().clone(),
scheduler_chan: global.scheduler_chan().clone(),
- worker_id: worker_id
+ worker_id: worker_id,
+ pipeline_id: global.pipeline_id(),
};
init
@@ -73,6 +81,7 @@ pub fn prepare_workerscope_init(global: GlobalRef,
pub struct WorkerGlobalScope {
eventtarget: EventTarget,
worker_id: WorkerId,
+ pipeline_id: PipelineId,
worker_url: Url,
closing: Option<Arc<AtomicBool>>,
#[ignore_heap_size_of = "Defined in js"]
@@ -116,6 +125,9 @@ pub struct WorkerGlobalScope {
console_timers: TimerSet,
promise_job_queue: PromiseJobQueue,
+
+ /// https://html.spec.whatwg.org/multipage/#in-error-reporting-mode
+ in_error_reporting_mode: Cell<bool>
}
impl WorkerGlobalScope {
@@ -130,6 +142,7 @@ impl WorkerGlobalScope {
eventtarget: EventTarget::new_inherited(),
next_worker_id: Cell::new(WorkerId(0)),
worker_id: init.worker_id,
+ pipeline_id: init.pipeline_id,
worker_url: worker_url,
closing: closing,
runtime: runtime,
@@ -148,6 +161,7 @@ impl WorkerGlobalScope {
scheduler_chan: init.scheduler_chan,
console_timers: TimerSet::new(),
promise_job_queue: PromiseJobQueue::new(),
+ in_error_reporting_mode: Default::default(),
}
}
@@ -393,6 +407,12 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
fn ClearInterval(&self, handle: i32) {
self.ClearTimeout(handle);
}
+
+ #[allow(unrooted_must_root)]
+ // https://fetch.spec.whatwg.org/#fetch-method
+ fn Fetch(&self, input: RequestOrUSVString, init: &RequestInit) -> Rc<Promise> {
+ fetch::Fetch(self.global().r(), input, init)
+ }
}
@@ -437,15 +457,7 @@ impl WorkerGlobalScope {
}
pub fn pipeline_id(&self) -> PipelineId {
- let dedicated = self.downcast::<DedicatedWorkerGlobalScope>();
- let service_worker = self.downcast::<ServiceWorkerGlobalScope>();
- if let Some(dedicated) = dedicated {
- return dedicated.pipeline_id();
- } else if let Some(service_worker) = service_worker {
- return service_worker.pipeline_id();
- } else {
- panic!("need to implement a sender for SharedWorker")
- }
+ self.pipeline_id
}
pub fn new_script_pair(&self) -> (Box<ScriptChan + Send>, Box<ScriptPort + Send>) {
@@ -485,9 +497,38 @@ impl WorkerGlobalScope {
/// https://html.spec.whatwg.org/multipage/#report-the-error
pub fn report_an_error(&self, error_info: ErrorInfo, value: HandleValue) {
- self.downcast::<DedicatedWorkerGlobalScope>()
- .expect("Should implement report_an_error for this worker")
- .report_an_error(error_info, value);
+ // Step 1.
+ if self.in_error_reporting_mode.get() {
+ return;
+ }
+
+ // Step 2.
+ self.in_error_reporting_mode.set(true);
+
+ // Steps 3-12.
+ // FIXME(#13195): muted errors.
+ let event = ErrorEvent::new(GlobalRef::Worker(self),
+ atom!("error"),
+ EventBubbles::DoesNotBubble,
+ EventCancelable::Cancelable,
+ error_info.message.as_str().into(),
+ error_info.filename.as_str().into(),
+ error_info.lineno,
+ error_info.column,
+ value);
+
+ // Step 13.
+ let event_status = event.upcast::<Event>().fire(self.upcast::<EventTarget>());
+
+ // Step 15
+ if event_status == EventStatus::NotCanceled {
+ if let Some(dedicated) = self.downcast::<DedicatedWorkerGlobalScope>() {
+ dedicated.forward_error_to_worker_object(error_info);
+ }
+ }
+
+ // Step 14
+ self.in_error_reporting_mode.set(false);
}
}
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 0d21f9026fc..caebbddd09e 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -587,7 +587,6 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
url: self.request_url.borrow().clone().unwrap(),
headers: (*self.request_headers.borrow()).clone(),
unsafe_request: true,
- same_origin_data: true,
// XXXManishearth figure out how to avoid this clone
body: extracted.as_ref().map(|e| e.0.clone()),
// XXXManishearth actually "subresource", but it doesn't exist
@@ -1371,7 +1370,7 @@ impl XHRTimeoutCallback {
}
}
-trait Extractable {
+pub trait Extractable {
fn extract(&self) -> (Vec<u8>, Option<DOMString>);
}
impl Extractable for BodyInit {