diff options
Diffstat (limited to 'components/script/dom')
27 files changed, 274 insertions, 225 deletions
diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs index e5168e57768..c9424adf5b2 100644 --- a/components/script/dom/bindings/callback.rs +++ b/components/script/dom/bindings/callback.rs @@ -164,7 +164,7 @@ impl CallSetup { /// Performs the setup needed to make a call. #[allow(unrooted_must_root)] pub fn new<T: CallbackContainer>(callback: &T, handling: ExceptionHandling) -> CallSetup { - let global = global_root_from_object(callback.callback()); + let global = unsafe { global_root_from_object(callback.callback()) }; let cx = global.r().get_cx(); let exception_compartment = unsafe { diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index b44cf2c1c2b..73d9f7f3ed0 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -5,6 +5,7 @@ # Common codegen classes. from collections import defaultdict +from itertools import groupby import operator import re @@ -1322,31 +1323,23 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): returnType) -class MemberCondition: +def MemberCondition(pref, func): """ - An object representing the condition for a member to actually be - exposed. Any of the arguments can be None. If not - None, they should have the following types: + A string representing the condition for a member to actually be exposed. + Any of the arguments can be None. If not None, they should have the + following types: pref: The name of the preference. func: The name of the function. """ - def __init__(self, pref=None, func=None): - assert pref is None or isinstance(pref, str) - assert func is None or isinstance(func, str) - self.pref = pref - - def toFuncPtr(val): - if val is None: - return "None" - return "Some(%s)" % val - self.func = toFuncPtr(func) - - def __eq__(self, other): - return (self.pref == other.pref and self.func == other.func) - - def __ne__(self, other): - return not self.__eq__(other) + assert pref is None or isinstance(pref, str) + assert func is None or isinstance(func, str) + assert func is None or pref is None + if pref: + return 'Condition::Pref("%s")' % pref + if func: + return 'Condition::Func(%s)' % func + return "Condition::Satisfied" class PropertyDefiner: @@ -1390,8 +1383,8 @@ class PropertyDefiner: PropertyDefiner.getStringAttr(interfaceMember, "Func")) - def generatePrefableArray(self, array, name, specTemplate, specTerminator, - specType, getCondition, getDataTuple): + def generateGuardedArray(self, array, name, specTemplate, specTerminator, + specType, getCondition, getDataTuple): """ This method generates our various arrays. @@ -1417,43 +1410,23 @@ class PropertyDefiner: # members while still allowing us to define all the members in the smallest # number of JSAPI calls. assert len(array) != 0 - # So we won't put a specTerminator at the very front of the list: - lastCondition = getCondition(array[0], self.descriptor) specs = [] - currentSpecs = [] prefableSpecs = [] + prefableTemplate = ' Guard::new(%s, %s[%d])' - prefableTemplate = ' Prefable { pref: %s, specs: %s[%d], terminator: %s }' - - def switchToCondition(props, condition): - prefableSpecs.append(prefableTemplate % - ('Some("%s")' % condition.pref if condition.pref else 'None', - name + "_specs", - len(specs), - 'true' if specTerminator else 'false')) + for cond, members in groupby(array, lambda m: getCondition(m, self.descriptor)): + currentSpecs = [specTemplate % getDataTuple(m) for m in members] + if specTerminator: + currentSpecs.append(specTerminator) specs.append("&[\n" + ",\n".join(currentSpecs) + "]\n") - del currentSpecs[:] - - for member in array: - curCondition = getCondition(member, self.descriptor) - if lastCondition != curCondition: - # Terminate previous list - if specTerminator: - currentSpecs.append(specTerminator) - # And switch to our new pref - switchToCondition(self, lastCondition) - lastCondition = curCondition - # And the actual spec - currentSpecs.append(specTemplate % getDataTuple(member)) - if specTerminator: - currentSpecs.append(specTerminator) - switchToCondition(self, lastCondition) + prefableSpecs.append( + prefableTemplate % (cond, name + "_specs", len(specs) - 1)) specsArray = ("const %s_specs: &'static [&'static[%s]] = &[\n" + ",\n".join(specs) + "\n" + "];\n") % (name, specType) - prefArray = ("const %s: &'static [Prefable<%s>] = &[\n" + + prefArray = ("const %s: &'static [Guard<&'static [%s]>] = &[\n" + ",\n".join(prefableSpecs) + "\n" + "];\n") % (name, specType) return specsArray + prefArray @@ -1500,7 +1473,7 @@ class MethodDefiner(PropertyDefiner): "methodInfo": False, "selfHostedName": "ArrayValues", "length": 0, - "condition": MemberCondition()}) + "condition": "Condition::Satisfied"}) isUnforgeableInterface = bool(descriptor.interface.getExtendedAttribute("Unforgeable")) if not static and unforgeable == isUnforgeableInterface: @@ -1551,7 +1524,7 @@ class MethodDefiner(PropertyDefiner): % m["name"][2:], accessor, jitinfo, m["length"], flags, selfHostedName) return (str_to_const_array(m["name"]), accessor, jitinfo, m["length"], flags, selfHostedName) - return self.generatePrefableArray( + return self.generateGuardedArray( array, name, ' JSFunctionSpec {\n' ' name: %s as *const u8 as *const libc::c_char,\n' @@ -1631,7 +1604,7 @@ class AttrDefiner(PropertyDefiner): return (str_to_const_array(attr.identifier.name), flags, getter(attr), setter(attr)) - return self.generatePrefableArray( + return self.generateGuardedArray( array, name, ' JSPropertySpec {\n' ' name: %s as *const u8 as *const libc::c_char,\n' @@ -1666,7 +1639,7 @@ class ConstDefiner(PropertyDefiner): return (str_to_const_array(const.identifier.name), convertConstIDLValueToJSVal(const.value)) - return self.generatePrefableArray( + return self.generateGuardedArray( array, name, ' ConstantSpec { name: %s, value: %s }', None, @@ -2327,8 +2300,8 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties): """ unforgeables = [] - defineUnforgeableAttrs = "define_prefable_properties(cx, unforgeable_holder.handle(), %s);" - defineUnforgeableMethods = "define_prefable_methods(cx, unforgeable_holder.handle(), %s);" + defineUnforgeableAttrs = "define_guarded_properties(cx, unforgeable_holder.handle(), %s);" + defineUnforgeableMethods = "define_guarded_methods(cx, unforgeable_holder.handle(), %s);" unforgeableMembers = [ (defineUnforgeableAttrs, properties.unforgeable_attrs), @@ -2560,15 +2533,10 @@ assert!(!prototype_proto.ptr.is_null());""" % getPrototypeProto)] properties = {"id": name} for arrayName in self.properties.arrayNames(): array = getattr(self.properties, arrayName) - if arrayName == "consts": - if array.length(): - properties[arrayName] = array.variableName() - else: - properties[arrayName] = "&[]" - elif array.length(): - properties[arrayName] = "Some(%s)" % array.variableName() + if array.length(): + properties[arrayName] = array.variableName() else: - properties[arrayName] = "None" + properties[arrayName] = "&[]" code.append(CGGeneric(""" let mut prototype = RootedObject::new(cx, ptr::null_mut()); @@ -5563,13 +5531,13 @@ class CGBindingRoot(CGThing): 'dom::bindings::interface::{InterfaceConstructorBehavior, NonCallbackInterfaceObjectClass}', 'dom::bindings::interface::{create_callback_interface_object, create_interface_prototype_object}', 'dom::bindings::interface::{create_named_constructors, create_noncallback_interface_object}', - 'dom::bindings::interface::{define_prefable_methods, define_prefable_properties}', + 'dom::bindings::interface::{define_guarded_methods, define_guarded_properties}', 'dom::bindings::interface::{ConstantSpec, NonNullJSNative}', 'dom::bindings::interface::ConstantVal::{IntVal, UintVal}', 'dom::bindings::js::{JS, Root, RootedReference}', 'dom::bindings::js::{OptionalRootedReference}', 'dom::bindings::reflector::{Reflectable}', - 'dom::bindings::utils::{DOMClass, DOMJSClass, Prefable}', + 'dom::bindings::utils::{DOMClass, DOMJSClass}', 'dom::bindings::utils::{DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, JSCLASS_DOM_GLOBAL}', 'dom::bindings::utils::{ProtoOrIfaceArray, create_dom_global}', 'dom::bindings::utils::{enumerate_global, finalize_global, find_enum_string_index}', @@ -5593,6 +5561,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::error::{Fallible, Error, ErrorResult}', 'dom::bindings::error::Error::JSFailed', 'dom::bindings::error::throw_dom_exception', + 'dom::bindings::guard::{Condition, Guard}', 'dom::bindings::proxyhandler', 'dom::bindings::proxyhandler::{ensure_expando_object, fill_property_descriptor}', 'dom::bindings::proxyhandler::{get_expando_object, get_property_descriptor}', diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index ff36817b660..036c53e67b4 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -302,44 +302,39 @@ impl GlobalRoot { /// Returns the global object of the realm that the given DOM object's reflector was created in. pub fn global_root_from_reflector<T: Reflectable>(reflector: &T) -> GlobalRoot { - global_root_from_object(*reflector.reflector().get_jsobject()) + unsafe { global_root_from_object(*reflector.reflector().get_jsobject()) } } /// Returns the Rust global object from a JS global object. #[allow(unrooted_must_root)] -pub fn global_root_from_global(global: *mut JSObject) -> GlobalRoot { - unsafe { - let clasp = JS_GetClass(global); - assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0); - match root_from_object(global) { - Ok(window) => return GlobalRoot::Window(window), - Err(_) => (), - } - - match root_from_object(global) { - Ok(worker) => return GlobalRoot::Worker(worker), - Err(_) => (), - } +unsafe fn global_root_from_global(global: *mut JSObject) -> GlobalRoot { + assert!(!global.is_null()); + let clasp = JS_GetClass(global); + assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0); + match root_from_object(global) { + Ok(window) => return GlobalRoot::Window(window), + Err(_) => (), + } - panic!("found DOM global that doesn't unwrap to Window or WorkerGlobalScope") + match root_from_object(global) { + Ok(worker) => return GlobalRoot::Worker(worker), + Err(_) => (), } + + panic!("found DOM global that doesn't unwrap to Window or WorkerGlobalScope") } /// Returns the global object of the realm that the given JS object was created in. #[allow(unrooted_must_root)] -pub fn global_root_from_object(obj: *mut JSObject) -> GlobalRoot { - unsafe { - let global = GetGlobalForObjectCrossCompartment(obj); - global_root_from_global(global) - } +pub unsafe fn global_root_from_object(obj: *mut JSObject) -> GlobalRoot { + assert!(!obj.is_null()); + let global = GetGlobalForObjectCrossCompartment(obj); + global_root_from_global(global) } /// Returns the global object for the given JSContext #[allow(unrooted_must_root)] -pub fn global_root_from_context(cx: *mut JSContext) -> GlobalRoot { - unsafe { - let global = CurrentGlobalOrNull(cx); - assert!(!global.is_null()); - global_root_from_global(global) - } +pub unsafe fn global_root_from_context(cx: *mut JSContext) -> GlobalRoot { + let global = CurrentGlobalOrNull(cx); + global_root_from_global(global) } diff --git a/components/script/dom/bindings/guard.rs b/components/script/dom/bindings/guard.rs new file mode 100644 index 00000000000..40faebbd4f2 --- /dev/null +++ b/components/script/dom/bindings/guard.rs @@ -0,0 +1,55 @@ +/* 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 conditionally expose things. + +use js::jsapi::{HandleObject, JSContext}; +use util::prefs::get_pref; + +/// A container with a condition. +pub struct Guard<T: Clone + Copy> { + condition: Condition, + value: T, +} + +impl<T: Clone + Copy> Guard<T> { + /// Construct a new guarded value. + pub const fn new(condition: Condition, value: T) -> Self { + Guard { + condition: condition, + value: value, + } + } + + /// Expose the value if the condition is satisfied. + /// + /// The passed handle is the object on which the value may be exposed. + pub unsafe fn expose(&self, cx: *mut JSContext, obj: HandleObject) -> Option<T> { + if self.condition.is_satisfied(cx, obj) { + Some(self.value) + } else { + None + } + } +} + +/// A condition to expose things. +pub enum Condition { + /// The condition is satisfied if the function returns true. + Func(unsafe fn(*mut JSContext, HandleObject) -> bool), + /// The condition is satisfied if the preference is set. + Pref(&'static str), + /// The condition is always satisfied. + Satisfied, +} + +impl Condition { + unsafe fn is_satisfied(&self, cx: *mut JSContext, obj: HandleObject) -> bool { + match *self { + Condition::Pref(name) => get_pref(name).as_boolean().unwrap_or(false), + Condition::Func(f) => f(cx, obj), + Condition::Satisfied => true, + } + } +} diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs index 9ce31b8bd36..590e57ba8e0 100644 --- a/components/script/dom/bindings/interface.rs +++ b/components/script/dom/bindings/interface.rs @@ -6,7 +6,8 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::conversions::get_dom_class; -use dom::bindings::utils::{get_proto_or_iface_array, Prefable}; +use dom::bindings::guard::Guard; +use dom::bindings::utils::get_proto_or_iface_array; use js::error::throw_type_error; use js::glue::UncheckedUnwrapObject; use js::jsapi::{Class, ClassExtension, ClassSpec, GetGlobalForObjectCrossCompartment}; @@ -66,7 +67,10 @@ pub type NonNullJSNative = /// Defines constants on `obj`. /// Fails on JSAPI failure. -pub fn define_constants(cx: *mut JSContext, obj: HandleObject, constants: &'static [ConstantSpec]) { +fn define_constants( + cx: *mut JSContext, + obj: HandleObject, + constants: &[ConstantSpec]) { for spec in constants { let value = RootedValue::new(cx, spec.get_value()); unsafe { @@ -208,18 +212,20 @@ impl InterfaceConstructorBehavior { /// Create and define the interface object of a callback interface. pub unsafe fn create_callback_interface_object( cx: *mut JSContext, - receiver: HandleObject, - constants: &'static [Prefable<ConstantSpec>], - name: &'static [u8], + global: HandleObject, + constants: &[Guard<&[ConstantSpec]>], + name: &[u8], rval: MutableHandleObject) { assert!(!constants.is_empty()); rval.set(JS_NewObject(cx, ptr::null())); assert!(!rval.ptr.is_null()); - for prefable in constants { - define_constants(cx, rval.handle(), prefable.specs()); + for guard in constants { + if let Some(specs) = guard.expose(cx, rval.handle()) { + define_constants(cx, rval.handle(), specs); + } } define_name(cx, rval.handle(), name); - define_on_global_object(cx, receiver, name, rval.handle()); + define_on_global_object(cx, global, name, rval.handle()); } /// Create the interface prototype object of a non-callback interface. @@ -227,9 +233,9 @@ pub unsafe fn create_interface_prototype_object( cx: *mut JSContext, proto: HandleObject, class: &'static JSClass, - regular_methods: Option<&'static [Prefable<JSFunctionSpec>]>, - regular_properties: Option<&'static [Prefable<JSPropertySpec>]>, - constants: &'static [Prefable<ConstantSpec>], + regular_methods: &[Guard<&'static [JSFunctionSpec]>], + regular_properties: &[Guard<&'static [JSPropertySpec]>], + constants: &[Guard<&[ConstantSpec]>], rval: MutableHandleObject) { create_object(cx, proto, class, regular_methods, regular_properties, constants, rval); } @@ -237,14 +243,14 @@ pub unsafe fn create_interface_prototype_object( /// Create and define the interface object of a non-callback interface. pub unsafe fn create_noncallback_interface_object( cx: *mut JSContext, - receiver: HandleObject, + global: HandleObject, proto: HandleObject, class: &'static NonCallbackInterfaceObjectClass, - static_methods: Option<&'static [Prefable<JSFunctionSpec>]>, - static_properties: Option<&'static [Prefable<JSPropertySpec>]>, - constants: &'static [Prefable<ConstantSpec>], + static_methods: &[Guard<&'static [JSFunctionSpec]>], + static_properties: &[Guard<&'static [JSPropertySpec]>], + constants: &[Guard<&[ConstantSpec]>], interface_prototype_object: HandleObject, - name: &'static [u8], + name: &[u8], length: u32, rval: MutableHandleObject) { create_object(cx, @@ -257,14 +263,14 @@ pub unsafe fn create_noncallback_interface_object( assert!(JS_LinkConstructorAndPrototype(cx, rval.handle(), interface_prototype_object)); define_name(cx, rval.handle(), name); define_length(cx, rval.handle(), length); - define_on_global_object(cx, receiver, name, rval.handle()); + define_on_global_object(cx, global, name, rval.handle()); } /// Create and define the named constructors of a non-callback interface. pub unsafe fn create_named_constructors( cx: *mut JSContext, - receiver: HandleObject, - named_constructors: &[(NonNullJSNative, &'static [u8], u32)], + global: HandleObject, + named_constructors: &[(NonNullJSNative, &[u8], u32)], interface_prototype_object: HandleObject) { let mut constructor = RootedObject::new(cx, ptr::null_mut()); @@ -288,7 +294,7 @@ pub unsafe fn create_named_constructors( None, None)); - define_on_global_object(cx, receiver, name, constructor.handle()); + define_on_global_object(cx, global, name, constructor.handle()); } } @@ -354,42 +360,46 @@ unsafe fn create_object( cx: *mut JSContext, proto: HandleObject, class: &'static JSClass, - methods: Option<&'static [Prefable<JSFunctionSpec>]>, - properties: Option<&'static [Prefable<JSPropertySpec>]>, - constants: &'static [Prefable<ConstantSpec>], + methods: &[Guard<&'static [JSFunctionSpec]>], + properties: &[Guard<&'static [JSPropertySpec]>], + constants: &[Guard<&[ConstantSpec]>], rval: MutableHandleObject) { rval.set(JS_NewObjectWithUniqueType(cx, class, proto)); assert!(!rval.ptr.is_null()); - if let Some(methods) = methods { - define_prefable_methods(cx, rval.handle(), methods); - } - if let Some(properties) = properties { - define_prefable_properties(cx, rval.handle(), properties); - } - for prefable in constants { - define_constants(cx, rval.handle(), prefable.specs()); + define_guarded_methods(cx, rval.handle(), methods); + define_guarded_properties(cx, rval.handle(), properties); + for guard in constants { + if let Some(specs) = guard.expose(cx, rval.handle()) { + define_constants(cx, rval.handle(), specs); + } } } /// Conditionally define methods on an object. -pub unsafe fn define_prefable_methods(cx: *mut JSContext, - obj: HandleObject, - methods: &'static [Prefable<JSFunctionSpec>]) { - for prefable in methods { - define_methods(cx, obj, prefable.specs()).unwrap(); +pub unsafe fn define_guarded_methods( + cx: *mut JSContext, + obj: HandleObject, + methods: &[Guard<&'static [JSFunctionSpec]>]) { + for guard in methods { + if let Some(specs) = guard.expose(cx, obj) { + define_methods(cx, obj, specs).unwrap(); + } } } /// Conditionally define properties on an object. -pub unsafe fn define_prefable_properties(cx: *mut JSContext, - obj: HandleObject, - properties: &'static [Prefable<JSPropertySpec>]) { - for prefable in properties { - define_properties(cx, obj, prefable.specs()).unwrap(); +pub unsafe fn define_guarded_properties( + cx: *mut JSContext, + obj: HandleObject, + properties: &[Guard<&'static [JSPropertySpec]>]) { + for guard in properties { + if let Some(specs) = guard.expose(cx, obj) { + define_properties(cx, obj, specs).unwrap(); + } } } -unsafe fn define_name(cx: *mut JSContext, obj: HandleObject, name: &'static [u8]) { +unsafe fn define_name(cx: *mut JSContext, obj: HandleObject, name: &[u8]) { assert!(*name.last().unwrap() == b'\0'); let name = RootedString::new( cx, JS_AtomizeAndPinString(cx, name.as_ptr() as *const libc::c_char)); @@ -413,12 +423,12 @@ unsafe fn define_length(cx: *mut JSContext, obj: HandleObject, length: u32) { unsafe fn define_on_global_object( cx: *mut JSContext, - receiver: HandleObject, - name: &'static [u8], + global: HandleObject, + name: &[u8], obj: HandleObject) { assert!(*name.last().unwrap() == b'\0'); assert!(JS_DefineProperty1(cx, - receiver, + global, name.as_ptr() as *const libc::c_char, obj, JSPROP_RESOLVING, diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs index d69720dc538..19797a473d0 100644 --- a/components/script/dom/bindings/mod.rs +++ b/components/script/dom/bindings/mod.rs @@ -133,6 +133,7 @@ pub mod cell; pub mod conversions; pub mod error; pub mod global; +pub mod guard; pub mod inheritance; pub mod interface; pub mod js; diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 607f74456d2..0f0d5bcf00e 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -16,6 +16,7 @@ use dom::bindings::trace::trace_object; use dom::browsingcontext; use heapsize::HeapSizeOf; use js; +use js::JS_CALLEE; use js::glue::{CallJitGetterOp, CallJitMethodOp, CallJitSetterOp, IsWrapper}; use js::glue::{GetCrossCompartmentWrapper, WrapperNew}; use js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO, RUST_JSID_IS_INT, RUST_JSID_IS_STRING}; @@ -32,14 +33,12 @@ use js::jsapi::{JS_SetReservedSlot, JS_StringHasLatin1Chars, MutableHandleValue, use js::jsapi::{OnNewGlobalHookOption, RootedObject, RootedValue}; use js::jsval::{JSVal, ObjectValue, PrivateValue, UndefinedValue}; use js::rust::{GCMethods, ToString}; -use js::{JS_CALLEE}; use libc; use std::default::Default; use std::ffi::CString; use std::os::raw::c_void; use std::ptr; use std::slice; -use util::prefs; /// Proxy handler for a WindowProxy. pub struct WindowProxyHandler(pub *const libc::c_void); @@ -550,31 +549,3 @@ unsafe extern "C" fn instance_class_has_proto_at_depth(clasp: *const js::jsapi:: pub const DOM_CALLBACKS: DOMCallbacks = DOMCallbacks { instanceClassMatchesProto: Some(instance_class_has_proto_at_depth), }; - -/// A container around JS member specifications that are conditionally enabled. -pub struct Prefable<T: 'static> { - /// If present, the name of the preference used to conditionally enable these specs. - pub pref: Option<&'static str>, - /// The underlying slice of specifications. - pub specs: &'static [T], - /// Whether the specifications contain special terminating entries that should be - /// included or not. - pub terminator: bool, -} - -impl<T> Prefable<T> { - /// Retrieve the slice represented by this container, unless the condition - /// guarding it is false. - pub fn specs(&self) -> &'static [T] { - if let Some(pref) = self.pref { - if !prefs::get_pref(pref).as_boolean().unwrap_or(false) { - return if self.terminator { - &self.specs[self.specs.len() - 1..] - } else { - &[] - }; - } - } - self.specs - } -} diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 89755564bb6..00dec5d995f 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -56,7 +56,7 @@ use dom::htmlembedelement::HTMLEmbedElement; use dom::htmlformelement::HTMLFormElement; use dom::htmlheadelement::HTMLHeadElement; use dom::htmlhtmlelement::HTMLHtmlElement; -use dom::htmliframeelement::{self, HTMLIFrameElement}; +use dom::htmliframeelement::HTMLIFrameElement; use dom::htmlimageelement::HTMLImageElement; use dom::htmllinkelement::HTMLLinkElement; use dom::htmlmetaelement::HTMLMetaElement; @@ -100,7 +100,7 @@ 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 num_traits::ToPrimitive; use origin::Origin; use parse::{ParserRoot, ParserRef, MutNullableParserField}; use script_thread::{MainThreadScriptMsg, Runnable}; @@ -127,6 +127,7 @@ use task_source::dom_manipulation::DOMManipulationTask; use time; use url::Url; use url::percent_encoding::percent_decode; +use util::prefs::mozbrowser_enabled; use util::str::{split_html_space_chars, str_join}; #[derive(JSTraceable, PartialEq, HeapSizeOf)] @@ -1228,9 +1229,9 @@ impl Document { self.stylesheets_changed_since_reflow.set(true); *self.stylesheets.borrow_mut() = None; // Mark the document element dirty so a reflow will be performed. - self.get_html_element().map(|root| { - root.upcast::<Node>().dirty(NodeDamage::NodeStyleDamaged); - }); + if let Some(element) = self.GetDocumentElement() { + element.upcast::<Node>().dirty(NodeDamage::NodeStyleDamaged); + } } pub fn get_and_reset_stylesheets_changed_since_reflow(&self) -> bool { @@ -1261,7 +1262,7 @@ impl Document { } pub fn trigger_mozbrowser_event(&self, event: MozBrowserEvent) { - if htmliframeelement::mozbrowser_enabled() { + if mozbrowser_enabled() { if let Some((containing_pipeline_id, subpage_id)) = self.window.parent_info() { let event = ConstellationMsg::MozBrowserEvent(containing_pipeline_id, subpage_id, diff --git a/components/script/dom/domquad.rs b/components/script/dom/domquad.rs index dbfb1f201d4..a53464739dc 100644 --- a/components/script/dom/domquad.rs +++ b/components/script/dom/domquad.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::DOMPointBinding::{DOMPointInit, DOMPointMethods}; use dom::bindings::codegen::Bindings::DOMQuadBinding::{DOMQuadInit, DOMQuadMethods, Wrap}; -use dom::bindings::codegen::Bindings::DOMRectReadOnlyBinding::{DOMRectInit}; +use dom::bindings::codegen::Bindings::DOMRectReadOnlyBinding::DOMRectInit; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; use dom::bindings::js::{Root, JS}; diff --git a/components/script/dom/forcetouchevent.rs b/components/script/dom/forcetouchevent.rs index 95532cb5c8f..1bc8a966cc5 100644 --- a/components/script/dom/forcetouchevent.rs +++ b/components/script/dom/forcetouchevent.rs @@ -7,7 +7,7 @@ use dom::bindings::codegen::Bindings::ForceTouchEventBinding::ForceTouchEventMet use dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{Root}; +use dom::bindings::js::Root; use dom::bindings::num::Finite; use dom::bindings::reflector::reflect_dom_object; use dom::bindings::str::DOMString; diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 3913d46b884..a4d1958445b 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::BrowserElementBinding::BrowserShowModalPro use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding; use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; -use dom::bindings::conversions::{ToJSValConvertible}; +use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::error::{Error, ErrorResult}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; @@ -42,13 +42,9 @@ use std::cell::Cell; use string_cache::Atom; use style::context::ReflowGoal; use url::Url; -use util::prefs; +use util::prefs::mozbrowser_enabled; use util::str::LengthOrPercentageOrAuto; -pub fn mozbrowser_enabled() -> bool { - prefs::get_pref("dom.mozbrowser.enabled").as_boolean().unwrap_or(false) -} - #[derive(HeapSizeOf)] enum SandboxAllowance { AllowNothing = 0x00, @@ -439,29 +435,16 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement { // Experimental mozbrowser implementation is based on the webidl // present in the gecko source tree, and the documentation here: // https://developer.mozilla.org/en-US/docs/Web/API/Using_the_Browser_API - - // TODO(gw): Use experimental codegen when it is available to avoid - // exposing these APIs. See https://github.com/servo/servo/issues/5264. - // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-mozbrowser fn Mozbrowser(&self) -> bool { - // We don't want to allow mozbrowser iframes within iframes - let is_root_pipeline = window_from_node(self).parent_info().is_none(); - if mozbrowser_enabled() && is_root_pipeline { - let element = self.upcast::<Element>(); - element.has_attribute(&atom!("mozbrowser")) - } else { - false - } + let element = self.upcast::<Element>(); + element.has_attribute(&atom!("mozbrowser")) } // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-mozbrowser - fn SetMozbrowser(&self, value: bool) -> ErrorResult { - if mozbrowser_enabled() { - let element = self.upcast::<Element>(); - element.set_bool_attribute(&atom!("mozbrowser"), value); - } - Ok(()) + fn SetMozbrowser(&self, value: bool) { + let element = self.upcast::<Element>(); + element.set_bool_attribute(&atom!("mozbrowser"), value); } // https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goBack diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 88de9756267..81b516e0772 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -9,8 +9,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::HTMLLinkElementBinding; use dom::bindings::codegen::Bindings::HTMLLinkElementBinding::HTMLLinkElementMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; -use dom::bindings::js::{RootedReference}; +use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference}; use dom::bindings::refcounted::Trusted; use dom::bindings::str::DOMString; use dom::document::Document; diff --git a/components/script/dom/mimetype.rs b/components/script/dom/mimetype.rs index 4757c4e7850..94262de5c26 100644 --- a/components/script/dom/mimetype.rs +++ b/components/script/dom/mimetype.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::MimeTypeBinding::MimeTypeMethods; use dom::bindings::js::Root; -use dom::bindings::reflector::{Reflector}; +use dom::bindings::reflector::Reflector; use dom::bindings::str::DOMString; use dom::plugin::Plugin; diff --git a/components/script/dom/plugin.rs b/components/script/dom/plugin.rs index 8fcd3f3a2e6..dc4ca4fe42d 100644 --- a/components/script/dom/plugin.rs +++ b/components/script/dom/plugin.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::PluginBinding::PluginMethods; use dom::bindings::js::Root; -use dom::bindings::reflector::{Reflector}; +use dom::bindings::reflector::Reflector; use dom::bindings::str::DOMString; use dom::mimetype::MimeType; diff --git a/components/script/dom/storageevent.rs b/components/script/dom/storageevent.rs index 71e3dc26350..1c9b563b037 100644 --- a/components/script/dom/storageevent.rs +++ b/components/script/dom/storageevent.rs @@ -4,7 +4,7 @@ use dom::bindings::codegen::Bindings::EventBinding::EventMethods; use dom::bindings::codegen::Bindings::StorageEventBinding; -use dom::bindings::codegen::Bindings::StorageEventBinding::{StorageEventMethods}; +use dom::bindings::codegen::Bindings::StorageEventBinding::StorageEventMethods; use dom::bindings::error::Fallible; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; diff --git a/components/script/dom/stylesheet.rs b/components/script/dom/stylesheet.rs index 0801d82fcad..15b8693c537 100644 --- a/components/script/dom/stylesheet.rs +++ b/components/script/dom/stylesheet.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::StyleSheetBinding; use dom::bindings::codegen::Bindings::StyleSheetBinding::StyleSheetMethods; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{Root}; +use dom::bindings::js::Root; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::window::Window; diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index faf53596ecc..630e5b2acd7 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -24,12 +24,12 @@ use dom::bindings::str::{ByteString, DOMString, USVString}; use dom::bindings::weakref::MutableWeakRef; use dom::blob::{Blob, DataSlice}; use dom::url::URL; -use js::jsapi::{HandleValue, JSContext, JSObject}; +use js::jsapi::{HandleObject, HandleValue, JSContext, JSObject}; use js::jsval::{JSVal, NullValue}; use std::borrow::ToOwned; use std::ptr; use std::rc::Rc; -use util::prefs::{get_pref}; +use util::prefs::get_pref; #[dom_struct] pub struct TestBinding { @@ -567,6 +567,10 @@ impl TestBindingMethods for TestBinding { fn PrefControlledAttributeEnabled(&self) -> bool { false } fn PrefControlledMethodDisabled(&self) {} fn PrefControlledMethodEnabled(&self) {} + fn FuncControlledAttributeDisabled(&self) -> bool { false } + fn FuncControlledAttributeEnabled(&self) -> bool { false } + fn FuncControlledMethodDisabled(&self) {} + fn FuncControlledMethodEnabled(&self) {} } impl TestBinding { @@ -577,4 +581,14 @@ impl TestBinding { pub fn PrefControlledStaticAttributeEnabled(_: GlobalRef) -> bool { false } pub fn PrefControlledStaticMethodDisabled(_: GlobalRef) {} pub fn PrefControlledStaticMethodEnabled(_: GlobalRef) {} + pub fn FuncControlledStaticAttributeDisabled(_: GlobalRef) -> bool { false } + pub fn FuncControlledStaticAttributeEnabled(_: GlobalRef) -> bool { false } + pub fn FuncControlledStaticMethodDisabled(_: GlobalRef) {} + pub fn FuncControlledStaticMethodEnabled(_: GlobalRef) {} +} + +#[allow(unsafe_code)] +impl TestBinding { + pub unsafe fn condition_satisfied(_: *mut JSContext, _: HandleObject) -> bool { true } + pub unsafe fn condition_unsatisfied(_: *mut JSContext, _: HandleObject) -> bool { false } } diff --git a/components/script/dom/text.rs b/components/script/dom/text.rs index 3d3100bcf4d..5d377e1e05d 100644 --- a/components/script/dom/text.rs +++ b/components/script/dom/text.rs @@ -11,7 +11,7 @@ use dom::bindings::error::{Error, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; -use dom::bindings::js::{RootedReference}; +use dom::bindings::js::RootedReference; use dom::bindings::str::DOMString; use dom::characterdata::CharacterData; use dom::document::Document; diff --git a/components/script/dom/userscripts.rs b/components/script/dom/userscripts.rs index dd9acb93a92..25490fb7726 100644 --- a/components/script/dom/userscripts.rs +++ b/components/script/dom/userscripts.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{RootedReference}; +use dom::bindings::js::RootedReference; use dom::bindings::str::DOMString; use dom::htmlheadelement::HTMLHeadElement; use dom::node::Node; diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs index 9dc4d7c16be..93522addf35 100644 --- a/components/script/dom/webglframebuffer.rs +++ b/components/script/dom/webglframebuffer.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl -use canvas_traits::{CanvasMsg}; +use canvas_traits::CanvasMsg; use dom::bindings::codegen::Bindings::WebGLFramebufferBinding; use dom::bindings::global::GlobalRef; use dom::bindings::js::Root; diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 3e57bae5a6e..540523323ac 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -4,7 +4,7 @@ use canvas_traits::{CanvasCommonMsg, CanvasMsg}; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; -use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{WebGLRenderingContextMethods}; +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}; @@ -87,6 +87,10 @@ pub struct WebGLRenderingContext { current_vertex_attrib_0: Cell<(f32, f32, f32, f32)>, } +fn log2(n: u32) -> u32 { + 31 - n.leading_zeros() +} + impl WebGLRenderingContext { fn new_inherited(global: GlobalRef, canvas: &HTMLCanvasElement, @@ -402,7 +406,7 @@ impl WebGLRenderingContext { // the returned value of GL_MAX_TEXTURE_SIZE when // target is GL_TEXTURE_2D or GL_MAX_CUBE_MAP_TEXTURE_SIZE // when target is not GL_TEXTURE_2D. - if level > (max as f32).log2() as i32 { + if level > log2(max) as i32 { self.webgl_error(InvalidValue); return false; } diff --git a/components/script/dom/webidls/HTMLIFrameElement.webidl b/components/script/dom/webidls/HTMLIFrameElement.webidl index 20bb563e908..0d78b56fb98 100644 --- a/components/script/dom/webidls/HTMLIFrameElement.webidl +++ b/components/script/dom/webidls/HTMLIFrameElement.webidl @@ -32,8 +32,8 @@ partial interface HTMLIFrameElement { }; partial interface HTMLIFrameElement { - [ChromeOnly,SetterThrows,Pref="dom.mozbrowser.enabled"] - attribute boolean mozbrowser; + [Func="Window::global_is_mozbrowser"] + attribute boolean mozbrowser; }; HTMLIFrameElement implements BrowserElement; diff --git a/components/script/dom/webidls/TestBinding.webidl b/components/script/dom/webidls/TestBinding.webidl index 6706ccfdaa9..cdfb9fd18ae 100644 --- a/components/script/dom/webidls/TestBinding.webidl +++ b/components/script/dom/webidls/TestBinding.webidl @@ -433,4 +433,26 @@ interface TestBinding { static void prefControlledStaticMethodEnabled(); [Pref="dom.testbinding.prefcontrolled2.enabled"] const unsigned short prefControlledConstEnabled = 0; + + [Func="TestBinding::condition_unsatisfied"] + readonly attribute boolean funcControlledAttributeDisabled; + [Func="TestBinding::condition_unsatisfied"] + static readonly attribute boolean funcControlledStaticAttributeDisabled; + [Func="TestBinding::condition_unsatisfied"] + void funcControlledMethodDisabled(); + [Func="TestBinding::condition_unsatisfied"] + static void funcControlledStaticMethodDisabled(); + [Func="TestBinding::condition_unsatisfied"] + const unsigned short funcControlledConstDisabled = 0; + + [Func="TestBinding::condition_satisfied"] + readonly attribute boolean funcControlledAttributeEnabled; + [Func="TestBinding::condition_satisfied"] + static readonly attribute boolean funcControlledStaticAttributeEnabled; + [Func="TestBinding::condition_satisfied"] + void funcControlledMethodEnabled(); + [Func="TestBinding::condition_satisfied"] + static void funcControlledStaticMethodEnabled(); + [Func="TestBinding::condition_satisfied"] + const unsigned short funcControlledConstEnabled = 0; }; diff --git a/components/script/dom/webidls/Window.webidl b/components/script/dom/webidls/Window.webidl index 65a7acbd1a2..c75def477da 100644 --- a/components/script/dom/webidls/Window.webidl +++ b/components/script/dom/webidls/Window.webidl @@ -20,7 +20,7 @@ //[Replaceable] readonly attribute BarProp scrollbars; //[Replaceable] readonly attribute BarProp statusbar; //[Replaceable] readonly attribute BarProp toolbar; - // attribute DOMString status; + attribute DOMString status; void close(); //readonly attribute boolean closed; //void stop(); diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 39894cbd585..8735394a7a9 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; 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::conversions::ToJSValConvertible; use dom::bindings::error::{Error, Fallible, ErrorResult}; use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 540266b6491..2cd6c4daf9e 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -14,7 +14,7 @@ use dom::bindings::codegen::Bindings::FunctionBinding::Function; use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions}; use dom::bindings::codegen::Bindings::WindowBinding::{self, FrameRequestCallback, WindowMethods}; use dom::bindings::error::{Error, Fallible, report_pending_exception}; -use dom::bindings::global::GlobalRef; +use dom::bindings::global::{GlobalRef, global_root_from_object}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::num::Finite; @@ -37,9 +37,8 @@ use dom::storage::Storage; use euclid::{Point2D, Rect, Size2D}; use gfx_traits::LayerId; use ipc_channel::ipc::{self, IpcSender}; -use js::jsapi::{Evaluate2, MutableHandleValue}; -use js::jsapi::{HandleValue, JSContext}; -use js::jsapi::{JSAutoCompartment, JS_GC, JS_GetRuntime, SetWindowProxy}; +use js::jsapi::{Evaluate2, HandleObject, HandleValue, JSAutoCompartment, JSContext}; +use js::jsapi::{JS_GetRuntime, JS_GC, MutableHandleValue, SetWindowProxy}; use js::rust::CompileOptionsWrapper; use js::rust::Runtime; use layout_interface::{ContentBoxResponse, ContentBoxesResponse, ResolvedStyleResponse, ScriptReflow}; @@ -79,7 +78,7 @@ use std::sync::{Arc, Mutex}; use string_cache::Atom; use style::context::ReflowGoal; use style::error_reporting::ParseErrorReporter; -use style::properties::longhands::{overflow_x}; +use style::properties::longhands::overflow_x; use style::selector_impl::PseudoElement; use task_source::TaskSource; use task_source::dom_manipulation::{DOMManipulationTaskSource, DOMManipulationTask}; @@ -93,6 +92,7 @@ use timers::{IsInterval, OneshotTimerCallback, OneshotTimerHandle, OneshotTimers use tinyfiledialogs::{self, MessageBoxIcon}; use url::Url; use util::geometry::{self, MAX_RECT}; +use util::prefs::mozbrowser_enabled; use util::str::HTML_SPACE_CHARACTERS; use util::{breakpoint, opts}; use webdriver_handlers::jsval_to_webdriver; @@ -160,6 +160,7 @@ pub struct Window { screen: MutNullableHeap<JS<Screen>>, session_storage: MutNullableHeap<JS<Storage>>, local_storage: MutNullableHeap<JS<Storage>>, + status: DOMRefCell<DOMString>, #[ignore_heap_size_of = "channels are hard"] scheduler_chan: IpcSender<TimerEventRequest>, timers: OneshotTimers, @@ -828,6 +829,16 @@ impl WindowMethods for Window { let dpr = self.window_size.get().map_or(1.0f32, |data| data.device_pixel_ratio.get()); Finite::wrap(dpr as f64) } + + // https://html.spec.whatwg.org/multipage/#dom-window-status + fn Status(&self) -> DOMString { + self.status.borrow().clone() + } + + // https://html.spec.whatwg.org/multipage/#dom-window-status + fn SetStatus(&self, status: DOMString) { + *self.status.borrow_mut() = status + } } pub trait ScriptHelpers { @@ -1437,6 +1448,19 @@ impl Window { context.active_window() }) } + + /// Returns whether mozbrowser is enabled and `obj` has been created + /// in a top-level `Window` global. + #[allow(unsafe_code)] + pub unsafe fn global_is_mozbrowser(_: *mut JSContext, obj: HandleObject) -> bool { + if !mozbrowser_enabled() { + return false; + } + match global_root_from_object(obj.get()).r() { + GlobalRef::Window(window) => window.parent_info().is_none(), + _ => false, + } + } } impl Window { @@ -1500,6 +1524,7 @@ impl Window { screen: Default::default(), session_storage: Default::default(), local_storage: Default::default(), + status: DOMRefCell::new(DOMString::new()), scheduler_chan: scheduler_chan.clone(), timers: OneshotTimers::new(timer_event_chan, scheduler_chan), next_worker_id: Cell::new(WorkerId(0)), diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 27fe4a783f0..743a06ff5ec 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -13,7 +13,7 @@ use dom::bindings::codegen::Bindings::XMLHttpRequestBinding; use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::BodyInit; use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::XMLHttpRequestMethods; use dom::bindings::codegen::Bindings::XMLHttpRequestBinding::XMLHttpRequestResponseType; -use dom::bindings::conversions::{ToJSValConvertible}; +use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::{GlobalRef, GlobalRoot}; use dom::bindings::inheritance::Castable; @@ -62,7 +62,7 @@ use string_cache::Atom; use time; use timers::{OneshotTimerCallback, OneshotTimerHandle}; use url::{Url, Position}; -use util::prefs; +use util::prefs::mozbrowser_enabled; #[derive(JSTraceable, PartialEq, Copy, Clone, HeapSizeOf)] enum XMLHttpRequestState { @@ -884,7 +884,7 @@ impl XMLHttpRequest { // story. See https://github.com/servo/servo/issues/9582 if let GlobalRoot::Window(win) = self.global() { let is_root_pipeline = win.parent_info().is_none(); - let is_mozbrowser_enabled = prefs::get_pref("dom.mozbrowser.enabled").as_boolean().unwrap_or(false); + let is_mozbrowser_enabled = mozbrowser_enabled(); is_root_pipeline && is_mozbrowser_enabled } else { false |