aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r--components/script/dom/bindings/callback.rs6
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py105
-rw-r--r--components/script/dom/bindings/codegen/Configuration.py11
-rw-r--r--components/script/dom/bindings/codegen/parser/WebIDL.py3
-rw-r--r--components/script/dom/bindings/codegen/parser/inline.patch12
-rwxr-xr-xcomponents/script/dom/bindings/codegen/parser/update.sh1
-rw-r--r--components/script/dom/bindings/error.rs10
-rw-r--r--components/script/dom/bindings/global.rs398
-rw-r--r--components/script/dom/bindings/iterable.rs7
-rw-r--r--components/script/dom/bindings/mod.rs8
-rw-r--r--components/script/dom/bindings/reflector.rs23
-rw-r--r--components/script/dom/bindings/structuredclone.rs6
12 files changed, 111 insertions, 479 deletions
diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs
index 7e6bb3534fb..709dab31049 100644
--- a/components/script/dom/bindings/callback.rs
+++ b/components/script/dom/bindings/callback.rs
@@ -5,8 +5,8 @@
//! Base classes to work with IDL callbacks.
use dom::bindings::error::{Error, Fallible, report_pending_exception};
-use dom::bindings::global::global_root_from_object;
use dom::bindings::reflector::Reflectable;
+use dom::globalscope::GlobalScope;
use js::jsapi::{Heap, MutableHandleObject, RootedObject};
use js::jsapi::{IsCallable, JSContext, JSObject, JS_WrapObject};
use js::jsapi::{JSCompartment, JS_EnterCompartment, JS_LeaveCompartment};
@@ -165,8 +165,8 @@ impl<'a> CallSetup<'a> {
callback: &T,
handling: ExceptionHandling)
-> CallSetup<'a> {
- let global = unsafe { global_root_from_object(callback.callback()) };
- let cx = global.r().get_cx();
+ let global = unsafe { GlobalScope::from_object(callback.callback()) };
+ let cx = global.get_cx();
exception_compartment.ptr = unsafe {
GetGlobalForObjectCrossCompartment(callback.callback())
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 4ea45ef9ded..24826ced714 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -817,16 +817,16 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
{ // Scope for our JSAutoCompartment.
rooted!(in(cx) let globalObj = CurrentGlobalOrNull(cx));
- let promiseGlobal = global_root_from_object_maybe_wrapped(globalObj.handle().get());
+ let promiseGlobal = GlobalScope::from_object_maybe_wrapped(globalObj.handle().get());
rooted!(in(cx) let mut valueToResolve = $${val}.get());
if !JS_WrapValue(cx, valueToResolve.handle_mut()) {
$*{exceptionCode}
}
- match Promise::Resolve(promiseGlobal.r(), cx, valueToResolve.handle()) {
+ match Promise::Resolve(&promiseGlobal, cx, valueToResolve.handle()) {
Ok(value) => value,
Err(error) => {
- throw_dom_exception(cx, promiseGlobal.r(), error);
+ throw_dom_exception(cx, &promiseGlobal, error);
$*{exceptionCode}
}
}
@@ -1927,10 +1927,12 @@ class CGImports(CGWrapper):
if t in dictionaries or t in enums:
continue
if t.isInterface() or t.isNamespace():
- descriptor = descriptorProvider.getDescriptor(getIdentifier(t).name)
- extras += [descriptor.path]
- if descriptor.interface.parent:
- parentName = getIdentifier(descriptor.interface.parent).name
+ name = getIdentifier(t).name
+ descriptor = descriptorProvider.getDescriptor(name)
+ if name != 'GlobalScope':
+ extras += [descriptor.path]
+ parentName = descriptor.getParentName()
+ if parentName:
descriptor = descriptorProvider.getDescriptor(parentName)
extras += [descriptor.path, descriptor.bindingPath]
elif t.isType() and t.isMozMap():
@@ -2523,7 +2525,8 @@ class CGWrapMethod(CGAbstractMethod):
def __init__(self, descriptor):
assert not descriptor.interface.isCallback()
assert not descriptor.isGlobal()
- args = [Argument('*mut JSContext', 'cx'), Argument('GlobalRef', 'scope'),
+ args = [Argument('*mut JSContext', 'cx'),
+ Argument('&GlobalScope', 'scope'),
Argument("Box<%s>" % descriptor.concreteType, 'object')]
retval = 'Root<%s>' % descriptor.concreteType
CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args,
@@ -2754,7 +2757,7 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null());
getPrototypeProto = "prototype_proto.set(JS_GetObjectPrototype(cx, global))"
else:
getPrototypeProto = ("%s::GetProtoObject(cx, global, prototype_proto.handle_mut())" %
- toBindingNamespace(self.descriptor.prototypeChain[-2]))
+ toBindingNamespace(self.descriptor.getParentName()))
code = [CGGeneric("""\
rooted!(in(cx) let mut prototype_proto = ptr::null_mut());
@@ -2808,8 +2811,9 @@ assert!((*cache)[PrototypeList::ID::%(id)s as usize].is_null());
properties["length"] = methodLength(self.descriptor.interface.ctor())
else:
properties["length"] = 0
- if self.descriptor.interface.parent:
- parentName = toBindingNamespace(self.descriptor.getParentName())
+ parentName = self.descriptor.getParentName()
+ if parentName:
+ parentName = toBindingNamespace(parentName)
code.append(CGGeneric("""
rooted!(in(cx) let mut interface_proto = ptr::null_mut());
%s::GetConstructorObject(cx, global, interface_proto.handle_mut());""" % parentName))
@@ -3164,16 +3168,15 @@ class CGCallGenerator(CGThing):
if isFallible:
if static:
- glob = ""
+ glob = "&global"
else:
- glob = " let global = global_root_from_reflector(this);\n"
+ glob = "&this.global()"
self.cgRoot.append(CGGeneric(
"let result = match result {\n"
" Ok(result) => result,\n"
" Err(e) => {\n"
- "%s"
- " throw_dom_exception(cx, global.r(), e);\n"
+ " throw_dom_exception(cx, %s, e);\n"
" return%s;\n"
" },\n"
"};" % (glob, errorResult)))
@@ -3383,7 +3386,7 @@ class CGAbstractStaticBindingMethod(CGAbstractMethod):
def definition_body(self):
preamble = CGGeneric("""\
-let global = global_root_from_object(JS_CALLEE(cx, vp).to_object());
+let global = GlobalScope::from_object(JS_CALLEE(cx, vp).to_object());
""")
return CGList([preamble, self.generate_code()])
@@ -3435,7 +3438,7 @@ class CGStaticMethod(CGAbstractStaticBindingMethod):
nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
self.method)
setupArgs = CGGeneric("let args = CallArgs::from_vp(vp, argc);\n")
- call = CGMethodCall(["global.r()"], nativeName, True, self.descriptor, self.method)
+ call = CGMethodCall(["&global"], nativeName, True, self.descriptor, self.method)
return CGList([setupArgs, call])
@@ -3489,7 +3492,7 @@ class CGStaticGetter(CGAbstractStaticBindingMethod):
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
self.attr)
setupArgs = CGGeneric("let args = CallArgs::from_vp(vp, argc);\n")
- call = CGGetterCall(["global.r()"], self.attr.type, nativeName, self.descriptor,
+ call = CGGetterCall(["&global"], self.attr.type, nativeName, self.descriptor,
self.attr)
return CGList([setupArgs, call])
@@ -3542,7 +3545,7 @@ class CGStaticSetter(CGAbstractStaticBindingMethod):
" throw_type_error(cx, \"Not enough arguments to %s setter.\");\n"
" return false;\n"
"}" % self.attr.identifier.name)
- call = CGSetterCall(["global.r()"], self.attr.type, nativeName, self.descriptor,
+ call = CGSetterCall(["&global"], self.attr.type, nativeName, self.descriptor,
self.attr)
return CGList([checkForArg, call])
@@ -5249,12 +5252,12 @@ class CGClassConstructHook(CGAbstractExternMethod):
def definition_body(self):
preamble = CGGeneric("""\
-let global = global_root_from_object(JS_CALLEE(cx, vp).to_object());
+let global = GlobalScope::from_object(JS_CALLEE(cx, vp).to_object());
let args = CallArgs::from_vp(vp, argc);
""")
name = self.constructor.identifier.name
nativeName = MakeNativeName(self.descriptor.binaryNameFor(name))
- callGenerator = CGMethodCall(["global.r()"], nativeName, True,
+ callGenerator = CGMethodCall(["&global"], nativeName, True,
self.descriptor, self.constructor)
return CGList([preamble, callGenerator])
@@ -5496,10 +5499,6 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'dom::bindings::codegen::InterfaceObjectMap',
'dom::bindings::constant::ConstantSpec',
'dom::bindings::constant::ConstantVal',
- 'dom::bindings::global::GlobalRef',
- 'dom::bindings::global::global_root_from_object',
- 'dom::bindings::global::global_root_from_object_maybe_wrapped',
- 'dom::bindings::global::global_root_from_reflector',
'dom::bindings::interface::ConstructorClassHook',
'dom::bindings::interface::InterfaceConstructorBehavior',
'dom::bindings::interface::NonCallbackInterfaceObjectClass',
@@ -5593,6 +5592,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'dom::bindings::weakref::WeakBox',
'dom::bindings::weakref::WeakReferenceable',
'dom::browsingcontext::BrowsingContext',
+ 'dom::globalscope::GlobalScope',
'mem::heap_size_of_raw_self_and_children',
'libc',
'util::prefs::PREFS',
@@ -5744,33 +5744,38 @@ class CGDescriptor(CGThing):
cgThings.append(CGGeneric(str(properties)))
- if not descriptor.interface.isCallback() and not descriptor.interface.isNamespace():
- cgThings.append(CGGetProtoObjectMethod(descriptor))
- reexports.append('GetProtoObject')
- cgThings.append(CGPrototypeJSClass(descriptor))
- if descriptor.interface.hasInterfaceObject():
- if descriptor.interface.ctor():
- cgThings.append(CGClassConstructHook(descriptor))
- for ctor in descriptor.interface.namedConstructors:
- cgThings.append(CGClassConstructHook(descriptor, ctor))
- if not descriptor.interface.isCallback():
- cgThings.append(CGInterfaceObjectJSClass(descriptor))
- if descriptor.shouldHaveGetConstructorObjectMethod():
- cgThings.append(CGGetConstructorObjectMethod(descriptor))
- reexports.append('GetConstructorObject')
- if descriptor.register:
- cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
- reexports.append('DefineDOMInterface')
- cgThings.append(CGConstructorEnabled(descriptor))
- cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties, haveUnscopables))
+ if not descriptor.interface.getExtendedAttribute("Inline"):
+ if not descriptor.interface.isCallback() and not descriptor.interface.isNamespace():
+ cgThings.append(CGGetProtoObjectMethod(descriptor))
+ reexports.append('GetProtoObject')
+ cgThings.append(CGPrototypeJSClass(descriptor))
+ if descriptor.interface.hasInterfaceObject():
+ if descriptor.interface.ctor():
+ cgThings.append(CGClassConstructHook(descriptor))
+ for ctor in descriptor.interface.namedConstructors:
+ cgThings.append(CGClassConstructHook(descriptor, ctor))
+ if not descriptor.interface.isCallback():
+ cgThings.append(CGInterfaceObjectJSClass(descriptor))
+ if descriptor.shouldHaveGetConstructorObjectMethod():
+ cgThings.append(CGGetConstructorObjectMethod(descriptor))
+ reexports.append('GetConstructorObject')
+ if descriptor.register:
+ cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
+ reexports.append('DefineDOMInterface')
+ cgThings.append(CGConstructorEnabled(descriptor))
+ cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties, haveUnscopables))
cgThings = generate_imports(config, CGList(cgThings, '\n'), [descriptor])
cgThings = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name),
cgThings, public=True),
post='\n')
- reexports = ', '.join(map(lambda name: reexportedName(name), reexports))
- self.cgRoot = CGList([CGGeneric('pub use self::%s::{%s};' % (toBindingNamespace(descriptor.name), reexports)),
- cgThings], '\n')
+
+ if reexports:
+ reexports = ', '.join(map(lambda name: reexportedName(name), reexports))
+ cgThings = CGList([CGGeneric('pub use self::%s::{%s};' % (toBindingNamespace(descriptor.name), reexports)),
+ cgThings], '\n')
+
+ self.cgRoot = cgThings
def define(self):
return self.cgRoot.define()
@@ -6799,7 +6804,7 @@ class GlobalGenRoots():
globals_ = CGWrapper(CGIndenter(global_flags), pre="bitflags! {\n", post="\n}")
pairs = []
- for d in config.getDescriptors(hasInterfaceObject=True):
+ for d in config.getDescriptors(hasInterfaceObject=True, isInline=False):
binding = toBindingNamespace(d.name)
pairs.append((d.name, binding, binding))
for ctor in d.interface.namedConstructors:
@@ -6927,7 +6932,7 @@ class GlobalGenRoots():
allprotos.append(CGGeneric("\n"))
if downcast:
- hierarchy[descriptor.getParentName()].append(name)
+ hierarchy[descriptor.interface.parent.identifier.name].append(name)
typeIdCode = []
topTypeVariants = [
@@ -6959,7 +6964,7 @@ impl Clone for TopTypeId {
for base, derived in hierarchy.iteritems():
variants = []
- if not config.getInterface(base).getExtendedAttribute("Abstract"):
+ if config.getDescriptor(base).concrete:
variants.append(CGGeneric(base))
variants += [CGGeneric(type_id_variant(derivedName)) for derivedName in derived]
derives = "Clone, Copy, Debug, PartialEq"
diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py
index 9a1120769c8..f2f64e9bee0 100644
--- a/components/script/dom/bindings/codegen/Configuration.py
+++ b/components/script/dom/bindings/codegen/Configuration.py
@@ -88,6 +88,8 @@ class Configuration:
getter = lambda x: x.interface.isJSImplemented()
elif key == 'isGlobal':
getter = lambda x: x.isGlobal()
+ elif key == 'isInline':
+ getter = lambda x: x.interface.getExtendedAttribute('Inline') is not None
elif key == 'isExposedConditionally':
getter = lambda x: x.interface.isExposedConditionally()
elif key == 'isIteratorInterface':
@@ -234,6 +236,7 @@ class Descriptor(DescriptorProvider):
self.concrete = (not self.interface.isCallback() and
not self.interface.isNamespace() and
not self.interface.getExtendedAttribute("Abstract") and
+ not self.interface.getExtendedAttribute("Inline") and
not spiderMonkeyInterface)
self.hasUnforgeableMembers = (self.concrete and
any(MemberIsUnforgeable(m, self) for m in
@@ -383,8 +386,12 @@ class Descriptor(DescriptorProvider):
return attrs
def getParentName(self):
- assert self.interface.parent is not None
- return self.interface.parent.identifier.name
+ parent = self.interface.parent
+ while parent:
+ if not parent.getExtendedAttribute("Inline"):
+ return parent.identifier.name
+ parent = parent.parent
+ return None
def hasDescendants(self):
return (self.interface.getUserData("hasConcreteDescendant", False) or
diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py
index 2894bbeb82e..dc9fa036141 100644
--- a/components/script/dom/bindings/codegen/parser/WebIDL.py
+++ b/components/script/dom/bindings/codegen/parser/WebIDL.py
@@ -1695,7 +1695,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
identifier == "ProbablyShortLivingObject" or
identifier == "LegacyUnenumerableNamedProperties" or
identifier == "NonOrdinaryGetPrototypeOf" or
- identifier == "Abstract"):
+ identifier == "Abstract" or
+ identifier == "Inline"):
# Known extended attributes that do not take values
if not attr.noArguments():
raise WebIDLError("[%s] must take no arguments" % identifier,
diff --git a/components/script/dom/bindings/codegen/parser/inline.patch b/components/script/dom/bindings/codegen/parser/inline.patch
new file mode 100644
index 00000000000..5d1056d2b58
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/inline.patch
@@ -0,0 +1,12 @@
+--- WebIDL.py
++++ WebIDL.py
+@@ -1695,7 +1695,8 @@ class IDLInterface(IDLInterfaceOrNamespace):
+ identifier == "ProbablyShortLivingObject" or
+ identifier == "LegacyUnenumerableNamedProperties" or
+ identifier == "NonOrdinaryGetPrototypeOf" or
+- identifier == "Abstract"):
++ identifier == "Abstract" or
++ identifier == "Inline"):
+ # Known extended attributes that do not take values
+ if not attr.noArguments():
+ raise WebIDLError("[%s] must take no arguments" % identifier, \ No newline at end of file
diff --git a/components/script/dom/bindings/codegen/parser/update.sh b/components/script/dom/bindings/codegen/parser/update.sh
index 6bf56cead30..213aba6df89 100755
--- a/components/script/dom/bindings/codegen/parser/update.sh
+++ b/components/script/dom/bindings/codegen/parser/update.sh
@@ -4,6 +4,7 @@ patch < debug.patch
patch < pref-main-thread.patch
patch < callback-location.patch
patch < union-typedef.patch
+patch < inline.patch
wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz
rm -r tests
diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs
index 1c0d49c4976..96ae220ce98 100644
--- a/components/script/dom/bindings/error.rs
+++ b/components/script/dom/bindings/error.rs
@@ -8,9 +8,9 @@ use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
use dom::bindings::codegen::PrototypeList::proto_id_to_name;
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};
+use dom::globalscope::GlobalScope;
use js::error::{throw_range_error, throw_type_error};
use js::jsapi::HandleObject;
use js::jsapi::JSContext;
@@ -87,7 +87,7 @@ pub type Fallible<T> = Result<T, Error>;
pub type ErrorResult = Fallible<()>;
/// Set a pending exception for the given `result` on `cx`.
-pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef, result: Error) {
+pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: &GlobalScope, result: Error) {
let code = match result {
Error::IndexSize => DOMErrorName::IndexSizeError,
Error::NotFound => DOMErrorName::NotFoundError,
@@ -245,8 +245,8 @@ pub unsafe fn report_pending_exception(cx: *mut JSContext, dispatch_event: bool)
error_info.message);
if dispatch_event {
- let global = global_root_from_context(cx);
- global.r().report_an_error(error_info, value.handle());
+ GlobalScope::from_context(cx)
+ .report_an_error(error_info, value.handle());
}
}
}
@@ -270,7 +270,7 @@ pub unsafe fn throw_invalid_this(cx: *mut JSContext, proto_id: u16) {
impl Error {
/// Convert this error value to a JS value, consuming it in the process.
- pub unsafe fn to_jsval(self, cx: *mut JSContext, global: GlobalRef, rval: MutableHandleValue) {
+ pub unsafe fn to_jsval(self, cx: *mut JSContext, global: &GlobalScope, rval: MutableHandleValue) {
assert!(!JS_IsExceptionPending(cx));
throw_dom_exception(cx, global, self);
assert!(JS_IsExceptionPending(cx));
diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs
deleted file mode 100644
index e0341ceeb68..00000000000
--- a/components/script/dom/bindings/global.rs
+++ /dev/null
@@ -1,398 +0,0 @@
-/* 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/. */
-
-//! Abstractions for global scopes.
-//!
-//! This module contains smart pointers to global scopes, to simplify writing
-//! code that works in workers as well as window scopes.
-
-use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId};
-use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
-use dom::bindings::conversions::root_from_object;
-use dom::bindings::error::{ErrorInfo, report_pending_exception};
-use dom::bindings::js::Root;
-use dom::bindings::reflector::{Reflectable, Reflector};
-use dom::console::TimerSet;
-use dom::window;
-use dom::workerglobalscope::WorkerGlobalScope;
-use ipc_channel::ipc::IpcSender;
-use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
-use js::glue::{IsWrapper, UnwrapObject};
-use js::jsapi::{CurrentGlobalOrNull, Evaluate2, GetGlobalForObjectCrossCompartment};
-use js::jsapi::{HandleValue, JS_GetClass, JSAutoCompartment, JSContext};
-use js::jsapi::{JSObject, MutableHandleValue};
-use js::rust::CompileOptionsWrapper;
-use libc;
-use msg::constellation_msg::PipelineId;
-use net_traits::{CoreResourceThread, IpcSend, ResourceThreads};
-use profile_traits::{mem, time};
-use script_runtime::{CommonScriptMsg, EnqueuedPromiseCallback, ScriptChan};
-use script_runtime::{ScriptPort, maybe_take_panic_result};
-use script_thread::{MainThreadScriptChan, RunnableWrapper, ScriptThread};
-use script_traits::{MsDuration, ScriptMsg as ConstellationMsg, TimerEventRequest};
-use std::ffi::CString;
-use std::panic;
-use task_source::file_reading::FileReadingTaskSource;
-use timers::{OneshotTimerCallback, OneshotTimerHandle};
-use url::Url;
-
-/// A freely-copyable reference to a rooted global object.
-#[derive(Copy, Clone)]
-pub enum GlobalRef<'a> {
- /// A reference to a `Window` object.
- Window(&'a window::Window),
- /// A reference to a `WorkerGlobalScope` object.
- Worker(&'a WorkerGlobalScope),
-}
-
-/// A stack-based rooted reference to a global object.
-pub enum GlobalRoot {
- /// A root for a `Window` object.
- Window(Root<window::Window>),
- /// A root for a `WorkerGlobalScope` object.
- Worker(Root<WorkerGlobalScope>),
-}
-
-impl<'a> GlobalRef<'a> {
- /// Get the `JSContext` for the `JSRuntime` associated with the thread
- /// this global object is on.
- pub fn get_cx(&self) -> *mut JSContext {
- match *self {
- GlobalRef::Window(ref window) => window.get_cx(),
- GlobalRef::Worker(ref worker) => worker.get_cx(),
- }
- }
-
- /// Extract a `Window`, causing thread failure if the global object is not
- /// a `Window`.
- pub fn as_window(&self) -> &window::Window {
- match *self {
- GlobalRef::Window(window) => window,
- GlobalRef::Worker(_) => panic!("expected a Window scope"),
- }
- }
-
- /// Get the `PipelineId` for this global scope.
- pub fn pipeline_id(&self) -> PipelineId {
- match *self {
- GlobalRef::Window(window) => window.pipeline_id(),
- GlobalRef::Worker(worker) => worker.pipeline_id(),
- }
- }
-
- /// Get a `mem::ProfilerChan` to send messages to the memory profiler thread.
- pub fn mem_profiler_chan(&self) -> &mem::ProfilerChan {
- match *self {
- GlobalRef::Window(window) => window.mem_profiler_chan(),
- GlobalRef::Worker(worker) => worker.mem_profiler_chan(),
- }
- }
-
- /// Get a `time::ProfilerChan` to send messages to the time profiler thread.
- pub fn time_profiler_chan(&self) -> &time::ProfilerChan {
- match *self {
- GlobalRef::Window(window) => window.time_profiler_chan(),
- GlobalRef::Worker(worker) => worker.time_profiler_chan(),
- }
- }
-
- /// Get a `IpcSender` to send messages to the constellation when available.
- pub fn constellation_chan(&self) -> &IpcSender<ConstellationMsg> {
- match *self {
- GlobalRef::Window(window) => window.constellation_chan(),
- GlobalRef::Worker(worker) => worker.constellation_chan(),
- }
- }
-
- /// Get the scheduler channel to request timer events.
- pub fn scheduler_chan(&self) -> &IpcSender<TimerEventRequest> {
- match *self {
- GlobalRef::Window(window) => window.scheduler_chan(),
- GlobalRef::Worker(worker) => worker.scheduler_chan(),
- }
- }
-
- /// Get an `IpcSender<ScriptToDevtoolsControlMsg>` to send messages to Devtools
- /// thread when available.
- pub fn devtools_chan(&self) -> Option<IpcSender<ScriptToDevtoolsControlMsg>> {
- match *self {
- GlobalRef::Window(window) => window.devtools_chan(),
- GlobalRef::Worker(worker) => worker.devtools_chan(),
- }
- }
-
- /// Get the `ResourceThreads` for this global scope.
- pub fn resource_threads(&self) -> ResourceThreads {
- match *self {
- GlobalRef::Window(ref window) => window.resource_threads().clone(),
- GlobalRef::Worker(ref worker) => worker.resource_threads().clone(),
- }
- }
-
- /// Get the `CoreResourceThread` for this global scope
- pub fn core_resource_thread(&self) -> CoreResourceThread {
- self.resource_threads().sender()
- }
-
- /// Get next worker id.
- pub fn get_next_worker_id(&self) -> WorkerId {
- match *self {
- GlobalRef::Window(ref window) => window.get_next_worker_id(),
- GlobalRef::Worker(ref worker) => worker.get_next_worker_id(),
- }
- }
-
- /// Get the URL for this global scope.
- pub fn get_url(&self) -> Url {
- match *self {
- GlobalRef::Window(ref window) => window.get_url(),
- GlobalRef::Worker(ref worker) => worker.get_url().clone(),
- }
- }
-
- /// Get the [base url](https://html.spec.whatwg.org/multipage/#api-base-url)
- /// for this global scope.
- pub fn api_base_url(&self) -> Url {
- match *self {
- // https://html.spec.whatwg.org/multipage/#script-settings-for-browsing-contexts:api-base-url
- GlobalRef::Window(ref window) => window.Document().base_url(),
- // https://html.spec.whatwg.org/multipage/#script-settings-for-workers:api-base-url
- GlobalRef::Worker(ref worker) => worker.get_url().clone(),
- }
- }
-
- /// `ScriptChan` used to send messages to the event loop of this global's
- /// thread.
- pub fn script_chan(&self) -> Box<ScriptChan + Send> {
- match *self {
- GlobalRef::Window(ref window) =>
- MainThreadScriptChan(window.main_thread_script_chan().clone()).clone(),
- GlobalRef::Worker(ref worker) => worker.script_chan(),
- }
- }
-
- /// `ScriptChan` used to send messages to the event loop of this global's
- /// thread.
- pub fn networking_task_source(&self) -> Box<ScriptChan + Send> {
- match *self {
- GlobalRef::Window(ref window) => window.networking_task_source(),
- GlobalRef::Worker(ref worker) => worker.script_chan(),
- }
- }
-
- /// `ScriptChan` used to send messages to the event loop of this global's
- /// thread.
- pub fn file_reading_task_source(&self) -> FileReadingTaskSource {
- match *self {
- GlobalRef::Window(ref window) => window.file_reading_task_source(),
- GlobalRef::Worker(ref worker) => worker.file_reading_task_source(),
- }
- }
-
- /// Create a new sender/receiver pair that can be used to implement an on-demand
- /// event loop. Used for implementing web APIs that require blocking semantics
- /// without resorting to nested event loops.
- pub fn new_script_pair(&self) -> (Box<ScriptChan + Send>, Box<ScriptPort + Send>) {
- match *self {
- GlobalRef::Window(ref window) => window.new_script_pair(),
- GlobalRef::Worker(ref worker) => worker.new_script_pair(),
- }
- }
-
- /// Process a single event as if it were the next event in the thread queue for
- /// this global.
- pub fn process_event(&self, msg: CommonScriptMsg) {
- match *self {
- GlobalRef::Window(_) => ScriptThread::process_event(msg),
- GlobalRef::Worker(ref worker) => worker.process_event(msg),
- }
- }
-
- /// Evaluate JS code on this global.
- pub fn evaluate_js_on_global_with_result(
- &self, code: &str, rval: MutableHandleValue) {
- self.evaluate_script_on_global_with_result(code, "", rval)
- }
-
- /// Evaluate a JS script on this global.
- #[allow(unsafe_code)]
- pub fn evaluate_script_on_global_with_result(
- &self, code: &str, filename: &str, rval: MutableHandleValue) {
- let metadata = time::TimerMetadata {
- url: if filename.is_empty() {
- self.get_url().as_str().into()
- } else {
- filename.into()
- },
- iframe: time::TimerMetadataFrameType::RootWindow,
- incremental: time::TimerMetadataReflowType::FirstReflow,
- };
- time::profile(
- time::ProfilerCategory::ScriptEvaluate,
- Some(metadata),
- self.time_profiler_chan().clone(),
- || {
- let cx = self.get_cx();
- let globalhandle = self.reflector().get_jsobject();
- let code: Vec<u16> = code.encode_utf16().collect();
- let filename = CString::new(filename).unwrap();
-
- let _ac = JSAutoCompartment::new(cx, globalhandle.get());
- let options = CompileOptionsWrapper::new(cx, filename.as_ptr(), 1);
- unsafe {
- if !Evaluate2(cx, options.ptr, code.as_ptr(),
- code.len() as libc::size_t,
- rval) {
- debug!("error evaluating JS string");
- report_pending_exception(cx, true);
- }
- }
-
- if let Some(error) = maybe_take_panic_result() {
- panic::resume_unwind(error);
- }
- }
- )
- }
-
- /// Set the `bool` value to indicate whether developer tools has requested
- /// updates from the global
- pub fn set_devtools_wants_updates(&self, send_updates: bool) {
- match *self {
- GlobalRef::Window(window) => window.set_devtools_wants_updates(send_updates),
- GlobalRef::Worker(worker) => worker.set_devtools_wants_updates(send_updates),
- }
- }
-
- /// Schedule the given `callback` to be invoked after at least `duration` milliseconds have
- /// passed.
- pub fn schedule_callback(&self,
- callback: OneshotTimerCallback,
- duration: MsDuration)
- -> OneshotTimerHandle {
- match *self {
- GlobalRef::Window(window) => window.schedule_callback(callback, duration),
- GlobalRef::Worker(worker) => worker.schedule_callback(callback, duration),
- }
- }
-
- /// Unschedule a previously-scheduled callback.
- pub fn unschedule_callback(&self, handle: OneshotTimerHandle) {
- match *self {
- GlobalRef::Window(window) => window.unschedule_callback(handle),
- GlobalRef::Worker(worker) => worker.unschedule_callback(handle),
- }
- }
-
- /// Returns the global's timers for the Console API.
- pub fn console_timers(&self) -> &TimerSet {
- match *self {
- GlobalRef::Window(ref window) => window.console_timers(),
- GlobalRef::Worker(ref worker) => worker.console_timers(),
- }
- }
-
- /// Returns a wrapper for runnables to ensure they are cancelled if the global
- /// is being destroyed.
- pub fn get_runnable_wrapper(&self) -> RunnableWrapper {
- match *self {
- GlobalRef::Window(ref window) => window.get_runnable_wrapper(),
- GlobalRef::Worker(ref worker) => worker.get_runnable_wrapper(),
- }
- }
-
- /// Enqueue a promise callback for subsequent execution.
- pub fn enqueue_promise_job(&self, job: EnqueuedPromiseCallback) {
- match *self {
- GlobalRef::Window(_) => ScriptThread::enqueue_promise_job(job, *self),
- GlobalRef::Worker(ref worker) => worker.enqueue_promise_job(job),
- }
- }
-
- /// Start the process of executing the pending promise callbacks. They will be invoked
- /// in FIFO order, synchronously, at some point in the future.
- pub fn flush_promise_jobs(&self) {
- match *self {
- GlobalRef::Window(_) => ScriptThread::flush_promise_jobs(*self),
- GlobalRef::Worker(ref worker) => worker.flush_promise_jobs(),
- }
- }
-
- /// https://html.spec.whatwg.org/multipage/#report-the-error
- 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(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(),
- }
- }
-}
-
-impl GlobalRoot {
- /// Obtain a safe reference to the global object that cannot outlive the
- /// lifetime of this root.
- pub fn r(&self) -> GlobalRef {
- match *self {
- GlobalRoot::Window(ref window) => GlobalRef::Window(window.r()),
- GlobalRoot::Worker(ref worker) => GlobalRef::Worker(worker.r()),
- }
- }
-}
-
-/// 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 {
- unsafe { global_root_from_object(*reflector.reflector().get_jsobject()) }
-}
-
-/// Returns the Rust global object from a JS global object.
-#[allow(unrooted_must_root)]
-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(_) => (),
- }
-
- 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 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 unsafe fn global_root_from_context(cx: *mut JSContext) -> GlobalRoot {
- let global = CurrentGlobalOrNull(cx);
- global_root_from_global(global)
-}
-
-/// Returns the global object of the realm that the given JS object was created in,
-/// after unwrapping any wrappers.
-pub unsafe fn global_root_from_object_maybe_wrapped(mut obj: *mut JSObject) -> GlobalRoot {
- if IsWrapper(obj) {
- obj = UnwrapObject(obj, /* stopAtWindowProxy = */ 0);
- assert!(!obj.is_null());
- }
- global_root_from_object(obj)
-}
diff --git a/components/script/dom/bindings/iterable.rs b/components/script/dom/bindings/iterable.rs
index 84381b52655..3e6febeeb5d 100644
--- a/components/script/dom/bindings/iterable.rs
+++ b/components/script/dom/bindings/iterable.rs
@@ -10,10 +10,10 @@ use core::nonzero::NonZero;
use dom::bindings::codegen::Bindings::IterableIteratorBinding::IterableKeyAndValueResult;
use dom::bindings::codegen::Bindings::IterableIteratorBinding::IterableKeyOrValueResult;
use dom::bindings::error::Fallible;
-use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{Reflector, Reflectable, MutReflectable, reflect_dom_object};
use dom::bindings::trace::JSTraceable;
+use dom::globalscope::GlobalScope;
use js::conversions::ToJSValConvertible;
use js::jsapi::{JSContext, JSObject, MutableHandleValue, MutableHandleObject, HandleValue};
use js::jsval::UndefinedValue;
@@ -85,7 +85,7 @@ impl<T: Reflectable + JSTraceable + Iterable> IterableIterator<T> {
/// Create a new iterator instance for the provided iterable DOM interface.
pub fn new(iterable: &T,
type_: IteratorType,
- wrap: fn(*mut JSContext, GlobalRef, Box<IterableIterator<T>>)
+ wrap: fn(*mut JSContext, &GlobalScope, Box<IterableIterator<T>>)
-> Root<Self>) -> Root<Self> {
let iterator = box IterableIterator {
reflector: Reflector::new(),
@@ -93,8 +93,7 @@ impl<T: Reflectable + JSTraceable + Iterable> IterableIterator<T> {
iterable: JS::from_ref(iterable),
index: Cell::new(0),
};
- let global = iterable.global();
- reflect_dom_object(iterator, global.r(), wrap)
+ reflect_dom_object(iterator, &*iterable.global(), wrap)
}
/// Return the next value from the iterable object.
diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs
index 013484a47b9..27504efda7c 100644
--- a/components/script/dom/bindings/mod.rs
+++ b/components/script/dom/bindings/mod.rs
@@ -43,8 +43,9 @@
//! [`Fallible<T>`](error/type.Fallible.html).
//! Methods that use certain WebIDL types like `any` or `object` will get a
//! `*mut JSContext` argument prepended to the argument list. Static methods
-//! will be passed a [`GlobalRef`](global/enum.GlobalRef.html) for the relevant
-//! global. This argument comes before the `*mut JSContext` argument, if any.
+//! will be passed a [`&GlobalScope`](../globalscope/struct.GlobalScope.html)
+//! for the relevant global. This argument comes before the `*mut JSContext`
+//! argument, if any.
//!
//! Rust reflections of WebIDL operations (methods)
//! -----------------------------------------------
@@ -79,7 +80,7 @@
//!
//! A WebIDL constructor is turned into a static class method named
//! `Constructor`. The arguments of this method will be the arguments of the
-//! WebIDL constructor, with a `GlobalRef` for the relevant global prepended.
+//! WebIDL constructor, with a `&GlobalScope` for the relevant global prepended.
//! The return value of the constructor for MyInterface is exactly the same as
//! that of a method returning an instance of MyInterface. Constructors are
//! always [allowed to throw](#throwing-exceptions).
@@ -133,7 +134,6 @@ pub mod cell;
pub mod constant;
pub mod conversions;
pub mod error;
-pub mod global;
pub mod guard;
pub mod inheritance;
pub mod interface;
diff --git a/components/script/dom/bindings/reflector.rs b/components/script/dom/bindings/reflector.rs
index d5280712a03..737268bf7d0 100644
--- a/components/script/dom/bindings/reflector.rs
+++ b/components/script/dom/bindings/reflector.rs
@@ -4,19 +4,24 @@
//! The `Reflector` struct.
-use dom::bindings::global::{GlobalRef, GlobalRoot, global_root_from_reflector};
+use dom::bindings::conversions::DerivedFrom;
use dom::bindings::js::Root;
+use dom::globalscope::GlobalScope;
use js::jsapi::{HandleObject, JSContext, JSObject};
use std::cell::UnsafeCell;
use std::ptr;
/// Create the reflector for a new DOM object and yield ownership to the
/// reflector.
-pub fn reflect_dom_object<T: Reflectable>(obj: Box<T>,
- global: GlobalRef,
- wrap_fn: fn(*mut JSContext, GlobalRef, Box<T>) -> Root<T>)
- -> Root<T> {
- wrap_fn(global.get_cx(), global, obj)
+pub fn reflect_dom_object<T, U>(
+ obj: Box<T>,
+ global: &U,
+ wrap_fn: fn(*mut JSContext, &GlobalScope, Box<T>) -> Root<T>)
+ -> Root<T>
+ where T: Reflectable, U: DerivedFrom<GlobalScope>
+{
+ let global_scope = global.upcast();
+ wrap_fn(global_scope.get_cx(), global_scope, obj)
}
/// A struct to store a reference to the reflector of a DOM object.
@@ -74,9 +79,9 @@ pub trait Reflectable {
/// Returns the receiver's reflector.
fn reflector(&self) -> &Reflector;
- /// 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)
+ /// Returns the global scope of the realm that the Reflectable was created in.
+ fn global(&self) -> Root<GlobalScope> where Self: Sized {
+ GlobalScope::from_reflector(self)
}
}
diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs
index 21963eec172..405d245c4bb 100644
--- a/components/script/dom/bindings/structuredclone.rs
+++ b/components/script/dom/bindings/structuredclone.rs
@@ -6,7 +6,7 @@
//! (https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data).
use dom::bindings::error::{Error, Fallible};
-use dom::bindings::global::GlobalRef;
+use dom::globalscope::GlobalScope;
use js::jsapi::{HandleValue, MutableHandleValue};
use js::jsapi::{JSContext, JS_ReadStructuredClone, JS_STRUCTURED_CLONE_VERSION};
use js::jsapi::{JS_ClearPendingException, JS_WriteStructuredClone};
@@ -60,7 +60,7 @@ impl StructuredCloneData {
/// Reads a structured clone.
///
/// Panics if `JS_ReadStructuredClone` fails.
- fn read_clone(global: GlobalRef, data: *mut u64, nbytes: size_t, rval: MutableHandleValue) {
+ fn read_clone(global: &GlobalScope, data: *mut u64, nbytes: size_t, rval: MutableHandleValue) {
unsafe {
assert!(JS_ReadStructuredClone(global.get_cx(),
data,
@@ -73,7 +73,7 @@ impl StructuredCloneData {
}
/// Thunk for the actual `read_clone` method. Resolves proper variant for read_clone.
- pub fn read(self, global: GlobalRef, rval: MutableHandleValue) {
+ pub fn read(self, global: &GlobalScope, rval: MutableHandleValue) {
match self {
StructuredCloneData::Vector(mut vec_msg) => {
let nbytes = vec_msg.len();