diff options
Diffstat (limited to 'components/script/dom')
61 files changed, 846 insertions, 271 deletions
diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs index 7b837df1fed..7e6bb3534fb 100644 --- a/components/script/dom/bindings/callback.rs +++ b/components/script/dom/bindings/callback.rs @@ -7,12 +7,12 @@ use dom::bindings::error::{Error, Fallible, report_pending_exception}; use dom::bindings::global::global_root_from_object; use dom::bindings::reflector::Reflectable; -use js::jsapi::GetGlobalForObjectCrossCompartment; -use js::jsapi::JSAutoCompartment; -use js::jsapi::JS_GetProperty; use js::jsapi::{Heap, MutableHandleObject, RootedObject}; use js::jsapi::{IsCallable, JSContext, JSObject, JS_WrapObject}; use js::jsapi::{JSCompartment, JS_EnterCompartment, JS_LeaveCompartment}; +use js::jsapi::GetGlobalForObjectCrossCompartment; +use js::jsapi::JSAutoCompartment; +use js::jsapi::JS_GetProperty; use js::jsval::{JSVal, UndefinedValue}; use js::rust::RootedGuard; use std::default::Default; diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index cb7e796c627..486758182d2 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -26,6 +26,7 @@ from WebIDL import ( ) from Configuration import ( + MakeNativeName, MemberIsUnforgeable, getModuleFromObject, getTypesFromCallback, @@ -80,7 +81,7 @@ def toStringBool(arg): def toBindingNamespace(arg): - return re.sub("((_workers)?$)", "Binding\\1", arg) + return re.sub("((_workers)?$)", "Binding\\1", MakeNativeName(arg)) def stripTrailingWhitespace(text): @@ -96,9 +97,6 @@ def innerSequenceType(type): return type.inner.inner if type.nullable() else type.inner -def MakeNativeName(name): - return name[0].upper() + name[1:] - builtinNames = { IDLType.Tags.bool: 'bool', IDLType.Tags.int8: 'i8', @@ -1811,7 +1809,8 @@ class CGImports(CGWrapper): def isImportable(type): if not type.isType(): - assert type.isInterface() or type.isDictionary() or type.isEnum() + assert (type.isInterface() or type.isDictionary() or + type.isEnum() or type.isNamespace()) return True return not (type.builtin or type.isSequence() or type.isUnion()) @@ -1830,7 +1829,7 @@ class CGImports(CGWrapper): if t.isCallback(): return t.callback.identifier return t.identifier - assert t.isInterface() or t.isDictionary() or t.isEnum() + assert t.isInterface() or t.isDictionary() or t.isEnum() or t.isNamespace() return t.identifier def removeWrapperAndNullableTypes(types): @@ -1881,7 +1880,7 @@ class CGImports(CGWrapper): # Importing these types in the same module that defines them is an error. if t in dictionaries or t in enums: continue - if t.isInterface(): + if t.isInterface() or t.isNamespace(): descriptor = descriptorProvider.getDescriptor(getIdentifier(t).name) extras += [descriptor.path] if descriptor.interface.parent: @@ -2060,6 +2059,17 @@ class CGInterfaceObjectJSClass(CGThing): self.descriptor = descriptor def define(self): + if self.descriptor.interface.isNamespace(): + classString = self.descriptor.interface.getExtendedAttribute("ClassString") + if classString: + classString = classString[0] + else: + classString = "Object" + return """\ +static NAMESPACE_OBJECT_CLASS: NamespaceObjectClass = unsafe { + NamespaceObjectClass::new(%s) +}; +""" % str_to_const_array(classString) if self.descriptor.interface.ctor(): constructorBehavior = "InterfaceConstructorBehavior::call(%s)" % CONSTRUCT_HOOK_NAME else: @@ -2134,7 +2144,7 @@ class CGCallbackTempRoot(CGGeneric): CGGeneric.__init__(self, "%s::new(${val}.get().to_object())" % name) -def getAllTypes(descriptors, dictionaries, callbacks): +def getAllTypes(descriptors, dictionaries, callbacks, typedefs): """ Generate all the types we're dealing with. For each type, a tuple containing type, descriptor, dictionary is yielded. The @@ -2150,9 +2160,11 @@ def getAllTypes(descriptors, dictionaries, callbacks): for callback in callbacks: for t in getTypesFromCallback(callback): yield (t, None, None) + for typedef in typedefs: + yield (typedef.innerType, None, None) -def UnionTypes(descriptors, dictionaries, callbacks, config): +def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config): """ Returns a CGList containing CGUnionStructs for every union. """ @@ -2181,7 +2193,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, config): # Now find all the things we'll need as arguments and return values because # we need to wrap or unwrap them. unionStructs = dict() - for (t, descriptor, dictionary) in getAllTypes(descriptors, dictionaries, callbacks): + for (t, descriptor, dictionary) in getAllTypes(descriptors, dictionaries, callbacks, typedefs): assert not descriptor or not dictionary t = t.unroll() if not t.isUnion(): @@ -2657,6 +2669,28 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): def definition_body(self): name = self.descriptor.interface.identifier.name + if self.descriptor.interface.isNamespace(): + if self.descriptor.interface.getExtendedAttribute("ProtoObjectHack"): + proto = "JS_GetObjectPrototype(cx, global)" + else: + proto = "JS_NewPlainObject(cx)" + if self.properties.static_methods.length(): + methods = self.properties.static_methods.variableName() + else: + methods = "&[]" + return CGGeneric("""\ +rooted!(in(cx) let proto = %(proto)s); +assert!(!proto.is_null()); +rooted!(in(cx) let mut namespace = ptr::null_mut()); +create_namespace_object(cx, global, proto.handle(), &NAMESPACE_OBJECT_CLASS, + %(methods)s, %(name)s, namespace.handle_mut()); +assert!(!namespace.is_null()); +assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); +(*cache)[PrototypeList::Constructor::%(id)s as usize] = namespace.get(); +<*mut JSObject>::post_barrier((*cache).as_mut_ptr().offset(PrototypeList::Constructor::%(id)s as isize), + ptr::null_mut(), + namespace.get()); +""" % {"id": MakeNativeName(name), "methods": methods, "name": str_to_const_array(name), "proto": proto}) if self.descriptor.interface.isCallback(): assert not self.descriptor.interface.ctor() and self.descriptor.interface.hasConstants() return CGGeneric("""\ @@ -2871,7 +2905,7 @@ class CGGetPerInterfaceObject(CGAbstractMethod): Argument('MutableHandleObject', 'rval')] CGAbstractMethod.__init__(self, descriptor, name, 'void', args, pub=pub, unsafe=True) - self.id = idPrefix + "::" + self.descriptor.name + self.id = idPrefix + "::" + MakeNativeName(self.descriptor.name) def definition_body(self): return CGGeneric(""" @@ -3014,7 +3048,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): return CGAbstractMethod.define(self) def definition_body(self): - if self.descriptor.interface.isCallback(): + if self.descriptor.interface.isCallback() or self.descriptor.interface.isNamespace(): function = "GetConstructorObject" else: function = "GetProtoObject" @@ -3045,7 +3079,7 @@ class CGCallGenerator(CGThing): exception from the native code, or None if no error reporting is needed. """ def __init__(self, errorResult, arguments, argsPre, returnType, - extendedAttributes, descriptorProvider, nativeMethodName, + extendedAttributes, descriptor, nativeMethodName, static, object="this"): CGThing.__init__(self) @@ -3053,7 +3087,7 @@ class CGCallGenerator(CGThing): isFallible = errorResult is not None - result = getRetvalDeclarationForType(returnType, descriptorProvider) + result = getRetvalDeclarationForType(returnType, descriptor) if isFallible: result = CGWrapper(result, pre="Result<", post=", Error>") @@ -3074,7 +3108,7 @@ class CGCallGenerator(CGThing): call = CGGeneric(nativeMethodName) if static: - call = CGWrapper(call, pre="%s::" % descriptorProvider.interface.identifier.name) + call = CGWrapper(call, pre="%s::" % MakeNativeName(descriptor.interface.identifier.name)) else: call = CGWrapper(call, pre="%s." % object) call = CGList([call, CGWrapper(args, pre="(", post=")")]) @@ -5452,6 +5486,9 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries 'dom::bindings::js::OptionalRootedReference', 'dom::bindings::js::Root', 'dom::bindings::js::RootedReference', + 'dom::bindings::namespace::NamespaceObjectClass', + 'dom::bindings::namespace::create_namespace_object', + 'dom::bindings::reflector::MutReflectable', 'dom::bindings::reflector::Reflectable', 'dom::bindings::utils::DOMClass', 'dom::bindings::utils::DOMJSClass', @@ -5558,7 +5595,7 @@ class CGDescriptor(CGThing): return name cgThings = [] - if not descriptor.interface.isCallback(): + if not descriptor.interface.isCallback() and not descriptor.interface.isNamespace(): cgThings.append(CGGetProtoObjectMethod(descriptor)) reexports.append('GetProtoObject') if (descriptor.interface.hasInterfaceObject() and @@ -5619,7 +5656,7 @@ class CGDescriptor(CGThing): if not descriptor.interface.isCallback(): cgThings.append(CGInterfaceObjectJSClass(descriptor)) - if not descriptor.interface.isCallback(): + 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 @@ -5676,7 +5713,7 @@ class CGDescriptor(CGThing): reexports.append('Wrap') haveUnscopables = False - if not descriptor.interface.isCallback(): + if not descriptor.interface.isCallback() and not descriptor.interface.isNamespace(): if unscopableNames: haveUnscopables = True cgThings.append( @@ -5703,7 +5740,7 @@ class CGDescriptor(CGThing): cgThings, public=True), post='\n') reexports = ', '.join(map(lambda name: reexportedName(name), reexports)) - self.cgRoot = CGList([CGGeneric('pub use self::%sBinding::{%s};' % (descriptor.name, reexports)), + self.cgRoot = CGList([CGGeneric('pub use self::%s::{%s};' % (toBindingNamespace(descriptor.name), reexports)), cgThings], '\n') def define(self): @@ -6757,10 +6794,12 @@ class GlobalGenRoots(): @staticmethod def PrototypeList(config): # Prototype ID enum. - interfaces = config.getDescriptors(isCallback=False) + interfaces = config.getDescriptors(isCallback=False, isNamespace=False) protos = [d.name for d in interfaces] - constructors = [d.name for d in config.getDescriptors(hasInterfaceObject=True) - if d.shouldHaveGetConstructorObjectMethod()] + constructors = sorted([MakeNativeName(d.name) + for d in config.getDescriptors(hasInterfaceObject=True) + if d.shouldHaveGetConstructorObjectMethod()]) + proxies = [d.name for d in config.getDescriptors(proxy=True)] return CGList([ @@ -6797,10 +6836,13 @@ class GlobalGenRoots(): @staticmethod def InterfaceTypes(config): - descriptors = [d.name for d in config.getDescriptors(register=True, + descriptors = sorted([MakeNativeName(d.name) + for d in config.getDescriptors(register=True, isCallback=False, - isIteratorInterface=False)] - curr = CGList([CGGeneric("pub use dom::%s::%s;\n" % (name.lower(), name)) for name in descriptors]) + isIteratorInterface=False)]) + curr = CGList([CGGeneric("pub use dom::%s::%s;\n" % (name.lower(), + MakeNativeName(name))) + for name in descriptors]) curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT) return curr @@ -6811,7 +6853,7 @@ class GlobalGenRoots(): return getModuleFromObject(d).split('::')[-1] descriptors = config.getDescriptors(register=True, isIteratorInterface=False) - descriptors = (set(d.name + "Binding" for d in descriptors) | + descriptors = (set(toBindingNamespace(d.name) for d in descriptors) | set(leafModule(d) for d in config.callbacks) | set(leafModule(d) for d in config.getDictionaries())) curr = CGList([CGGeneric("pub mod %s;\n" % name) for name in sorted(descriptors)]) @@ -6913,6 +6955,7 @@ impl %(base)s { curr = UnionTypes(config.getDescriptors(), config.getDictionaries(), config.getCallbacks(), + config.typedefs, config) # Add the auto-generated comment. diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py index c8f92472618..6e71bd4bd00 100644 --- a/components/script/dom/bindings/codegen/Configuration.py +++ b/components/script/dom/bindings/codegen/Configuration.py @@ -4,7 +4,7 @@ import os -from WebIDL import IDLExternalInterface, IDLInterface, IDLWrapperType, WebIDLError +from WebIDL import IDLExternalInterface, IDLWrapperType, WebIDLError class Configuration: @@ -30,10 +30,9 @@ class Configuration: raise WebIDLError("Servo does not support external interfaces.", [thing.location]) - # Some toplevel things are sadly types, and those have an - # isInterface that doesn't mean the same thing as IDLObject's - # isInterface()... - if not isinstance(thing, IDLInterface): + assert not thing.isType() + + if not thing.isInterface() and not thing.isNamespace(): continue iface = thing @@ -83,6 +82,8 @@ class Configuration: getter = lambda x: x.interface.hasInterfaceObject() elif key == 'isCallback': getter = lambda x: x.interface.isCallback() + elif key == 'isNamespace': + getter = lambda x: x.interface.isNamespace() elif key == 'isJSImplemented': getter = lambda x: x.interface.isJSImplemented() elif key == 'isGlobal': @@ -210,7 +211,7 @@ class Descriptor(DescriptorProvider): if self.interface.isIteratorInterface(): pathDefault = 'dom::bindings::iterable::IterableIterator' else: - pathDefault = 'dom::types::%s' % typeName + pathDefault = 'dom::types::%s' % MakeNativeName(typeName) self.concreteType = typeName self.register = desc.get('register', True) @@ -223,6 +224,7 @@ class Descriptor(DescriptorProvider): # If we're concrete, we need to crawl our ancestor interfaces and mark # them as having a concrete descendant. self.concrete = (not self.interface.isCallback() and + not self.interface.isNamespace() and not self.interface.getExtendedAttribute("Abstract")) self.hasUnforgeableMembers = (self.concrete and any(MemberIsUnforgeable(m, self) for m in @@ -381,7 +383,7 @@ class Descriptor(DescriptorProvider): def shouldHaveGetConstructorObjectMethod(self): assert self.interface.hasInterfaceObject() - return self.interface.isCallback() or self.hasDescendants() + return self.interface.isCallback() or self.interface.isNamespace() or self.hasDescendants() def isExposedConditionally(self): return self.interface.isExposedConditionally() @@ -396,6 +398,12 @@ class Descriptor(DescriptorProvider): # Some utility methods + + +def MakeNativeName(name): + return name[0].upper() + name[1:] + + def getModuleFromObject(object): return ('dom::bindings::codegen::Bindings::' + os.path.basename(object.location.filename()).split('.webidl')[0] + 'Binding') diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py index 21af299303e..878c221f01c 100644 --- a/components/script/dom/bindings/codegen/parser/WebIDL.py +++ b/components/script/dom/bindings/codegen/parser/WebIDL.py @@ -2491,10 +2491,18 @@ class IDLUnionType(IDLType): return type.name for (i, type) in enumerate(self.memberTypes): - if not type.isComplete(): + # 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.flatMemberTypes = list(self.memberTypes) i = 0 while i < len(self.flatMemberTypes): diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs index 88ed079d2ba..c9cbeb09f21 100644 --- a/components/script/dom/bindings/error.rs +++ b/components/script/dom/bindings/error.rs @@ -6,8 +6,8 @@ use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods; use dom::bindings::codegen::PrototypeList::proto_id_to_name; -use dom::bindings::conversions::root_from_object; use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, ToJSValConvertible}; +use dom::bindings::conversions::root_from_object; use dom::bindings::global::{GlobalRef, global_root_from_context}; use dom::bindings::str::USVString; use dom::domexception::{DOMErrorName, DOMException}; diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index af4cd59a86f..a5c9d1a3d79 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -13,18 +13,19 @@ use dom::bindings::conversions::root_from_object; use dom::bindings::error::ErrorInfo; use dom::bindings::js::Root; use dom::bindings::reflector::{Reflectable, Reflector}; +use dom::console::TimerSet; use dom::window::{self, ScriptHelpers}; use dom::workerglobalscope::WorkerGlobalScope; use ipc_channel::ipc::IpcSender; -use js::jsapi::HandleValue; +use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL}; use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment}; use js::jsapi::{JSContext, JSObject, JS_GetClass, MutableHandleValue}; -use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL}; +use js::jsapi::HandleValue; use msg::constellation_msg::PipelineId; -use net_traits::{ResourceThreads, CoreResourceThread, IpcSend}; +use net_traits::{CoreResourceThread, IpcSend, ResourceThreads}; use profile_traits::{mem, time}; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort}; -use script_thread::{MainThreadScriptChan, ScriptThread, RunnableWrapper}; +use script_thread::{MainThreadScriptChan, RunnableWrapper, ScriptThread}; use script_traits::{MsDuration, ScriptMsg as ConstellationMsg, TimerEventRequest}; use task_source::dom_manipulation::DOMManipulationTaskSource; use task_source::file_reading::FileReadingTaskSource; @@ -271,11 +272,11 @@ impl<'a> GlobalRef<'a> { } } - /// Returns the receiver's reflector. - pub fn reflector(&self) -> &Reflector { + /// Returns the global's timers for the Console API. + pub fn console_timers(&self) -> &TimerSet { match *self { - GlobalRef::Window(ref window) => window.reflector(), - GlobalRef::Worker(ref worker) => worker.reflector(), + GlobalRef::Window(ref window) => window.console_timers(), + GlobalRef::Worker(ref worker) => worker.console_timers(), } } @@ -292,7 +293,16 @@ impl<'a> GlobalRef<'a> { pub fn report_an_error(&self, error_info: ErrorInfo, value: HandleValue) { match *self { GlobalRef::Window(ref window) => window.report_an_error(error_info, value), - GlobalRef::Worker(_) => (), + GlobalRef::Worker(ref worker) => worker.report_an_error(error_info, value), + } + } +} + +impl<'a> Reflectable for GlobalRef<'a> { + fn reflector(&self) -> &Reflector { + match *self { + GlobalRef::Window(ref window) => window.reflector(), + GlobalRef::Worker(ref worker) => worker.reflector(), } } } diff --git a/components/script/dom/bindings/inheritance.rs b/components/script/dom/bindings/inheritance.rs index c9ccdbd0325..f4f1274ac6e 100644 --- a/components/script/dom/bindings/inheritance.rs +++ b/components/script/dom/bindings/inheritance.rs @@ -6,8 +6,8 @@ pub use dom::bindings::codegen::InheritTypes::*; -use dom::bindings::conversions::get_dom_class; use dom::bindings::conversions::{DerivedFrom, IDLInterface}; +use dom::bindings::conversions::get_dom_class; use dom::bindings::reflector::Reflectable; use std::mem; diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs index f7786163cc5..cae5da97887 100644 --- a/components/script/dom/bindings/interface.rs +++ b/components/script/dom/bindings/interface.rs @@ -257,7 +257,8 @@ pub unsafe fn create_named_constructors( } } -unsafe fn create_object( +/// Create a new object with a unique type. +pub unsafe fn create_object( cx: *mut JSContext, proto: HandleObject, class: &'static JSClass, @@ -316,7 +317,9 @@ pub unsafe fn is_exposed_in(object: HandleObject, globals: Globals) -> bool { globals.contains(dom_class.global) } -unsafe fn define_on_global_object( +/// Define a property with a given name on the global object. Should be called +/// through the resolve hook. +pub unsafe fn define_on_global_object( cx: *mut JSContext, global: HandleObject, name: &[u8], diff --git a/components/script/dom/bindings/iterable.rs b/components/script/dom/bindings/iterable.rs index a3092ed73b6..84381b52655 100644 --- a/components/script/dom/bindings/iterable.rs +++ b/components/script/dom/bindings/iterable.rs @@ -12,7 +12,7 @@ use dom::bindings::codegen::Bindings::IterableIteratorBinding::IterableKeyOrValu use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, Root}; -use dom::bindings::reflector::{Reflector, Reflectable, reflect_dom_object}; +use dom::bindings::reflector::{Reflector, Reflectable, MutReflectable, reflect_dom_object}; use dom::bindings::trace::JSTraceable; use js::conversions::ToJSValConvertible; use js::jsapi::{JSContext, JSObject, MutableHandleValue, MutableHandleObject, HandleValue}; @@ -63,6 +63,9 @@ impl<T: Reflectable + JSTraceable + Iterable> Reflectable for IterableIterator<T fn reflector<'a>(&'a self) -> &'a Reflector { &self.reflector } +} + +impl<T: Reflectable + JSTraceable + Iterable> MutReflectable for IterableIterator<T> { fn init_reflector(&mut self, obj: *mut JSObject) { self.reflector.set_jsobject(obj); } diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs index 8aefc71d577..16607c9045f 100644 --- a/components/script/dom/bindings/mod.rs +++ b/components/script/dom/bindings/mod.rs @@ -140,6 +140,7 @@ pub mod inheritance; pub mod interface; pub mod iterable; pub mod js; +pub mod namespace; pub mod num; pub mod proxyhandler; pub mod refcounted; diff --git a/components/script/dom/bindings/namespace.rs b/components/script/dom/bindings/namespace.rs new file mode 100644 index 00000000000..38055dea180 --- /dev/null +++ b/components/script/dom/bindings/namespace.rs @@ -0,0 +1,42 @@ +/* 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/. */ + +//! Machinery to initialise namespace objects. + +use dom::bindings::guard::Guard; +use dom::bindings::interface::{create_object, define_on_global_object}; +use js::jsapi::{HandleObject, JSClass, JSContext, JSFunctionSpec, MutableHandleObject}; +use libc; +use std::ptr; + +/// The class of a namespace object. +#[derive(Copy, Clone)] +pub struct NamespaceObjectClass(JSClass); + +unsafe impl Sync for NamespaceObjectClass {} + +impl NamespaceObjectClass { + /// Create a new `NamespaceObjectClass` structure. + pub const unsafe fn new(name: &'static [u8]) -> Self { + NamespaceObjectClass(JSClass { + name: name as *const _ as *const libc::c_char, + flags: 0, + cOps: ptr::null_mut(), + reserved: [ptr::null_mut(); 3], + }) + } +} + +/// Create a new namespace object. +pub unsafe fn create_namespace_object( + cx: *mut JSContext, + global: HandleObject, + proto: HandleObject, + class: &'static NamespaceObjectClass, + methods: &[Guard<&'static [JSFunctionSpec]>], + name: &[u8], + rval: MutableHandleObject) { + create_object(cx, proto, &class.0, methods, &[], &[], rval); + define_on_global_object(cx, global, name, rval.handle()); +} diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs index a5be8f1dc96..cacac064376 100644 --- a/components/script/dom/bindings/proxyhandler.rs +++ b/components/script/dom/bindings/proxyhandler.rs @@ -8,21 +8,22 @@ use dom::bindings::conversions::is_dom_proxy; use dom::bindings::utils::delete_property_by_id; +use js::glue::{GetProxyHandler, GetProxyHandlerFamily, SetProxyExtra}; use js::glue::GetProxyExtra; use js::glue::InvokeGetOwnPropertyDescriptor; -use js::glue::{GetProxyHandler, SetProxyExtra, GetProxyHandlerFamily}; +use js::jsapi::{DOMProxyShadowsResult, JSContext, JSObject, JSPROP_GETTER, PropertyDescriptor}; +use js::jsapi::{Handle, HandleId, HandleObject, MutableHandle, ObjectOpResult}; +use js::jsapi::{JSErrNum, JS_AlreadyHasOwnPropertyById, JS_StrictPropertyStub}; +use js::jsapi::{JS_DefinePropertyById, JS_NewObjectWithGivenProto, SetDOMProxyInformation}; use js::jsapi::GetObjectProto; use js::jsapi::GetStaticPrototype; use js::jsapi::JS_GetPropertyDescriptorById; use js::jsapi::MutableHandleObject; -use js::jsapi::{Handle, HandleId, HandleObject, MutableHandle, ObjectOpResult}; -use js::jsapi::{JSContext, JSObject, JSPROP_GETTER, PropertyDescriptor, DOMProxyShadowsResult}; -use js::jsapi::{JSErrNum, JS_StrictPropertyStub, JS_AlreadyHasOwnPropertyById}; -use js::jsapi::{JS_DefinePropertyById, JS_NewObjectWithGivenProto, SetDOMProxyInformation}; use js::jsval::ObjectValue; use libc; use std::{mem, ptr}; + static JSPROXYSLOT_EXPANDO: u32 = 0; /// Determine if this id shadows any existing properties for this proxy. diff --git a/components/script/dom/bindings/reflector.rs b/components/script/dom/bindings/reflector.rs index 04466ea6926..d5280712a03 100644 --- a/components/script/dom/bindings/reflector.rs +++ b/components/script/dom/bindings/reflector.rs @@ -73,11 +73,15 @@ impl Reflector { pub trait Reflectable { /// Returns the receiver's reflector. fn reflector(&self) -> &Reflector; - /// Initializes the Reflector - fn init_reflector(&mut self, obj: *mut JSObject); /// Returns the global object of the realm that the Reflectable was created in. fn global(&self) -> GlobalRoot where Self: Sized { global_root_from_reflector(self) } } + +/// A trait to initialize the `Reflector` for a DOM object. +pub trait MutReflectable: Reflectable { + /// Initializes the Reflector + fn init_reflector(&mut self, obj: *mut JSObject); +} diff --git a/components/script/dom/bindings/str.rs b/components/script/dom/bindings/str.rs index c73a08d182b..2e28a1b314e 100644 --- a/components/script/dom/bindings/str.rs +++ b/components/script/dom/bindings/str.rs @@ -5,7 +5,7 @@ //! The `ByteString` struct. use std::ascii::AsciiExt; -use std::borrow::{ToOwned, Cow}; +use std::borrow::{Borrow, Cow, ToOwned}; use std::fmt; use std::hash::{Hash, Hasher}; use std::ops; @@ -180,6 +180,13 @@ impl DOMString { } } +impl Borrow<str> for DOMString { + #[inline] + fn borrow(&self) -> &str { + &self.0 + } +} + impl Default for DOMString { fn default() -> Self { DOMString(String::new()) diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 1f46b3f649c..fae24096bac 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -50,20 +50,22 @@ use html5ever::tree_builder::QuirksMode; use hyper::header::Headers; use hyper::method::Method; use hyper::mime::Mime; +use hyper::status::StatusCode; use ipc_channel::ipc::{IpcReceiver, IpcSender}; use js::glue::{CallObjectTracer, CallUnbarrieredObjectTracer, CallValueTracer}; -use js::jsapi::{GCTraceKindToAscii, Heap, TraceKind, JSObject, JSTracer}; +use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind}; use js::jsval::JSVal; use js::rust::Runtime; use libc; -use msg::constellation_msg::{FrameType, PipelineId, SubpageId, WindowSizeType, ReferrerPolicy}; +use msg::constellation_msg::{FrameType, PipelineId, ReferrerPolicy, SubpageId, WindowSizeType}; +use net_traits::{Metadata, NetworkError, ResourceThreads}; use net_traits::filemanager_thread::RelativePos; use net_traits::image::base::{Image, ImageMetadata}; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread}; use net_traits::request::Request; +use net_traits::response::{Response, ResponseBody}; use net_traits::response::HttpsState; use net_traits::storage_thread::StorageType; -use net_traits::{Metadata, NetworkError, ResourceThreads}; use offscreen_gl_context::GLLimits; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan as TimeProfilerChan; @@ -91,7 +93,7 @@ use style::attr::{AttrIdentifier, AttrValue, LengthOrPercentageOrAuto}; use style::domrefcell::DOMRefCell; use style::element_state::*; use style::properties::PropertyDeclarationBlock; -use style::selector_impl::{PseudoElement, ElementSnapshot}; +use style::selector_impl::{ElementSnapshot, PseudoElement}; use style::values::specified::Length; use time::Duration; use url::Origin as UrlOrigin; @@ -339,7 +341,10 @@ no_jsmanaged_fields!(SharedRt); no_jsmanaged_fields!(TouchpadPressurePhase); no_jsmanaged_fields!(USVString); no_jsmanaged_fields!(ReferrerPolicy); +no_jsmanaged_fields!(Response); +no_jsmanaged_fields!(ResponseBody); no_jsmanaged_fields!(ResourceThreads); +no_jsmanaged_fields!(StatusCode); no_jsmanaged_fields!(SystemTime); no_jsmanaged_fields!(Instant); no_jsmanaged_fields!(RelativePos); diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 0e513081e10..78990f40564 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -14,9 +14,9 @@ use dom::bindings::str::DOMString; use encoding::all::UTF_8; use encoding::types::{EncoderTrap, Encoding}; use ipc_channel::ipc; -use net_traits::blob_url_store::{BlobBuf, get_blob_origin}; -use net_traits::filemanager_thread::{FileManagerThreadMsg, RelativePos, ReadFileProgress}; use net_traits::{CoreResourceMsg, IpcSend}; +use net_traits::blob_url_store::{BlobBuf, get_blob_origin}; +use net_traits::filemanager_thread::{FileManagerThreadMsg, ReadFileProgress, RelativePos}; use std::cell::Cell; use std::mem; use std::ops::Index; diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index c86fa0150a3..6540f6c971f 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -5,8 +5,8 @@ use bluetooth_blacklist::{Blacklist, uuid_is_blacklisted}; use core::clone::Clone; use dom::bindings::codegen::Bindings::BluetoothBinding; +use dom::bindings::codegen::Bindings::BluetoothBinding::{BluetoothMethods, BluetoothScanFilter}; use dom::bindings::codegen::Bindings::BluetoothBinding::RequestDeviceOptions; -use dom::bindings::codegen::Bindings::BluetoothBinding::{BluetoothScanFilter, BluetoothMethods}; use dom::bindings::error::Error::{self, Security, Type}; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs index 0c27097625c..c88463920e6 100644 --- a/components/script/dom/bluetoothremotegattcharacteristic.rs +++ b/components/script/dom/bluetoothremotegattcharacteristic.rs @@ -12,8 +12,8 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTCharacteristicBinding:: BluetoothRemoteGATTCharacteristicMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods; +use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{self, InvalidModification, Network, NotSupported, Security}; -use dom::bindings::error::{Fallible, ErrorResult}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, MutHeap, Root}; use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; diff --git a/components/script/dom/bluetoothremotegattdescriptor.rs b/components/script/dom/bluetoothremotegattdescriptor.rs index 0ba52181b48..a726de42974 100644 --- a/components/script/dom/bluetoothremotegattdescriptor.rs +++ b/components/script/dom/bluetoothremotegattdescriptor.rs @@ -11,8 +11,8 @@ use dom::bindings::codegen::Bindings::BluetoothRemoteGATTDescriptorBinding; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTDescriptorBinding::BluetoothRemoteGATTDescriptorMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServiceBinding::BluetoothRemoteGATTServiceMethods; +use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{self, InvalidModification, Network, Security}; -use dom::bindings::error::{Fallible, ErrorResult}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, MutHeap, Root}; use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; diff --git a/components/script/dom/bluetoothremotegattserver.rs b/components/script/dom/bluetoothremotegattserver.rs index f4b1e532f10..615094623e9 100644 --- a/components/script/dom/bluetoothremotegattserver.rs +++ b/components/script/dom/bluetoothremotegattserver.rs @@ -6,8 +6,8 @@ use bluetooth_blacklist::{Blacklist, uuid_is_blacklisted}; use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; +use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{self, Security}; -use dom::bindings::error::{Fallible, ErrorResult}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, MutHeap, Root}; use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; diff --git a/components/script/dom/browsingcontext.rs b/components/script/dom/browsingcontext.rs index 18fbe914cef..919b574c27a 100644 --- a/components/script/dom/browsingcontext.rs +++ b/components/script/dom/browsingcontext.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::conversions::{ToJSValConvertible, root_from_handleobject}; use dom::bindings::js::{JS, Root, RootedReference}; use dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor}; -use dom::bindings::reflector::{Reflectable, Reflector}; +use dom::bindings::reflector::{Reflectable, MutReflectable, Reflector}; use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::WindowProxyHandler; diff --git a/components/script/dom/canvasgradient.rs b/components/script/dom/canvasgradient.rs index f47589b60af..a805b485796 100644 --- a/components/script/dom/canvasgradient.rs +++ b/components/script/dom/canvasgradient.rs @@ -3,8 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use canvas_traits::{CanvasGradientStop, FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle}; -use cssparser::Color as CSSColor; use cssparser::{Parser, RGBA}; +use cssparser::Color as CSSColor; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::CanvasGradientBinding; use dom::bindings::codegen::Bindings::CanvasGradientBinding::CanvasGradientMethods; diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 61cc2520165..13610c53487 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -6,8 +6,8 @@ use canvas_traits::{Canvas2dMsg, CanvasCommonMsg, CanvasMsg}; use canvas_traits::{CompositionOrBlending, FillOrStrokeStyle, FillRule}; use canvas_traits::{LineCapStyle, LineJoinStyle, LinearGradientStyle}; use canvas_traits::{RadialGradientStyle, RepetitionStyle, byte_swap, byte_swap_and_premultiply}; -use cssparser::Color as CSSColor; use cssparser::{Parser, RGBA}; +use cssparser::Color as CSSColor; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods; use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding; @@ -19,7 +19,7 @@ use dom::bindings::codegen::Bindings::ImageDataBinding::ImageDataMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::UnionTypes::HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D; use dom::bindings::codegen::UnionTypes::StringOrCanvasGradientOrCanvasPattern; -use dom::bindings::error::{Error, Fallible, ErrorResult}; +use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, LayoutJS, Root}; @@ -42,9 +42,9 @@ use net_traits::image::base::PixelFormat; use net_traits::image_cache_thread::ImageResponse; use num_traits::ToPrimitive; use script_traits::ScriptMsg as ConstellationMsg; +use std::{cmp, fmt}; use std::cell::Cell; use std::str::FromStr; -use std::{cmp, fmt}; use unpremultiplytable::UNPREMULTIPLY_TABLE; use url::Url; use util::opts; diff --git a/components/script/dom/client.rs b/components/script/dom/client.rs index 1039ff1a04a..d800d6f55e0 100644 --- a/components/script/dom/client.rs +++ b/components/script/dom/client.rs @@ -2,8 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::codegen::Bindings::ClientBinding::FrameType; use dom::bindings::codegen::Bindings::ClientBinding::{ClientMethods, Wrap}; +use dom::bindings::codegen::Bindings::ClientBinding::FrameType; use dom::bindings::global::GlobalRef; use dom::bindings::js::JS; use dom::bindings::js::Root; diff --git a/components/script/dom/console.rs b/components/script/dom/console.rs index 9382bf936a8..37d549befd9 100644 --- a/components/script/dom/console.rs +++ b/components/script/dom/console.rs @@ -4,39 +4,17 @@ use devtools_traits::{ConsoleMessage, LogLevel, ScriptToDevtoolsControlMsg}; use dom::bindings::cell::DOMRefCell; -use dom::bindings::codegen::Bindings::ConsoleBinding; -use dom::bindings::codegen::Bindings::ConsoleBinding::ConsoleMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::Root; -use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use std::collections::HashMap; +use std::collections::hash_map::Entry; use time::{Timespec, get_time}; // https://developer.mozilla.org/en-US/docs/Web/API/Console -#[dom_struct] -pub struct Console { - reflector_: Reflector, - timers: DOMRefCell<HashMap<DOMString, u64>>, -} +pub struct Console(()); impl Console { - fn new_inherited() -> Console { - Console { - reflector_: Reflector::new(), - timers: DOMRefCell::new(HashMap::new()), - } - } - - pub fn new(global: GlobalRef) -> Root<Console> { - reflect_dom_object(box Console::new_inherited(), - global, - ConsoleBinding::Wrap) - } - - fn send_to_devtools(&self, level: LogLevel, message: DOMString) { - let global = self.global(); - let global = global.r(); + fn send_to_devtools(global: GlobalRef, level: LogLevel, message: DOMString) { if let Some(chan) = global.devtools_chan() { let console_message = prepare_message(level, message); let devtools_message = ScriptToDevtoolsControlMsg::ConsoleAPI( @@ -48,83 +26,73 @@ impl Console { } } -impl ConsoleMethods for Console { +impl Console { // https://developer.mozilla.org/en-US/docs/Web/API/Console/log - fn Log(&self, messages: Vec<DOMString>) { + pub fn Log(global: GlobalRef, messages: Vec<DOMString>) { for message in messages { println!("{}", message); - self.send_to_devtools(LogLevel::Log, message); + Self::send_to_devtools(global, LogLevel::Log, message); } } // https://developer.mozilla.org/en-US/docs/Web/API/Console - fn Debug(&self, messages: Vec<DOMString>) { + pub fn Debug(global: GlobalRef, messages: Vec<DOMString>) { for message in messages { println!("{}", message); - self.send_to_devtools(LogLevel::Debug, message); + Self::send_to_devtools(global, LogLevel::Debug, message); } } // https://developer.mozilla.org/en-US/docs/Web/API/Console/info - fn Info(&self, messages: Vec<DOMString>) { + pub fn Info(global: GlobalRef, messages: Vec<DOMString>) { for message in messages { println!("{}", message); - self.send_to_devtools(LogLevel::Info, message); + Self::send_to_devtools(global, LogLevel::Info, message); } } // https://developer.mozilla.org/en-US/docs/Web/API/Console/warn - fn Warn(&self, messages: Vec<DOMString>) { + pub fn Warn(global: GlobalRef, messages: Vec<DOMString>) { for message in messages { println!("{}", message); - self.send_to_devtools(LogLevel::Warn, message); + Self::send_to_devtools(global, LogLevel::Warn, message); } } // https://developer.mozilla.org/en-US/docs/Web/API/Console/error - fn Error(&self, messages: Vec<DOMString>) { + pub fn Error(global: GlobalRef, messages: Vec<DOMString>) { for message in messages { println!("{}", message); - self.send_to_devtools(LogLevel::Error, message); + Self::send_to_devtools(global, LogLevel::Error, message); } } // https://developer.mozilla.org/en-US/docs/Web/API/Console/assert - fn Assert(&self, condition: bool, message: Option<DOMString>) { + pub fn Assert(global: GlobalRef, condition: bool, message: Option<DOMString>) { if !condition { let message = message.unwrap_or_else(|| DOMString::from("no message")); println!("Assertion failed: {}", message); - self.send_to_devtools(LogLevel::Error, message); + Self::send_to_devtools(global, LogLevel::Error, message); } } // https://developer.mozilla.org/en-US/docs/Web/API/Console/time - fn Time(&self, label: DOMString) { - let mut timers = self.timers.borrow_mut(); - if timers.contains_key(&label) { - // Timer already started - return; - } - if timers.len() >= 10000 { - // Too many timers on page - return; + pub fn Time(global: GlobalRef, label: DOMString) { + if let Ok(()) = global.console_timers().time(label.clone()) { + let message = DOMString::from(format!("{}: timer started", label)); + println!("{}", message); + Self::send_to_devtools(global, LogLevel::Log, message); } - - timers.insert(label.clone(), timestamp_in_ms(get_time())); - let message = DOMString::from(format!("{}: timer started", label)); - println!("{}", message); - self.send_to_devtools(LogLevel::Log, message); } // https://developer.mozilla.org/en-US/docs/Web/API/Console/timeEnd - fn TimeEnd(&self, label: DOMString) { - let mut timers = self.timers.borrow_mut(); - if let Some(start) = timers.remove(&label) { + pub fn TimeEnd(global: GlobalRef, label: DOMString) { + if let Ok(delta) = global.console_timers().time_end(&label) { let message = DOMString::from( - format!("{}: {}ms", label, timestamp_in_ms(get_time()) - start) + format!("{}: {}ms", label, delta) ); println!("{}", message); - self.send_to_devtools(LogLevel::Log, message); + Self::send_to_devtools(global, LogLevel::Log, message); }; } } @@ -143,3 +111,32 @@ fn prepare_message(logLevel: LogLevel, message: DOMString) -> ConsoleMessage { columnNumber: 1, } } + +#[derive(HeapSizeOf, JSTraceable)] +pub struct TimerSet(DOMRefCell<HashMap<DOMString, u64>>); + +impl TimerSet { + pub fn new() -> Self { + TimerSet(DOMRefCell::new(Default::default())) + } + + fn time(&self, label: DOMString) -> Result<(), ()> { + let mut timers = self.0.borrow_mut(); + if timers.len() >= 10000 { + return Err(()); + } + match timers.entry(label) { + Entry::Vacant(entry) => { + entry.insert(timestamp_in_ms(get_time())); + Ok(()) + }, + Entry::Occupied(_) => Err(()), + } + } + + fn time_end(&self, label: &str) -> Result<u64, ()> { + self.0.borrow_mut().remove(label).ok_or(()).map(|start| { + timestamp_in_ms(get_time()) - start + }) + } +} diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index d537d8f3fd3..4f0bad72949 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -4,21 +4,24 @@ use devtools; use devtools_traits::DevtoolScriptControlMsg; -use dom::abstractworker::{WorkerScriptMsg, SharedRt , SimpleWorkerErrorHandler}; +use dom::abstractworker::{SharedRt, SimpleWorkerErrorHandler, WorkerScriptMsg}; use dom::abstractworkerglobalscope::{SendableWorkerScriptChan, WorkerThreadWorkerChan}; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding; use dom::bindings::codegen::Bindings::DedicatedWorkerGlobalScopeBinding::DedicatedWorkerGlobalScopeMethods; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; -use dom::bindings::error::ErrorResult; +use dom::bindings::error::{ErrorInfo, ErrorResult}; use dom::bindings::global::{GlobalRef, global_root_from_context}; use dom::bindings::inheritance::Castable; 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::eventtarget::EventTarget; use dom::messageevent::MessageEvent; -use dom::worker::{TrustedWorkerAddress, WorkerMessageHandler}; +use dom::worker::{TrustedWorkerAddress, WorkerErrorHandler, WorkerMessageHandler}; use dom::workerglobalscope::WorkerGlobalScope; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; @@ -27,15 +30,16 @@ use js::jsapi::{JSAutoCompartment, JSContext}; use js::jsval::UndefinedValue; use js::rust::Runtime; use msg::constellation_msg::PipelineId; -use net_traits::{LoadContext, load_whole_resource, IpcSend}; +use net_traits::{IpcSend, LoadContext, load_whole_resource}; use rand::random; -use script_runtime::ScriptThreadEventCategory::WorkerEvent; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, StackRootTLS, get_reports, new_rt_and_cx}; -use script_traits::{TimerEvent, TimerSource, WorkerScriptLoadOrigin, WorkerGlobalScopeInit}; +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; use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel}; -use std::sync::{Arc, Mutex}; use style::thread_state; use url::Url; use util::thread::spawn_named; @@ -88,6 +92,8 @@ 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 { @@ -116,6 +122,7 @@ impl DedicatedWorkerGlobalScope { timer_event_port: timer_event_port, parent_sender: parent_sender, worker: DOMRefCell::new(None), + in_error_reporting_mode: Cell::new(false), } } @@ -339,6 +346,42 @@ 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 handled = !event.upcast::<Event>().fire(self.upcast::<EventTarget>()); + if !handled { + 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(); + } + + self.in_error_reporting_mode.set(false); + } } #[allow(unsafe_code)] diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index d0eebc77c80..fe55c035ff7 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -23,14 +23,14 @@ use dom::bindings::codegen::UnionTypes::NodeOrString; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId}; -use dom::bindings::js::RootedReference; use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root}; +use dom::bindings::js::RootedReference; use dom::bindings::num::Finite; use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::{DOMString, USVString}; +use dom::bindings::xmlname::{namespace_from_domstring, validate_and_extract, xml_name_type}; use dom::bindings::xmlname::XMLName::InvalidXMLName; -use dom::bindings::xmlname::{validate_and_extract, namespace_from_domstring, xml_name_type}; use dom::browsingcontext::BrowsingContext; use dom::closeevent::CloseEvent; use dom::comment::Comment; @@ -90,24 +90,24 @@ use encoding::all::UTF_8; use euclid::point::Point2D; use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks, QuirksMode}; use ipc_channel::ipc::{self, IpcSender}; -use js::jsapi::JS_GetRuntime; use js::jsapi::{JSContext, JSObject, JSRuntime}; +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, SubpageId}; +use net_traits::{AsyncResponseTarget, IpcSend, PendingAsyncLoad}; use net_traits::CookieSource::NonHTTP; use net_traits::CoreResourceMsg::{GetCookiesForUrl, SetCookiesForUrl}; use net_traits::response::HttpsState; -use net_traits::{AsyncResponseTarget, PendingAsyncLoad, IpcSend}; use num_traits::ToPrimitive; use origin::Origin; -use parse::{ParserRoot, ParserRef, MutNullableParserField}; +use parse::{MutNullableParserField, ParserRef, ParserRoot}; use script_layout_interface::message::{Msg, ReflowQueryType}; use script_thread::{MainThreadScriptMsg, Runnable}; -use script_traits::UntrustedNodeAddress; use script_traits::{AnimationState, MouseButton, MouseEventType, MozBrowserEvent}; use script_traits::{ScriptMsg as ConstellationMsg, TouchpadPressurePhase}; use script_traits::{TouchEventType, TouchId}; +use script_traits::UntrustedNodeAddress; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::boxed::FnBox; diff --git a/components/script/dom/domimplementation.rs b/components/script/dom/domimplementation.rs index 824cc0b88cf..dd55630204c 100644 --- a/components/script/dom/domimplementation.rs +++ b/components/script/dom/domimplementation.rs @@ -13,9 +13,9 @@ use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; -use dom::bindings::xmlname::{validate_qualified_name, namespace_from_domstring}; -use dom::document::DocumentSource; +use dom::bindings::xmlname::{namespace_from_domstring, validate_qualified_name}; use dom::document::{Document, IsHTMLDocument}; +use dom::document::DocumentSource; use dom::documenttype::DocumentType; use dom::htmlbodyelement::HTMLBodyElement; use dom::htmlheadelement::HTMLHeadElement; diff --git a/components/script/dom/domparser.rs b/components/script/dom/domparser.rs index 3964c84abcb..a52f0b8b82f 100644 --- a/components/script/dom/domparser.rs +++ b/components/script/dom/domparser.rs @@ -16,8 +16,8 @@ use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, Root}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; -use dom::document::DocumentSource; use dom::document::{Document, IsHTMLDocument}; +use dom::document::DocumentSource; use dom::window::Window; use parse::html::{ParseContext, parse_html}; use parse::xml::{self, parse_xml}; diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 8dea99bcd4a..f85f608545f 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -17,8 +17,8 @@ use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods; use dom::bindings::codegen::Bindings::EventBinding::EventMethods; use dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; -use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions}; +use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::UnionTypes::NodeOrString; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; @@ -26,8 +26,8 @@ use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, Nod use dom::bindings::js::{JS, LayoutJS, MutNullableHeap}; use dom::bindings::js::{Root, RootedReference}; use dom::bindings::str::DOMString; -use dom::bindings::xmlname::XMLName::InvalidXMLName; use dom::bindings::xmlname::{namespace_from_domstring, validate_and_extract, xml_name_type}; +use dom::bindings::xmlname::XMLName::InvalidXMLName; use dom::characterdata::CharacterData; use dom::create::create_element; use dom::document::{Document, LayoutDocumentHelpers}; @@ -71,7 +71,7 @@ use html5ever::serialize::TraversalScope; use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode}; use html5ever::tree_builder::{LimitedQuirks, NoQuirks, Quirks}; use selectors::matching::{ElementFlags, MatchingReason, matches}; -use selectors::matching::{HAS_SLOW_SELECTOR, HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS}; +use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS}; use selectors::parser::{AttrSelector, NamespaceConstraint, parse_author_origin_selector_list_from_str}; use std::ascii::AsciiExt; use std::borrow::Cow; @@ -86,9 +86,9 @@ use style::attr::{AttrValue, LengthOrPercentageOrAuto}; use style::element_state::*; use style::matching::{common_style_affecting_attributes, rare_style_affecting_attributes}; use style::parser::ParserContextExtraData; -use style::properties::longhands::{self, background_image, border_spacing, font_family, overflow_x, font_size}; use style::properties::{DeclaredValue, Importance}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute}; +use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size, overflow_x}; use style::refcell::Ref; use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use style::selector_matching::ApplicableDeclarationBlock; diff --git a/components/script/dom/headers.rs b/components/script/dom/headers.rs index 7b45956c039..abfa959c8e6 100644 --- a/components/script/dom/headers.rs +++ b/components/script/dom/headers.rs @@ -209,7 +209,13 @@ impl Headers { headers_for_request } - pub fn set_guard(&self, new_guard: Guard) { + pub fn for_response(global: GlobalRef) -> Root<Headers> { + let headers_for_response = Headers::new(global); + headers_for_response.guard.set(Guard::Response); + headers_for_response + } + + pub fn set_guard(&self, new_guard: Guard) { self.guard.set(new_guard) } @@ -346,7 +352,7 @@ pub fn is_forbidden_header_name(name: &str) -> bool { // [3] https://tools.ietf.org/html/rfc7230#section-3.2.6 // [4] https://www.rfc-editor.org/errata_search.php?rfc=7230 fn validate_name_and_value(name: ByteString, value: ByteString) - -> Result<(String, Vec<u8>), Error> { + -> Fallible<(String, Vec<u8>)> { let valid_name = try!(validate_name(name)); if !is_field_content(&value) { return Err(Error::Type("Value is not valid".to_string())); @@ -354,7 +360,7 @@ fn validate_name_and_value(name: ByteString, value: ByteString) Ok((valid_name, value.into())) } -fn validate_name(name: ByteString) -> Result<String, Error> { +fn validate_name(name: ByteString) -> Fallible<String> { if !is_field_name(&name) { return Err(Error::Type("Name is not valid".to_string())); } @@ -444,7 +450,7 @@ fn is_field_vchar(x: u8) -> bool { } // https://tools.ietf.org/html/rfc5234#appendix-B.1 -fn is_vchar(x: u8) -> bool { +pub fn is_vchar(x: u8) -> bool { match x { 0x21...0x7E => true, _ => false, @@ -452,7 +458,7 @@ fn is_vchar(x: u8) -> bool { } // http://tools.ietf.org/html/rfc7230#section-3.2.6 -fn is_obs_text(x: u8) -> bool { +pub fn is_obs_text(x: u8) -> bool { match x { 0x80...0xFF => true, _ => false, diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs index 6c15cf92150..af95ec404b9 100644 --- a/components/script/dom/htmlbuttonelement.rs +++ b/components/script/dom/htmlbuttonelement.rs @@ -15,9 +15,9 @@ use dom::event::Event; use dom::eventtarget::EventTarget; use dom::htmlelement::HTMLElement; use dom::htmlfieldsetelement::HTMLFieldSetElement; -use dom::htmlformelement::HTMLFormElement; use dom::htmlformelement::{FormControl, FormDatum, FormDatumValue}; use dom::htmlformelement::{FormSubmitter, ResetFrom, SubmittedFrom}; +use dom::htmlformelement::HTMLFormElement; use dom::node::{Node, UnbindContext, document_from_node, window_from_node}; use dom::nodelist::NodeList; use dom::validation::Validatable; diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index e9d967514d7..4ec42ced6d6 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -11,8 +11,8 @@ use dom::bindings::codegen::Bindings::HTMLElementBinding; use dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::error::{Error, ErrorResult}; -use dom::bindings::inheritance::Castable; use dom::bindings::inheritance::{ElementTypeId, HTMLElementTypeId, NodeTypeId}; +use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; use dom::bindings::str::DOMString; use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration}; diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 2cc946ec933..59578b37b59 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -2,7 +2,7 @@ * 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 document_loader::{LoadType, LoadBlocker}; +use document_loader::{LoadBlocker, LoadType}; use dom::attr::Attr; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserElementErrorEventDetail; @@ -20,7 +20,7 @@ use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root, LayoutJS}; +use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root}; use dom::bindings::reflector::Reflectable; use dom::bindings::str::DOMString; use dom::browsingcontext::BrowsingContext; @@ -31,18 +31,18 @@ use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers}; use dom::event::Event; use dom::eventtarget::EventTarget; use dom::htmlelement::HTMLElement; -use dom::node::{Node, NodeDamage, UnbindContext, window_from_node, document_from_node}; +use dom::node::{Node, NodeDamage, UnbindContext, document_from_node, window_from_node}; use dom::urlhelper::UrlHelper; use dom::virtualmethods::VirtualMethods; use dom::window::{ReflowReason, Window}; use ipc_channel::ipc; use js::jsapi::{JSAutoCompartment, JSContext, MutableHandleValue}; -use js::jsval::{UndefinedValue, NullValue}; -use msg::constellation_msg::{FrameType, LoadData, TraversalDirection, PipelineId, SubpageId}; +use js::jsval::{NullValue, UndefinedValue}; +use msg::constellation_msg::{FrameType, LoadData, PipelineId, SubpageId, TraversalDirection}; use net_traits::response::HttpsState; use script_layout_interface::message::ReflowQueryType; -use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed}; use script_traits::{IFrameLoadInfo, MozBrowserEvent, ScriptMsg as ConstellationMsg}; +use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed}; use std::cell::Cell; use string_cache::Atom; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index a98fcbcfb4e..978d93f6138 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -13,17 +13,17 @@ use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementM use dom::bindings::codegen::Bindings::KeyboardEventBinding::KeyboardEventMethods; use dom::bindings::error::{Error, ErrorResult}; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, LayoutJS, Root, RootedReference, MutNullableHeap}; +use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root, RootedReference}; use dom::bindings::str::DOMString; use dom::document::Document; -use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers, LayoutElementHelpers}; +use dom::element::{AttributeMutation, Element, LayoutElementHelpers, RawLayoutElementHelpers}; use dom::event::{Event, EventBubbles, EventCancelable}; use dom::eventtarget::EventTarget; use dom::file::File; use dom::filelist::FileList; use dom::htmlelement::HTMLElement; use dom::htmlfieldsetelement::HTMLFieldSetElement; -use dom::htmlformelement::{FormDatumValue, FormControl, FormDatum, FormSubmitter, HTMLFormElement}; +use dom::htmlformelement::{FormControl, FormDatum, FormDatumValue, FormSubmitter, HTMLFormElement}; use dom::htmlformelement::{ResetFrom, SubmittedFrom}; use dom::keyboardevent::KeyboardEvent; use dom::node::{Node, NodeDamage, UnbindContext}; @@ -34,9 +34,9 @@ use dom::virtualmethods::VirtualMethods; use ipc_channel::ipc::{self, IpcSender}; use mime_guess; use msg::constellation_msg::Key; +use net_traits::{CoreResourceMsg, IpcSend}; use net_traits::blob_url_store::get_blob_origin; use net_traits::filemanager_thread::{FileManagerThreadMsg, FilterPattern}; -use net_traits::{IpcSend, CoreResourceMsg}; use script_traits::ScriptMsg as ConstellationMsg; use std::borrow::ToOwned; use std::cell::Cell; @@ -45,9 +45,9 @@ use string_cache::Atom; use style::attr::AttrValue; use style::element_state::*; use style::str::split_commas; +use textinput::{SelectionDirection, TextInput}; use textinput::KeyReaction::{DispatchInput, Nothing, RedrawSelection, TriggerDefaultAction}; use textinput::Lines::Single; -use textinput::{TextInput, SelectionDirection}; const DEFAULT_SUBMIT_VALUE: &'static str = "Submit"; const DEFAULT_RESET_VALUE: &'static str = "Reset"; diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 9264bcb0490..07cd47cbcec 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -22,7 +22,6 @@ use dom::virtualmethods::VirtualMethods; use encoding::EncodingRef; use encoding::all::UTF_8; use hyper::header::ContentType; -use hyper::http::RawStatus; use hyper::mime::{Mime, TopLevel, SubLevel}; use hyper_serde::Serde; use ipc_channel::ipc; @@ -335,7 +334,7 @@ impl AsyncResponseListener for StylesheetContext { document.invalidate_stylesheets(); // FIXME: Revisit once consensus is reached at: https://github.com/whatwg/html/issues/1142 - successful = metadata.status.map_or(false, |Serde(RawStatus(code, _))| code == 200); + successful = metadata.status.map_or(false, |(code, _)| code == 200); } if elem.parser_inserted.get() { diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index d26ac6a044e..6be1fbb3d96 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -2,6 +2,7 @@ * 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 audio_video_metadata; use document_loader::LoadType; use dom::attr::Attr; use dom::bindings::cell::DOMRefCell; @@ -24,7 +25,6 @@ use dom::htmlsourceelement::HTMLSourceElement; use dom::mediaerror::MediaError; use dom::node::{window_from_node, document_from_node, Node, UnbindContext}; use dom::virtualmethods::VirtualMethods; -use hyper_serde::Serde; use ipc_channel::ipc; use ipc_channel::router::ROUTER; use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, NetworkError}; @@ -66,7 +66,7 @@ impl AsyncResponseListener for HTMLMediaElementContext { .as_ref() .and_then(|m| m.status .as_ref() - .map(|&Serde(ref s)| s.0 < 200 || s.0 >= 300)) + .map(|&(s, _)| s < 200 || s >= 300)) .unwrap_or(false); if is_failure { // Ensure that the element doesn't receive any further notifications @@ -160,12 +160,24 @@ impl HTMLMediaElementContext { } fn check_metadata(&mut self, elem: &HTMLMediaElement) { - // Step 6. - // - // TODO: Properly implement once we have figured out the build and - // licensing ffmpeg issues. - elem.change_ready_state(HAVE_METADATA); - self.have_metadata = true; + match audio_video_metadata::get_format_from_slice(&self.data) { + Ok(audio_video_metadata::Metadata::Video(meta)) => { + let dur = meta.audio.duration.unwrap_or(::std::time::Duration::new(0, 0)); + *elem.video.borrow_mut() = Some(VideoMedia { + format: format!("{:?}", meta.format), + duration: Duration::seconds(dur.as_secs() as i64) + + Duration::nanoseconds(dur.subsec_nanos() as i64), + width: meta.dimensions.width, + height: meta.dimensions.height, + video: meta.video.unwrap_or("".to_owned()), + audio: meta.audio.audio, + }); + // Step 6 + elem.change_ready_state(HAVE_METADATA); + self.have_metadata = true; + } + _ => {} + } } } diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 6a6fe7d50b4..6484de1e029 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -11,8 +11,8 @@ use dom::bindings::codegen::Bindings::HTMLScriptElementBinding::HTMLScriptElemen use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; -use dom::bindings::js::RootedReference; use dom::bindings::js::{JS, Root}; +use dom::bindings::js::RootedReference; use dom::bindings::refcounted::Trusted; use dom::bindings::str::DOMString; use dom::document::Document; @@ -26,8 +26,6 @@ use dom::window::ScriptHelpers; use encoding::label::encoding_from_whatwg_label; use encoding::types::{DecoderTrap, EncodingRef}; use html5ever::tree_builder::NextParserState; -use hyper::http::RawStatus; -use hyper_serde::Serde; use ipc_channel::ipc; use ipc_channel::router::ROUTER; use js::jsval::UndefinedValue; @@ -159,7 +157,7 @@ impl AsyncResponseListener for ScriptContext { let status_code = self.metadata.as_ref().and_then(|m| { match m.status { - Some(Serde(RawStatus(c, _))) => Some(c), + Some((c, _)) => Some(c), _ => None, } }).unwrap_or(0); diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index a89df91f99b..5df0778fa2b 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -12,8 +12,8 @@ use dom::bindings::inheritance::Castable; use dom::bindings::js::{LayoutJS, Root}; use dom::bindings::str::DOMString; use dom::document::Document; -use dom::element::RawLayoutElementHelpers; use dom::element::{AttributeMutation, Element}; +use dom::element::RawLayoutElementHelpers; use dom::event::{Event, EventBubbles, EventCancelable}; use dom::htmlelement::HTMLElement; use dom::htmlfieldsetelement::HTMLFieldSetElement; @@ -31,7 +31,7 @@ use std::ops::Range; use string_cache::Atom; use style::attr::AttrValue; use style::element_state::*; -use textinput::{KeyReaction, Lines, TextInput, SelectionDirection}; +use textinput::{KeyReaction, Lines, SelectionDirection, TextInput}; #[dom_struct] pub struct HTMLTextAreaElement { diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 07e4d6227be..f38d1e8949c 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -372,6 +372,7 @@ pub mod progressevent; pub mod radionodelist; pub mod range; pub mod request; +pub mod response; pub mod screen; pub mod serviceworker; pub mod serviceworkercontainer; diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 555c7719fb1..5f1bee3a730 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -23,9 +23,9 @@ use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::{Castable, CharacterDataTypeId, ElementTypeId}; use dom::bindings::inheritance::{EventTargetTypeId, HTMLElementTypeId, NodeTypeId}; +use dom::bindings::js::{JS, LayoutJS, MutNullableHeap}; use dom::bindings::js::Root; use dom::bindings::js::RootedReference; -use dom::bindings::js::{JS, LayoutJS, MutNullableHeap}; use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::{DOMString, USVString}; use dom::bindings::xmlname::namespace_from_domstring; @@ -59,9 +59,9 @@ use libc::{self, c_void, uintptr_t}; use msg::constellation_msg::PipelineId; use parse::html::parse_html_fragment; use ref_slice::ref_slice; -use script_layout_interface::message::Msg; use script_layout_interface::{HTMLCanvasData, OpaqueStyleAndLayoutData}; -use script_layout_interface::{LayoutNodeType, LayoutElementType, TrustedNodeAddress}; +use script_layout_interface::{LayoutElementType, LayoutNodeType, TrustedNodeAddress}; +use script_layout_interface::message::Msg; use script_traits::UntrustedNodeAddress; use selectors::matching::{MatchingReason, matches}; use selectors::parser::Selector; diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs index b8cb72c4dc4..bab6bdcc3a2 100644 --- a/components/script/dom/range.rs +++ b/components/script/dom/range.rs @@ -6,14 +6,14 @@ use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods use dom::bindings::codegen::Bindings::NodeBinding::NodeConstants; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods; -use dom::bindings::codegen::Bindings::RangeBinding::RangeMethods; use dom::bindings::codegen::Bindings::RangeBinding::{self, RangeConstants}; +use dom::bindings::codegen::Bindings::RangeBinding::RangeMethods; use dom::bindings::codegen::Bindings::TextBinding::TextMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; -use dom::bindings::inheritance::Castable; use dom::bindings::inheritance::{CharacterDataTypeId, NodeTypeId}; +use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutHeap, Root, RootedReference}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs index c396c0d36e1..a32799cd61c 100644 --- a/components/script/dom/request.rs +++ b/components/script/dom/request.rs @@ -19,10 +19,11 @@ use dom::bindings::error::{Error, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; -use dom::bindings::str::{ByteString, USVString, DOMString}; -use dom::headers::{Headers, Guard}; +use dom::bindings::str::{ByteString, DOMString, USVString}; +use dom::headers::{Guard, Headers}; use hyper; -use msg::constellation_msg::{ReferrerPolicy as MsgReferrerPolicy}; +use msg::constellation_msg::ReferrerPolicy as MsgReferrerPolicy; +use net_traits::request::{Origin, Window}; use net_traits::request::CacheMode as NetTraitsRequestCache; use net_traits::request::CredentialsMode as NetTraitsRequestCredentials; use net_traits::request::Destination as NetTraitsRequestDestination; @@ -31,7 +32,6 @@ use net_traits::request::Referer as NetTraitsRequestReferer; use net_traits::request::Request as NetTraitsRequest; use net_traits::request::RequestMode as NetTraitsRequestMode; use net_traits::request::Type as NetTraitsRequestType; -use net_traits::request::{Origin, Window}; use std::cell::Cell; use url::Url; diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs new file mode 100644 index 00000000000..acfc181283a --- /dev/null +++ b/components/script/dom/response.rs @@ -0,0 +1,290 @@ +/* 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/. */ + +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::error::{Error, Fallible}; +use dom::bindings::global::GlobalRef; +use dom::bindings::js::{JS, MutNullableHeap, Root}; +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 hyper::status::StatusCode; +use net_traits::response::{ResponseBody as NetTraitsResponseBody}; +use std::str::FromStr; +use url::Position; +use url::Url; + +#[dom_struct] +pub struct Response { + reflector_: Reflector, + headers_reflector: MutNullableHeap<JS<Headers>>, + mime_type: DOMRefCell<Vec<u8>>, + body_used: Cell<bool>, + /// `None` can be considered a StatusCode of `0`. + #[ignore_heap_size_of = "Defined in hyper"] + status: DOMRefCell<Option<StatusCode>>, + raw_status: DOMRefCell<Option<(u16, Vec<u8>)>>, + response_type: DOMRefCell<DOMResponseType>, + url: DOMRefCell<Option<Url>>, + url_list: DOMRefCell<Vec<Url>>, + // For now use the existing NetTraitsResponseBody enum, until body + // is implemented. + body: DOMRefCell<NetTraitsResponseBody>, +} + +impl Response { + pub fn new_inherited() -> Response { + Response { + reflector_: Reflector::new(), + headers_reflector: Default::default(), + mime_type: DOMRefCell::new("".to_string().into_bytes()), + body_used: Cell::new(false), + status: DOMRefCell::new(Some(StatusCode::Ok)), + raw_status: DOMRefCell::new(Some((200, b"OK".to_vec()))), + response_type: DOMRefCell::new(DOMResponseType::Default), + url: DOMRefCell::new(None), + url_list: DOMRefCell::new(vec![]), + body: DOMRefCell::new(NetTraitsResponseBody::Empty), + } + } + + // https://fetch.spec.whatwg.org/#dom-response + pub fn new(global: GlobalRef) -> Root<Response> { + reflect_dom_object(box Response::new_inherited(), global, ResponseBinding::Wrap) + } + + pub fn Constructor(global: GlobalRef, _body: Option<USVString>, init: &ResponseBinding::ResponseInit) + -> Fallible<Root<Response>> { + // Step 1 + if init.status < 200 || init.status > 599 { + return Err(Error::Range( + format!("init's status member should be in the range 200 to 599, inclusive, but is {}" + , init.status))); + } + + // Step 2 + if !is_valid_status_text(&init.statusText) { + return Err(Error::Type("init's statusText member does not match the reason-phrase token production" + .to_string())); + } + + // Step 3 + let r = Response::new(global); + + // Step 4 + *r.status.borrow_mut() = Some(StatusCode::from_u16(init.status)); + + // Step 5 + *r.raw_status.borrow_mut() = Some((init.status, init.statusText.clone().into())); + + // 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 + try!(r.Headers().fill(Some(headers_member.clone()))); + } + + // Step 7 + if let Some(_) = _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. + + // 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)); + } + }; + } + + // Step 8 + *r.mime_type.borrow_mut() = r.Headers().extract_mime_type(); + + // Step 9 + // TODO: `entry settings object` is not implemented in Servo yet. + + // Step 10 + // TODO: Write this step once Promises are merged in + + // Step 11 + Ok(r) + } + + // https://fetch.spec.whatwg.org/#dom-response-error + pub fn Error(global: GlobalRef) -> Root<Response> { + let r = Response::new(global); + *r.response_type.borrow_mut() = DOMResponseType::Error; + r.Headers().set_guard(Guard::Immutable); + *r.raw_status.borrow_mut() = Some((0, b"".to_vec())); + r + } + + // https://fetch.spec.whatwg.org/#dom-response-redirect + pub fn Redirect(global: GlobalRef, url: USVString, status: u16) -> Fallible<Root<Response>> { + // Step 1 + // TODO: `entry settings object` is not implemented in Servo yet. + let base_url = global.get_url(); + let parsed_url = base_url.join(&url.0); + + // Step 2 + let url = match parsed_url { + Ok(url) => url, + Err(_) => return Err(Error::Type("Url could not be parsed".to_string())), + }; + + // Step 3 + if !is_redirect_status(status) { + return Err(Error::Range("status is not a redirect status".to_string())); + } + + // Step 4 + // see Step 4 continued + let r = Response::new(global); + + // Step 5 + *r.status.borrow_mut() = Some(StatusCode::from_u16(status)); + *r.raw_status.borrow_mut() = Some((status, b"".to_vec())); + + // Step 6 + let url_bytestring = ByteString::from_str(url.as_str()).unwrap_or(ByteString::new(b"".to_vec())); + try!(r.Headers().Set(ByteString::new(b"Location".to_vec()), url_bytestring)); + + // Step 4 continued + // Headers Guard is set to Immutable here to prevent error in Step 6 + r.Headers().set_guard(Guard::Immutable); + + // Step 7 + Ok(r) + } +} + +// https://fetch.spec.whatwg.org/#redirect-status +fn is_redirect_status(status: u16) -> bool { + status == 301 || status == 302 || status == 303 || status == 307 || status == 308 +} + +// https://tools.ietf.org/html/rfc7230#section-3.1.2 +fn is_valid_status_text(status_text: &ByteString) -> bool { + // reason-phrase = *( HTAB / SP / VCHAR / obs-text ) + for byte in status_text.iter() { + if !(*byte == b'\t' || *byte == b' ' || is_vchar(*byte) || is_obs_text(*byte)) { + return false; + } + } + true +} + +// https://fetch.spec.whatwg.org/#null-body-status +fn is_null_body_status(status: u16) -> bool { + status == 101 || status == 204 || status == 205 || status == 304 +} + +impl ResponseMethods for Response { + // https://fetch.spec.whatwg.org/#dom-response-type + fn Type(&self) -> DOMResponseType { + *self.response_type.borrow()//into() + } + + // https://fetch.spec.whatwg.org/#dom-response-url + fn Url(&self) -> USVString { + USVString(String::from((*self.url.borrow()).as_ref().map(|u| serialize_without_fragment(u)).unwrap_or(""))) + } + + // https://fetch.spec.whatwg.org/#dom-response-redirected + fn Redirected(&self) -> bool { + let url_list_len = self.url_list.borrow().len(); + url_list_len > 1 + } + + // https://fetch.spec.whatwg.org/#dom-response-status + fn Status(&self) -> u16 { + match *self.raw_status.borrow() { + Some((s, _)) => s, + None => 0, + } + } + + // https://fetch.spec.whatwg.org/#dom-response-ok + fn Ok(&self) -> bool { + match *self.status.borrow() { + Some(s) => { + let status_num = s.to_u16(); + return status_num >= 200 && status_num <= 299; + } + None => false, + } + } + + // https://fetch.spec.whatwg.org/#dom-response-statustext + fn StatusText(&self) -> ByteString { + match *self.raw_status.borrow() { + Some((_, ref st)) => ByteString::new(st.clone()), + None => ByteString::new(b"OK".to_vec()), + } + } + + // https://fetch.spec.whatwg.org/#dom-response-headers + fn Headers(&self) -> Root<Headers> { + self.headers_reflector.or_init(|| Headers::for_response(self.global().r())) + } + + // https://fetch.spec.whatwg.org/#dom-response-clone + fn Clone(&self) -> Fallible<Root<Response>> { + // Step 1 + // TODO: This step relies on body and stream, which are still unimplemented. + + // Step 2 + let new_response = Response::new(self.global().r()); + new_response.Headers().set_guard(self.Headers().get_guard()); + + // https://fetch.spec.whatwg.org/#concept-response-clone + // Instead of storing a net_traits::Response internally, we + // only store the relevant fields, and only clone them here + *new_response.response_type.borrow_mut() = self.response_type.borrow().clone(); + *new_response.status.borrow_mut() = self.status.borrow().clone(); + *new_response.raw_status.borrow_mut() = self.raw_status.borrow().clone(); + *new_response.url.borrow_mut() = self.url.borrow().clone(); + *new_response.url_list.borrow_mut() = self.url_list.borrow().clone(); + + if *self.body.borrow() != NetTraitsResponseBody::Empty { + *new_response.body.borrow_mut() = self.body.borrow().clone(); + } + + // Step 3 + // TODO: This step relies on promises, which are still unimplemented. + + // Step 4 + Ok(new_response) + } + + // https://fetch.spec.whatwg.org/#dom-body-bodyused + fn BodyUsed(&self) -> bool { + self.body_used.get() + } +} + +fn serialize_without_fragment(url: &Url) -> &str { + &url[..Position::AfterQuery] +} diff --git a/components/script/dom/serviceworkercontainer.rs b/components/script/dom/serviceworkercontainer.rs index 4487c064fe1..06080b7731c 100644 --- a/components/script/dom/serviceworkercontainer.rs +++ b/components/script/dom/serviceworkercontainer.rs @@ -2,8 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::bindings::codegen::Bindings::ServiceWorkerContainerBinding::RegistrationOptions; use dom::bindings::codegen::Bindings::ServiceWorkerContainerBinding::{ServiceWorkerContainerMethods, Wrap}; +use dom::bindings::codegen::Bindings::ServiceWorkerContainerBinding::RegistrationOptions; use dom::bindings::error::{Error, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; diff --git a/components/script/dom/servohtmlparser.rs b/components/script/dom/servohtmlparser.rs index d4d2cbc911a..548dad24dae 100644 --- a/components/script/dom/servohtmlparser.rs +++ b/components/script/dom/servohtmlparser.rs @@ -33,9 +33,9 @@ use js::jsapi::JSTracer; use msg::constellation_msg::{PipelineId, SubpageId}; use net_traits::{AsyncResponseListener, Metadata, NetworkError}; use network_listener::PreInvoke; -use parse::{TrustedParser, ParserRef, Parser}; +use parse::{Parser, ParserRef, TrustedParser}; +use profile_traits::time::{TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType, profile}; use profile_traits::time::ProfilerCategory; -use profile_traits::time::{profile, TimerMetadata, TimerMetadataReflowType, TimerMetadataFrameType}; use script_thread::ScriptThread; use std::cell::Cell; use std::default::Default; diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index 21439c0b19a..b9e34ebe0a7 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -12,8 +12,9 @@ use dom::bindings::codegen::Bindings::TestBindingBinding::{TestBindingMethods, T use dom::bindings::codegen::Bindings::TestBindingBinding::{TestDictionaryDefaults, TestEnum}; use dom::bindings::codegen::UnionTypes::{BlobOrBoolean, BlobOrBlobSequence, LongOrLongSequenceSequence}; use dom::bindings::codegen::UnionTypes::{BlobOrString, BlobOrUnsignedLong, EventOrString}; -use dom::bindings::codegen::UnionTypes::{ByteStringOrLong, ByteStringSequenceOrLongOrString, ByteStringSequenceOrLong}; -use dom::bindings::codegen::UnionTypes::{EventOrUSVString, HTMLElementOrLong}; +use dom::bindings::codegen::UnionTypes::{ByteStringOrLong, ByteStringSequenceOrLongOrString}; +use dom::bindings::codegen::UnionTypes::{ByteStringSequenceOrLong, DocumentOrTestTypedef}; +use dom::bindings::codegen::UnionTypes::{EventOrUSVString, HTMLElementOrLong, LongSequenceOrTestTypedef}; use dom::bindings::codegen::UnionTypes::{HTMLElementOrUnsignedLongOrStringOrBoolean, LongSequenceOrBoolean}; use dom::bindings::codegen::UnionTypes::{StringOrLongSequence, StringOrStringSequence, StringSequenceOrUnsignedLong}; use dom::bindings::codegen::UnionTypes::{StringOrUnsignedLong, StringOrBoolean, UnsignedLongOrBoolean}; @@ -421,6 +422,8 @@ impl TestBindingMethods for TestBinding { fn PassUnion6(&self, _: UnsignedLongOrBoolean) {} fn PassUnion7(&self, _: StringSequenceOrUnsignedLong) {} fn PassUnion8(&self, _: ByteStringSequenceOrLong) {} + fn PassUnionWithTypedef(&self, _: DocumentOrTestTypedef) {} + fn PassUnionWithTypedef2(&self, _: LongSequenceOrTestTypedef) {} fn PassAny(&self, _: *mut JSContext, _: HandleValue) {} fn PassObject(&self, _: *mut JSContext, _: *mut JSObject) {} fn PassCallbackFunction(&self, _: Rc<Function>) {} diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs index 8103421a155..c4097fc761a 100644 --- a/components/script/dom/treewalker.rs +++ b/components/script/dom/treewalker.rs @@ -10,8 +10,8 @@ use dom::bindings::codegen::Bindings::TreeWalkerBinding; use dom::bindings::codegen::Bindings::TreeWalkerBinding::TreeWalkerMethods; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; -use dom::bindings::js::Root; use dom::bindings::js::{JS, MutHeap}; +use dom::bindings::js::Root; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::document::Document; use dom::node::Node; diff --git a/components/script/dom/uievent.rs b/components/script/dom/uievent.rs index 16461315ca1..a0f35868662 100644 --- a/components/script/dom/uievent.rs +++ b/components/script/dom/uievent.rs @@ -8,8 +8,8 @@ use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; -use dom::bindings::js::Root; use dom::bindings::js::{JS, MutNullableHeap, RootedReference}; +use dom::bindings::js::Root; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; use dom::event::{Event, EventBubbles, EventCancelable}; diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs index e42b3b7f1cd..bc686d23cc4 100644 --- a/components/script/dom/url.rs +++ b/components/script/dom/url.rs @@ -14,13 +14,13 @@ use dom::blob::Blob; use dom::urlhelper::UrlHelper; use dom::urlsearchparams::URLSearchParams; use ipc_channel::ipc; +use net_traits::{CoreResourceMsg, IpcSend}; use net_traits::blob_url_store::{get_blob_origin, parse_blob_url}; use net_traits::filemanager_thread::FileManagerThreadMsg; -use net_traits::{IpcSend, CoreResourceMsg}; use std::borrow::ToOwned; use std::default::Default; -use url::quirks::domain_to_unicode; use url::{Host, Url}; +use url::quirks::domain_to_unicode; use uuid::Uuid; // https://url.spec.whatwg.org/#url diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index aadf03d4211..3fc63349634 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -4,12 +4,12 @@ use canvas_traits::{CanvasCommonMsg, CanvasMsg, byte_swap}; use core::nonzero::NonZero; +use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes}; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods; -use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes}; use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement; use dom::bindings::conversions::{ToJSValConvertible, array_buffer_view_data, array_buffer_view_data_checked}; -use dom::bindings::conversions::{array_buffer_view_to_vec_checked, array_buffer_view_to_vec}; +use dom::bindings::conversions::{array_buffer_view_to_vec, array_buffer_view_to_vec_checked}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root}; @@ -22,7 +22,7 @@ use dom::node::{Node, NodeDamage, window_from_node}; use dom::webgl_validations::WebGLValidator; use dom::webgl_validations::tex_image_2d::{CommonTexImage2DValidator, CommonTexImage2DValidatorResult}; use dom::webgl_validations::tex_image_2d::{TexImage2DValidator, TexImage2DValidatorResult}; -use dom::webgl_validations::types::{TexFormat, TexImageTarget, TexDataType}; +use dom::webgl_validations::types::{TexDataType, TexFormat, TexImageTarget}; use dom::webglactiveinfo::WebGLActiveInfo; use dom::webglbuffer::WebGLBuffer; use dom::webglcontextevent::WebGLContextEvent; @@ -34,15 +34,15 @@ use dom::webgltexture::{TexParameterValue, WebGLTexture}; use dom::webgluniformlocation::WebGLUniformLocation; use euclid::size::Size2D; use ipc_channel::ipc::{self, IpcSender}; -use js::jsapi::{JSContext, JS_GetArrayBufferViewType, JSObject, Type}; +use js::jsapi::{JSContext, JSObject, JS_GetArrayBufferViewType, Type}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue}; use net_traits::image::base::PixelFormat; use net_traits::image_cache_thread::ImageResponse; use offscreen_gl_context::{GLContextAttributes, GLLimits}; use script_traits::ScriptMsg as ConstellationMsg; use std::cell::Cell; -use webrender_traits::WebGLError::*; use webrender_traits::{WebGLCommand, WebGLError, WebGLFramebufferBindingRequest, WebGLParameter}; +use webrender_traits::WebGLError::*; type ImagePixelResult = Result<(Vec<u8>, Size2D<i32>), ()>; pub const MAX_UNIFORM_AND_ATTRIBUTE_LEN: usize = 256; diff --git a/components/script/dom/webidls/Console.webidl b/components/script/dom/webidls/Console.webidl index 09273db78b8..90f9bb9f58e 100644 --- a/components/script/dom/webidls/Console.webidl +++ b/components/script/dom/webidls/Console.webidl @@ -9,8 +9,10 @@ * © Copyright 2014 Mozilla Foundation. */ -[Exposed=(Window,Worker)] -interface Console { +[ClassString="Console", + Exposed=(Window,Worker), + ProtoObjectHack] +namespace console { // These should be DOMString message, DOMString message2, ... void log(DOMString... messages); void debug(DOMString... messages); diff --git a/components/script/dom/webidls/Response.webidl b/components/script/dom/webidls/Response.webidl new file mode 100644 index 00000000000..2052f5c6371 --- /dev/null +++ b/components/script/dom/webidls/Response.webidl @@ -0,0 +1,37 @@ +/* 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/#response-class + +// TODO: pass 'optional ResponseBodyInit? body = null' to constructor in place of USVString + [Constructor(optional USVString? body = null, optional ResponseInit init), + Exposed=(Window,Worker)] +interface Response { + [NewObject] static Response error(); + [NewObject, Throws] static Response redirect(USVString url, optional unsigned short status = 302); + + readonly attribute ResponseType type; + + readonly attribute USVString url; + readonly attribute boolean redirected; + readonly attribute unsigned short status; + readonly attribute boolean ok; + readonly attribute ByteString statusText; + [SameObject] readonly attribute Headers headers; + // readonly attribute ReadableStream? body; + // [SameObject] readonly attribute Promise<Headers> trailer; + + [NewObject, Throws] Response clone(); +}; +Response implements Body; + +dictionary ResponseInit { + unsigned short status = 200; + ByteString statusText = "OK"; + HeadersInit headers; +}; + +enum ResponseType { "basic", "cors", "default", "error", "opaque", "opaqueredirect" }; + +// typedef (BodyInit or ReadableStream) ResponseBodyInit; diff --git a/components/script/dom/webidls/TestBinding.webidl b/components/script/dom/webidls/TestBinding.webidl index 392aee5963b..d98b9428031 100644 --- a/components/script/dom/webidls/TestBinding.webidl +++ b/components/script/dom/webidls/TestBinding.webidl @@ -6,6 +6,7 @@ // web pages. enum TestEnum { "", "foo", "bar" }; +typedef (DOMString or URL or Blob) TestTypedef; dictionary TestDictionary { required boolean requiredValue; @@ -241,6 +242,8 @@ interface TestBinding { void passUnion6((unsigned long or boolean) bool); void passUnion7((sequence<DOMString> or unsigned long) arg); void passUnion8((sequence<ByteString> or long) arg); + void passUnionWithTypedef((Document or TestTypedef) arg); + void passUnionWithTypedef2((sequence<long> or TestTypedef) arg); void passAny(any arg); void passObject(object arg); void passCallbackFunction(Function fun); diff --git a/components/script/dom/webidls/Window.webidl b/components/script/dom/webidls/Window.webidl index dcf79a61c7e..dbe73ca4831 100644 --- a/components/script/dom/webidls/Window.webidl +++ b/components/script/dom/webidls/Window.webidl @@ -161,7 +161,6 @@ partial interface Window { // Proprietary extensions. partial interface Window { - readonly attribute Console console; void debug(DOMString arg); void gc(); void trap(); diff --git a/components/script/dom/webidls/WorkerGlobalScope.webidl b/components/script/dom/webidls/WorkerGlobalScope.webidl index ec65bcb09a6..186e5cd7fee 100644 --- a/components/script/dom/webidls/WorkerGlobalScope.webidl +++ b/components/script/dom/webidls/WorkerGlobalScope.webidl @@ -9,7 +9,7 @@ interface WorkerGlobalScope : EventTarget { readonly attribute WorkerLocation location; //void close(); - // attribute OnErrorEventHandler onerror; + attribute OnErrorEventHandler onerror; // attribute EventHandler onlanguagechange; // attribute EventHandler onoffline; // attribute EventHandler ononline; @@ -24,10 +24,3 @@ partial interface WorkerGlobalScope { // not obsolete }; WorkerGlobalScope implements WindowTimers; WorkerGlobalScope implements WindowBase64; - -// Proprietary -[Exposed=Worker] -partial interface WorkerGlobalScope { - [Replaceable] - readonly attribute Console console; -}; diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 3b3652040e9..df9c2e5ed34 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::WebSocketBinding; use dom::bindings::codegen::Bindings::WebSocketBinding::{BinaryType, WebSocketMethods}; use dom::bindings::codegen::UnionTypes::StringOrStringSequence; use dom::bindings::conversions::ToJSValConvertible; -use dom::bindings::error::{Error, Fallible, ErrorResult}; +use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; @@ -23,18 +23,18 @@ use dom::eventtarget::EventTarget; use dom::messageevent::MessageEvent; use dom::urlhelper::UrlHelper; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; -use js::jsapi::JSAutoCompartment; use js::jsapi::{JS_GetArrayBufferData, JS_NewArrayBuffer}; +use js::jsapi::JSAutoCompartment; use js::jsval::UndefinedValue; use libc::{uint32_t, uint8_t}; +use net_traits::{WebSocketCommunicate, WebSocketConnectData, WebSocketDomAction, WebSocketNetworkEvent}; use net_traits::CookieSource::HTTP; -use net_traits::CoreResourceMsg::{WebsocketConnect, SetCookiesForUrl}; +use net_traits::CoreResourceMsg::{SetCookiesForUrl, WebsocketConnect}; use net_traits::MessageData; use net_traits::hosts::replace_hosts; use net_traits::unwrap_websocket_protocol; -use net_traits::{WebSocketCommunicate, WebSocketConnectData, WebSocketDomAction, WebSocketNetworkEvent}; -use script_runtime::ScriptThreadEventCategory::WebSocketEvent; use script_runtime::{CommonScriptMsg, ScriptChan}; +use script_runtime::ScriptThreadEventCategory::WebSocketEvent; use script_thread::Runnable; use std::ascii::AsciiExt; use std::borrow::ToOwned; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index d1529b44b19..e8006123360 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -12,9 +12,9 @@ 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::WindowBinding::{ScrollBehavior, ScrollToOptions}; use dom::bindings::codegen::Bindings::WindowBinding::{self, FrameRequestCallback, WindowMethods}; -use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception, ErrorInfo}; +use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions}; +use dom::bindings::error::{Error, ErrorInfo, ErrorResult, Fallible, report_pending_exception}; use dom::bindings::global::{GlobalRef, global_root_from_object}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableHeap, Root}; @@ -25,7 +25,7 @@ use dom::bindings::str::DOMString; use dom::bindings::structuredclone::StructuredCloneData; use dom::bindings::utils::{GlobalStaticData, WindowProxyHandler}; use dom::browsingcontext::BrowsingContext; -use dom::console::Console; +use dom::console::TimerSet; use dom::crypto::Crypto; use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration}; use dom::document::Document; @@ -46,7 +46,7 @@ use euclid::{Point2D, Rect, Size2D}; use gfx_traits::LayerId; use ipc_channel::ipc::{self, IpcSender}; use js::jsapi::{Evaluate2, HandleObject, HandleValue, JSAutoCompartment, JSContext}; -use js::jsapi::{JS_GetRuntime, JS_GC, MutableHandleValue, SetWindowProxy}; +use js::jsapi::{JS_GC, JS_GetRuntime, MutableHandleValue, SetWindowProxy}; use js::jsval::UndefinedValue; use js::rust::CompileOptionsWrapper; use js::rust::Runtime; @@ -68,13 +68,13 @@ use script_layout_interface::message::{Msg, Reflow, ReflowQueryType, ScriptReflo use script_layout_interface::reporter::CSSErrorReporter; use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse, LayoutRPC}; use script_layout_interface::rpc::{MarginStyleResponse, ResolvedStyleResponse}; -use script_runtime::{ScriptChan, ScriptPort, CommonScriptMsg, ScriptThreadEventCategory, maybe_take_panic_result}; +use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThreadEventCategory, maybe_take_panic_result}; +use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, RunnableWrapper}; use script_thread::SendableMainThreadScriptChan; -use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, RunnableWrapper, Runnable}; -use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; use script_traits::{ConstellationControlMsg, MozBrowserEvent, UntrustedNodeAddress}; use script_traits::{DocumentState, MsDuration, TimerEvent, TimerEventId}; use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, TimerSource, WindowSizeData}; +use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; @@ -84,10 +84,10 @@ 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}; -use std::sync::mpsc::TryRecvError::{Disconnected, Empty}; use std::sync::mpsc::{Sender, channel}; -use std::sync::{Arc, Mutex}; +use std::sync::mpsc::TryRecvError::{Disconnected, Empty}; use string_cache::Atom; use style::context::ReflowGoal; use style::error_reporting::ParseErrorReporter; @@ -157,7 +157,6 @@ pub struct Window { history_traversal_task_source: HistoryTraversalTaskSource, #[ignore_heap_size_of = "task sources are hard"] file_reading_task_source: FileReadingTaskSource, - console: MutNullableHeap<JS<Console>>, crypto: MutNullableHeap<JS<Crypto>>, navigator: MutNullableHeap<JS<Navigator>>, #[ignore_heap_size_of = "channels are hard"] @@ -276,7 +275,10 @@ pub struct Window { scroll_offsets: DOMRefCell<HashMap<UntrustedNodeAddress, Point2D<f32>>>, /// https://html.spec.whatwg.org/multipage/#in-error-reporting-mode - in_error_reporting_mode: Cell<bool> + in_error_reporting_mode: Cell<bool>, + + /// Timers used by the Console API. + console_timers: TimerSet, } impl Window { @@ -508,11 +510,6 @@ impl WindowMethods for Window { self.local_storage.or_init(|| Storage::new(&GlobalRef::Window(self), StorageType::Local)) } - // https://developer.mozilla.org/en-US/docs/Web/API/Console - fn Console(&self) -> Root<Console> { - self.console.or_init(|| Console::new(GlobalRef::Window(self))) - } - // https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#dfn-GlobalCrypto fn Crypto(&self) -> Root<Crypto> { self.crypto.or_init(|| Crypto::new(GlobalRef::Window(self))) @@ -1701,7 +1698,6 @@ impl Window { history_traversal_task_source: history_task_source, file_reading_task_source: file_task_source, image_cache_chan: image_cache_chan, - console: Default::default(), crypto: Default::default(), navigator: Default::default(), image_cache_thread: image_cache_thread, @@ -1747,10 +1743,16 @@ impl Window { error_reporter: error_reporter, scroll_offsets: DOMRefCell::new(HashMap::new()), in_error_reporting_mode: Cell::new(false), + console_timers: TimerSet::new(), }; WindowBinding::Wrap(runtime.cx(), win) } + + pub fn console_timers(&self) -> &TimerSet { + &self.console_timers + } + pub fn live_devtools_updates(&self) -> bool { return self.devtools_wants_updates.get(); } @@ -1766,6 +1768,7 @@ impl Window { self.in_error_reporting_mode.set(true); // Steps 3-12. + // FIXME(#13195): muted errors. let event = ErrorEvent::new(GlobalRef::Window(self), atom!("error"), EventBubbles::DoesNotBubble, diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index f171d1ee515..e40ebee24f0 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -2,13 +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 devtools_traits::{ScriptToDevtoolsControlMsg, DevtoolsPageInfo}; +use devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg}; +use dom::abstractworker::{SharedRt, SimpleWorkerErrorHandler}; use dom::abstractworker::WorkerScriptMsg; -use dom::abstractworker::{SimpleWorkerErrorHandler, SharedRt}; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::Bindings::WorkerBinding; use dom::bindings::codegen::Bindings::WorkerBinding::WorkerMethods; -use dom::bindings::error::{Error, ErrorResult, Fallible}; +use dom::bindings::error::{Error, ErrorResult, Fallible, ErrorInfo}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; @@ -17,18 +17,20 @@ use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::bindings::structuredclone::StructuredCloneData; use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope; +use dom::errorevent::ErrorEvent; +use dom::event::{Event, EventBubbles, EventCancelable}; use dom::eventtarget::EventTarget; use dom::messageevent::MessageEvent; use dom::workerglobalscope::prepare_workerscope_init; use ipc_channel::ipc; -use js::jsapi::{HandleValue, JSContext, JSAutoCompartment}; +use js::jsapi::{HandleValue, JSAutoCompartment, JSContext, NullHandleValue}; use js::jsval::UndefinedValue; use script_thread::Runnable; use script_traits::WorkerScriptLoadOrigin; use std::cell::Cell; +use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::{Sender, channel}; -use std::sync::{Arc, Mutex}; pub type TrustedWorkerAddress = Trusted<Worker>; @@ -137,6 +139,26 @@ impl Worker { let worker = address.root(); worker.upcast().fire_simple_event("error"); } + + fn dispatch_error(&self, error_info: ErrorInfo) { + let global = self.global(); + let event = ErrorEvent::new(global.r(), + atom!("error"), + EventBubbles::DoesNotBubble, + EventCancelable::Cancelable, + error_info.message.as_str().into(), + error_info.filename.as_str().into(), + error_info.lineno, + error_info.column, + NullHandleValue); + + let handled = !event.upcast::<Event>().fire(self.upcast::<EventTarget>()); + if handled { + return; + } + + global.r().report_an_error(error_info, NullHandleValue); + } } impl WorkerMethods for Worker { @@ -202,3 +224,24 @@ impl Runnable for SimpleWorkerErrorHandler<Worker> { Worker::dispatch_simple_error(this.addr); } } + +pub struct WorkerErrorHandler { + address: Trusted<Worker>, + error_info: ErrorInfo, +} + +impl WorkerErrorHandler { + pub fn new(address: Trusted<Worker>, error_info: ErrorInfo) -> WorkerErrorHandler { + WorkerErrorHandler { + address: address, + error_info: error_info, + } + } +} + +impl Runnable for WorkerErrorHandler { + fn handler(self: Box<Self>) { + let this = *self; + this.address.root().dispatch_error(this.error_info); + } +} diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 9f61753ca64..1c2c46fb52d 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -3,15 +3,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 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::WorkerGlobalScopeBinding::WorkerGlobalScopeMethods; -use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception}; +use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception, ErrorInfo}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::reflector::Reflectable; use dom::bindings::str::DOMString; -use dom::console::Console; +use dom::console::TimerSet; use dom::crypto::Crypto; use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope; use dom::eventtarget::EventTarget; @@ -24,14 +25,14 @@ use js::jsapi::{HandleValue, JSAutoCompartment, JSContext, JSRuntime}; use js::jsval::UndefinedValue; use js::rust::Runtime; use msg::constellation_msg::{PipelineId, ReferrerPolicy}; +use net_traits::{IpcSend, LoadOrigin}; use net_traits::{LoadContext, ResourceThreads, load_whole_resource}; -use net_traits::{LoadOrigin, IpcSend}; use profile_traits::{mem, time}; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, maybe_take_panic_result}; use script_thread::RunnableWrapper; +use script_traits::{MsDuration, TimerEvent, TimerEventId, TimerEventRequest, TimerSource}; use script_traits::ScriptMsg as ConstellationMsg; use script_traits::WorkerGlobalScopeInit; -use script_traits::{MsDuration, TimerEvent, TimerEventId, TimerEventRequest, TimerSource}; use std::cell::Cell; use std::default::Default; use std::panic; @@ -79,7 +80,6 @@ pub struct WorkerGlobalScope { resource_threads: ResourceThreads, location: MutNullableHeap<JS<WorkerLocation>>, navigator: MutNullableHeap<JS<WorkerNavigator>>, - console: MutNullableHeap<JS<Console>>, crypto: MutNullableHeap<JS<Crypto>>, timers: OneshotTimers, @@ -109,6 +109,9 @@ pub struct WorkerGlobalScope { #[ignore_heap_size_of = "Defined in std"] scheduler_chan: IpcSender<TimerEventRequest>, + + /// Timers used by the Console API. + console_timers: TimerSet, } impl WorkerGlobalScope { @@ -129,7 +132,6 @@ impl WorkerGlobalScope { resource_threads: init.resource_threads, location: Default::default(), navigator: Default::default(), - console: Default::default(), crypto: Default::default(), timers: OneshotTimers::new(timer_event_chan, init.scheduler_chan.clone()), mem_profiler_chan: init.mem_profiler_chan, @@ -140,9 +142,14 @@ impl WorkerGlobalScope { devtools_wants_updates: Cell::new(false), constellation_chan: init.constellation_chan, scheduler_chan: init.scheduler_chan, + console_timers: TimerSet::new(), } } + pub fn console_timers(&self) -> &TimerSet { + &self.console_timers + } + pub fn mem_profiler_chan(&self) -> &mem::ProfilerChan { &self.mem_profiler_chan } @@ -248,6 +255,9 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { }) } + // https://html.spec.whatwg.org/multipage/#handler-workerglobalscope-onerror + error_event_handler!(error, GetOnerror, SetOnerror); + // https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-importscripts fn ImportScripts(&self, url_strings: Vec<DOMString>) -> ErrorResult { let mut urls = Vec::with_capacity(url_strings.len()); @@ -295,11 +305,6 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { self.navigator.or_init(|| WorkerNavigator::new(self)) } - // https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/console - fn Console(&self) -> Root<Console> { - self.console.or_init(|| Console::new(GlobalRef::Worker(self))) - } - // https://html.spec.whatwg.org/multipage/#dfn-Crypto fn Crypto(&self) -> Root<Crypto> { self.crypto.or_init(|| Crypto::new(GlobalRef::Worker(self))) @@ -451,4 +456,11 @@ impl WorkerGlobalScope { closing.store(true, Ordering::SeqCst); } } + + /// 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); + } } diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 382e4c69faa..a97dc7f802b 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -21,8 +21,8 @@ use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::{ByteString, DOMString, USVString, is_token}; use dom::blob::{Blob, BlobImpl}; -use dom::document::DocumentSource; use dom::document::{Document, IsHTMLDocument}; +use dom::document::DocumentSource; use dom::event::{Event, EventBubbles, EventCancelable}; use dom::eventtarget::EventTarget; use dom::headers::is_forbidden_header_name; @@ -34,23 +34,22 @@ use encoding::all::UTF_8; use encoding::label::encoding_from_whatwg_label; use encoding::types::{DecoderTrap, EncoderTrap, Encoding, EncodingRef}; use euclid::length::Length; -use hyper::header::Headers; use hyper::header::{ContentLength, ContentType}; -use hyper::http::RawStatus; +use hyper::header::Headers; use hyper::method::Method; -use hyper::mime::{self, Mime, Attr as MimeAttr, Value as MimeValue}; +use hyper::mime::{self, Attr as MimeAttr, Mime, Value as MimeValue}; use hyper_serde::Serde; use ipc_channel::ipc; use ipc_channel::router::ROUTER; -use js::jsapi::JS_ClearPendingException; use js::jsapi::{JSContext, JS_ParseJSON}; +use js::jsapi::JS_ClearPendingException; use js::jsval::{JSVal, NullValue, UndefinedValue}; use msg::constellation_msg::{PipelineId, ReferrerPolicy}; +use net_traits::{CoreResourceThread, LoadOrigin}; +use net_traits::{FetchResponseListener, Metadata, NetworkError}; use net_traits::CoreResourceMsg::Fetch; use net_traits::request::{CredentialsMode, Destination, RequestInit, RequestMode}; use net_traits::trim_http_whitespace; -use net_traits::{CoreResourceThread, LoadOrigin}; -use net_traits::{FetchResponseListener, Metadata, NetworkError}; use network_listener::{NetworkListener, PreInvoke}; use parse::html::{ParseContext, parse_html}; use parse::xml::{self, parse_xml}; @@ -64,7 +63,7 @@ use std::sync::{Arc, Mutex}; use string_cache::Atom; use time; use timers::{OneshotTimerCallback, OneshotTimerHandle}; -use url::{Url, Position}; +use url::{Position, Url}; use util::prefs::PREFS; #[derive(JSTraceable, PartialEq, Copy, Clone, HeapSizeOf)] @@ -91,7 +90,7 @@ struct XHRContext { #[derive(Clone)] pub enum XHRProgress { /// Notify that headers have been received - HeadersReceived(GenerationId, Option<Headers>, Option<RawStatus>), + HeadersReceived(GenerationId, Option<Headers>, Option<(u16, Vec<u8>)>), /// Partial progress (after receiving headers), containing portion of the response Loading(GenerationId, ByteString), /// Loading is done @@ -879,7 +878,7 @@ impl XMLHttpRequest { self.process_partial_response(XHRProgress::HeadersReceived( gen_id, metadata.headers.map(Serde::into_inner), - metadata.status.map(Serde::into_inner))); + metadata.status)); Ok(()) } @@ -943,9 +942,9 @@ impl XMLHttpRequest { // Part of step 13, send() (processing response) // XXXManishearth handle errors, if any (substep 1) // Substep 2 - status.map(|RawStatus(code, reason)| { + status.map(|(code, reason)| { self.status.set(code); - *self.status_text.borrow_mut() = ByteString::new(reason.into_owned().into_bytes()); + *self.status_text.borrow_mut() = ByteString::new(reason); }); headers.as_ref().map(|h| *self.response_headers.borrow_mut() = h.clone()); @@ -1236,8 +1235,8 @@ impl XMLHttpRequest { fn filter_response_headers(&self) -> Headers { // https://fetch.spec.whatwg.org/#concept-response-header-list use hyper::error::Result; - use hyper::header::SetCookie; use hyper::header::{Header, HeaderFormat}; + use hyper::header::SetCookie; use std::fmt; // a dummy header so we can use headers.remove::<SetCookie2>() |