Auto merge of #29805 - jdm:dom-protos, r=mrobinson

Support extending DOM classes in JS

Adds support for determining the correct prototype as part of a `new` call for non-HTML constructors. Support for HTML constructors [was added](https://github.com/servo/servo/blob/master/components/script/dom/bindings/htmlconstructor.rs#L116) as part of the custom element work, but that wasn't enough for extending other DOM objects like `EventTarget`.

This work is based on Gecko's code in https://searchfox.org/mozilla-central/rev/2d678a843ceab81e43f7ffb83212197dc10e944a/dom/bindings/BindingUtils.cpp#3667, and is split into two parts:
1) the actualy new implementation (demonstrating that extending `EventTarget` works as expected)
2) plumbing the new prototype through all of the rest of the DOM object construction code.

This ends up being more complex than the way it's done in Gecko because they have lazy DOM reflectors, so their native DOM objects can be constructed without any knowledge of a JS prototype. Servo's reflectors are eager, however, so we need to propagate prototype information into individual constructors. As a result, this was a tedious set of changes to make.

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #29770
- [x] There are tests for these changes
This commit is contained in:
bors-servo 2023-06-01 05:06:09 +02:00 committed by GitHub
commit fd7698c3ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
208 changed files with 2657 additions and 696 deletions

4
Cargo.lock generated
View file

@ -3752,7 +3752,7 @@ dependencies = [
[[package]]
name = "mozjs"
version = "0.14.1"
source = "git+https://github.com/servo/mozjs#d2a3526611cc123139d01f9ac4ff915f805f9e74"
source = "git+https://github.com/servo/mozjs#b9edc816b6662a5986e190cdf53ae295049acb92"
dependencies = [
"cc",
"lazy_static",
@ -3765,7 +3765,7 @@ dependencies = [
[[package]]
name = "mozjs_sys"
version = "0.68.2"
source = "git+https://github.com/servo/mozjs#d2a3526611cc123139d01f9ac4ff915f805f9e74"
source = "git+https://github.com/servo/mozjs#b9edc816b6662a5986e190cdf53ae295049acb92"
dependencies = [
"bindgen",
"cc",

View file

@ -14,14 +14,14 @@ use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::window::Window;
use crate::task_source::TaskSource;
use dom_struct::dom_struct;
use ipc_channel::ipc::{self, IpcReceiver};
use ipc_channel::router::ROUTER;
use js::rust::CustomAutoRooterGuard;
use js::rust::{CustomAutoRooterGuard, HandleObject};
use js::typedarray::{Float32Array, Uint8Array};
use servo_media::audio::analyser_node::AnalysisEngine;
use servo_media::audio::block::Block;
@ -89,14 +89,23 @@ impl AnalyserNode {
))
}
#[allow(unrooted_must_root)]
pub fn new(
window: &Window,
context: &BaseAudioContext,
options: &AnalyserOptions,
) -> Fallible<DomRoot<AnalyserNode>> {
Self::new_with_proto(window, None, context, options)
}
#[allow(unrooted_must_root)]
pub fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &AnalyserOptions,
) -> Fallible<DomRoot<AnalyserNode>> {
let (node, recv) = AnalyserNode::new_inherited(window, context, options)?;
let object = reflect_dom_object(Box::new(node), window);
let object = reflect_dom_object_with_proto(Box::new(node), window, proto);
let (source, canceller) = window
.task_manager()
.dom_manipulation_task_source_with_canceller();
@ -122,10 +131,11 @@ impl AnalyserNode {
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &AnalyserOptions,
) -> Fallible<DomRoot<AnalyserNode>> {
AnalyserNode::new(window, context, options)
AnalyserNode::new_with_proto(window, proto, context, options)
}
pub fn push_block(&self, block: Block) {

View file

@ -8,12 +8,13 @@ use crate::dom::bindings::codegen::Bindings::AnimationEventBinding::{
use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::event::Event;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_atoms::Atom;
#[dom_struct]
@ -35,7 +36,20 @@ impl AnimationEvent {
}
pub fn new(window: &Window, type_: Atom, init: &AnimationEventInit) -> DomRoot<AnimationEvent> {
let ev = reflect_dom_object(Box::new(AnimationEvent::new_inherited(init)), window);
Self::new_with_proto(window, None, type_, init)
}
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
type_: Atom,
init: &AnimationEventInit,
) -> DomRoot<AnimationEvent> {
let ev = reflect_dom_object_with_proto(
Box::new(AnimationEvent::new_inherited(init)),
window,
proto,
);
{
let event = ev.upcast::<Event>();
event.init_event(type_, init.parent.bubbles, init.parent.cancelable);
@ -46,10 +60,11 @@ impl AnimationEvent {
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
type_: DOMString,
init: &AnimationEventInit,
) -> DomRoot<AnimationEvent> {
AnimationEvent::new(window, Atom::from(type_), init)
AnimationEvent::new_with_proto(window, proto, Atom::from(type_), init)
}
}

View file

@ -9,7 +9,7 @@ use crate::dom::bindings::codegen::Bindings::AudioBufferBinding::{
};
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
@ -20,6 +20,7 @@ use js::jsapi::JS_GetArrayBufferViewBuffer;
use js::jsapi::{Heap, JSObject};
use js::rust::wrappers::DetachArrayBuffer;
use js::rust::CustomAutoRooterGuard;
use js::rust::HandleObject;
use js::typedarray::{CreateWith, Float32Array};
use servo_media::audio::buffer_source_node::AudioBuffer as ServoMediaAudioBuffer;
use std::cmp::min;
@ -76,16 +77,34 @@ impl AudioBuffer {
}
}
#[allow(unrooted_must_root)]
pub fn new(
global: &Window,
number_of_channels: u32,
length: u32,
sample_rate: f32,
initial_data: Option<&[Vec<f32>]>,
) -> DomRoot<AudioBuffer> {
Self::new_with_proto(
global,
None,
number_of_channels,
length,
sample_rate,
initial_data,
)
}
#[allow(unrooted_must_root)]
fn new_with_proto(
global: &Window,
proto: Option<HandleObject>,
number_of_channels: u32,
length: u32,
sample_rate: f32,
initial_data: Option<&[Vec<f32>]>,
) -> DomRoot<AudioBuffer> {
let buffer = AudioBuffer::new_inherited(number_of_channels, length, sample_rate);
let buffer = reflect_dom_object(Box::new(buffer), global);
let buffer = reflect_dom_object_with_proto(Box::new(buffer), global, proto);
buffer.set_initial_data(initial_data);
buffer
}
@ -94,6 +113,7 @@ impl AudioBuffer {
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
options: &AudioBufferOptions,
) -> Fallible<DomRoot<AudioBuffer>> {
if options.length <= 0 ||
@ -104,8 +124,9 @@ impl AudioBuffer {
{
return Err(Error::NotSupported);
}
Ok(AudioBuffer::new(
Ok(AudioBuffer::new_with_proto(
window,
proto,
options.numberOfChannels,
options.length,
*options.sampleRate,

View file

@ -13,10 +13,11 @@ use crate::dom::bindings::codegen::Bindings::AudioScheduledSourceNodeBinding::Au
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_media::audio::buffer_source_node::AudioBufferSourceNodeMessage;
use servo_media::audio::buffer_source_node::AudioBufferSourceNodeOptions;
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage};
@ -92,23 +93,33 @@ impl AudioBufferSourceNode {
Ok(node)
}
#[allow(unrooted_must_root)]
pub fn new(
window: &Window,
context: &BaseAudioContext,
options: &AudioBufferSourceOptions,
) -> Fallible<DomRoot<AudioBufferSourceNode>> {
Self::new_with_proto(window, None, context, options)
}
#[allow(unrooted_must_root)]
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &AudioBufferSourceOptions,
) -> Fallible<DomRoot<AudioBufferSourceNode>> {
let node = AudioBufferSourceNode::new_inherited(window, context, options)?;
Ok(reflect_dom_object(Box::new(node), window))
Ok(reflect_dom_object_with_proto(Box::new(node), window, proto))
}
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &AudioBufferSourceOptions,
) -> Fallible<DomRoot<AudioBufferSourceNode>> {
AudioBufferSourceNode::new(window, context, options)
AudioBufferSourceNode::new_with_proto(window, proto, context, options)
}
}

View file

@ -17,7 +17,7 @@ use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject};
use crate::dom::bindings::root::DomRoot;
use crate::dom::htmlmediaelement::HTMLMediaElement;
use crate::dom::mediaelementaudiosourcenode::MediaElementAudioSourceNode;
@ -31,6 +31,7 @@ use crate::dom::window::Window;
use crate::realms::InRealm;
use crate::task_source::TaskSource;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use msg::constellation_msg::PipelineId;
use servo_media::audio::context::{LatencyCategory, ProcessingState, RealTimeAudioContextOptions};
use std::rc::Rc;
@ -79,10 +80,14 @@ impl AudioContext {
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, options: &AudioContextOptions) -> DomRoot<AudioContext> {
fn new(
window: &Window,
proto: Option<HandleObject>,
options: &AudioContextOptions,
) -> DomRoot<AudioContext> {
let pipeline_id = window.pipeline_id();
let context = AudioContext::new_inherited(options, pipeline_id);
let context = reflect_dom_object(Box::new(context), window);
let context = reflect_dom_object_with_proto(Box::new(context), window, proto);
context.resume();
context
}
@ -91,9 +96,10 @@ impl AudioContext {
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
options: &AudioContextOptions,
) -> Fallible<DomRoot<AudioContext>> {
Ok(AudioContext::new(window, options))
Ok(AudioContext::new(window, proto, options))
}
fn resume(&self) {

View file

@ -2313,10 +2313,11 @@ def DOMClass(descriptor):
return """\
DOMClass {
interface_chain: [ %s ],
depth: %d,
type_id: %s,
malloc_size_of: %s as unsafe fn(&mut _, _) -> _,
global: InterfaceObjectMap::Globals::%s,
}""" % (prototypeChainString, DOMClassTypeId(descriptor), mallocSizeOf, globals_)
}""" % (prototypeChainString, descriptor.prototypeDepth, DOMClassTypeId(descriptor), mallocSizeOf, globals_)
class CGDOMJSClass(CGThing):
@ -2865,7 +2866,7 @@ ensure_expando_object(*cx, obj.handle().into(), expando.handle_mut());
copyFunc = "JS_InitializePropertiesFromCompatibleNativeObject"
copyCode += """\
let mut slot = UndefinedValue();
JS_GetReservedSlot(proto.get(), DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, &mut slot);
JS_GetReservedSlot(canonical_proto.get(), DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, &mut slot);
rooted!(in(*cx) let mut unforgeable_holder = ptr::null_mut::<JSObject>());
unforgeable_holder.handle_mut().set(slot.to_object());
assert!(%(copyFunc)s(*cx, %(obj)s.handle(), unforgeable_holder.handle()));
@ -2884,6 +2885,7 @@ class CGWrapMethod(CGAbstractMethod):
assert not descriptor.isGlobal()
args = [Argument('SafeJSContext', 'cx'),
Argument('&GlobalScope', 'scope'),
Argument('Option<HandleObject>', 'given_proto'),
Argument("Box<%s>" % descriptor.concreteType, 'object')]
retval = 'DomRoot<%s>' % descriptor.concreteType
CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args,
@ -2896,7 +2898,7 @@ class CGWrapMethod(CGAbstractMethod):
proto = "ptr::null_mut()"
lazyProto = "true" # Our proxy handler will manage the prototype
else:
proto = "proto.get()"
proto = "canonical_proto.get()"
lazyProto = "false"
create = """
@ -2924,6 +2926,15 @@ SetProxyReservedSlot(
else:
lazyProto = None
create = """
rooted!(in(*cx) let mut proto = ptr::null_mut::<JSObject>());
if let Some(given) = given_proto {
*proto = *given;
if get_context_realm(*cx) != get_object_realm(*given) {
assert!(JS_WrapObject(*cx, proto.handle_mut()));
}
} else {
*proto = *canonical_proto;
}
rooted!(in(*cx) let obj = JS_NewObjectWithGivenProto(
*cx,
&Class.base,
@ -2951,9 +2962,9 @@ assert!(!scope.get().is_null());
assert!(((*get_object_class(scope.get())).flags & JSCLASS_IS_GLOBAL) != 0);
let _ac = JSAutoRealm::new(*cx, scope.get());
rooted!(in(*cx) let mut proto = ptr::null_mut::<JSObject>());
GetProtoObject(cx, scope, proto.handle_mut());
assert!(!proto.is_null());
rooted!(in(*cx) let mut canonical_proto = ptr::null_mut::<JSObject>());
GetProtoObject(cx, scope, canonical_proto.handle_mut());
assert!(!canonical_proto.is_null());
%(createObject)s
let root = raw.reflect_with(obj.get());
@ -3010,9 +3021,9 @@ assert!(!obj.is_null());
let root = raw.reflect_with(obj.get());
let _ac = JSAutoRealm::new(*cx, obj.get());
rooted!(in(*cx) let mut proto = ptr::null_mut::<JSObject>());
GetProtoObject(cx, obj.handle(), proto.handle_mut());
assert!(JS_SetPrototype(*cx, obj.handle(), proto.handle()));
rooted!(in(*cx) let mut canonical_proto = ptr::null_mut::<JSObject>());
GetProtoObject(cx, obj.handle(), canonical_proto.handle_mut());
assert!(JS_SetPrototype(*cx, obj.handle(), canonical_proto.handle()));
let mut immutable = false;
assert!(JS_SetImmutablePrototype(*cx, obj.handle(), &mut immutable));
assert!(immutable);
@ -3076,6 +3087,7 @@ impl DomObjectWrap for %s {
const WRAP: unsafe fn(
SafeJSContext,
&GlobalScope,
Option<HandleObject>,
Box<Self>,
) -> Root<Dom<Self>> = Wrap;
}
@ -3098,6 +3110,7 @@ impl DomObjectIteratorWrap for %s {
const ITER_WRAP: unsafe fn(
SafeJSContext,
&GlobalScope,
Option<HandleObject>,
Box<IterableIterator<Self>>,
) -> Root<Dom<IterableIterator<Self>>> = Wrap;
}
@ -3950,6 +3963,17 @@ let global = GlobalScope::from_object(args.callee());
raise NotImplementedError # Override me!
def GetConstructorNameForReporting(descriptor, ctor):
# Figure out the name of our constructor for reporting purposes.
# For unnamed webidl constructors, identifier.name is "constructor" but
# the name JS sees is the interface name; for legacy factory functions
# identifier.name is the actual name.
ctorName = ctor.identifier.name
if ctorName == "constructor":
return descriptor.interface.identifier.name
return ctorName
class CGSpecializedMethod(CGAbstractExternMethod):
"""
A class for generating the C++ code for a specialized method that the JIT
@ -6102,14 +6126,13 @@ class CGClassConstructHook(CGAbstractExternMethod):
def definition_body(self):
preamble = """let cx = SafeJSContext::from_ptr(cx);
let args = CallArgs::from_vp(vp, argc);
let global = GlobalScope::from_object(JS_CALLEE(*cx, vp).to_object());
"""
if len(self.exposureSet) == 1:
preamble += """\
let global = DomRoot::downcast::<dom::types::%s>(global).unwrap();
""" % list(self.exposureSet)[0]
preamble += """let args = CallArgs::from_vp(vp, argc);\n"""
preamble = CGGeneric(preamble)
if self.constructor.isHTMLConstructor():
signatures = self.constructor.signatures()
assert len(signatures) == 1
@ -6120,11 +6143,32 @@ let global = DomRoot::downcast::<dom::types::%s>(global).unwrap();
GetProtoObject,
)""" % self.descriptor.name)
else:
ctorName = GetConstructorNameForReporting(self.descriptor, self.constructor)
preamble += """
if !callargs_is_constructing(&args) {
throw_constructor_without_new(*cx, "%s");
return false;
}
rooted!(in(*cx) let mut desired_proto = ptr::null_mut::<JSObject>());
let proto_result = get_desired_proto(
cx,
&args,
PrototypeList::ID::%s,
CreateInterfaceObjects,
desired_proto.handle_mut(),
);
assert!(proto_result.is_ok());
if proto_result.is_err() {
return false;
}
""" % (ctorName, MakeNativeName(self.descriptor.name))
name = self.constructor.identifier.name
nativeName = MakeNativeName(self.descriptor.binaryNameFor(name))
constructorCall = CGMethodCall(["&global"], nativeName, True,
args = ["&global", "Some(desired_proto.handle())"]
constructorCall = CGMethodCall(args, nativeName, True,
self.descriptor, self.constructor)
return CGList([preamble, constructorCall])
return CGList([CGGeneric(preamble), constructorCall])
class CGClassFinalizeHook(CGAbstractClassHook):
@ -6295,6 +6339,8 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'js::jsapi::CallArgs',
'js::jsapi::CurrentGlobalOrNull',
'js::rust::wrappers::GetPropertyKeys',
'js::rust::get_object_realm',
'js::rust::get_context_realm',
'js::jsapi::GCContext',
'js::jsapi::GetWellKnownSymbol',
'js::rust::Handle',
@ -6439,6 +6485,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'crate::dom::bindings::interface::define_guarded_properties',
'crate::dom::bindings::interface::is_exposed_in',
'crate::dom::bindings::interface::get_per_interface_object_handle',
'crate::dom::bindings::interface::get_desired_proto',
'crate::dom::bindings::htmlconstructor::pop_current_element_queue',
'crate::dom::bindings::htmlconstructor::push_new_element_queue',
'crate::dom::bindings::iterable::Iterable',
@ -6461,6 +6508,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'crate::dom::bindings::utils::DOM_PROTO_UNFORGEABLE_HOLDER_SLOT',
'crate::dom::bindings::utils::JSCLASS_DOM_GLOBAL',
'crate::dom::bindings::utils::ProtoOrIfaceArray',
'crate::dom::bindings::utils::callargs_is_constructing',
'crate::dom::bindings::utils::enumerate_global',
'crate::dom::bindings::utils::finalize_global',
'crate::dom::bindings::utils::generic_getter',
@ -6511,6 +6559,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'crate::dom::bindings::error::Fallible',
'crate::dom::bindings::error::Error::JSFailed',
'crate::dom::bindings::error::throw_dom_exception',
'crate::dom::bindings::error::throw_constructor_without_new',
'crate::dom::bindings::guard::Condition',
'crate::dom::bindings::guard::Guard',
'crate::dom::bindings::inheritance::Castable',

View file

@ -312,6 +312,12 @@ pub unsafe fn throw_invalid_this(cx: *mut JSContext, proto_id: u16) {
throw_type_error(cx, &error);
}
pub unsafe fn throw_constructor_without_new(cx: *mut JSContext, name: &str) {
debug_assert!(!JS_IsExceptionPending(cx));
let error = format!("{} constructor: 'new' is required", name);
throw_type_error(cx, &error);
}
impl Error {
/// Convert this error value to a JS value, consuming it in the process.
pub unsafe fn to_jsval(

View file

@ -225,10 +225,18 @@ unsafe fn html_constructor(
None => {
// Step 8.1
let name = QualName::new(None, ns!(html), definition.local_name.clone());
// Any prototype used to create these elements will be overwritten before returning
// from this function, so we don't bother overwriting the defaults here.
let element = if definition.is_autonomous() {
DomRoot::upcast(HTMLElement::new(name.local, None, &*document))
DomRoot::upcast(HTMLElement::new(name.local, None, &*document, None))
} else {
create_native_html_element(name, None, &*document, ElementCreator::ScriptCreated)
create_native_html_element(
name,
None,
&*document,
ElementCreator::ScriptCreated,
None,
)
};
// Step 8.2 is performed in the generated caller code.

View file

@ -11,16 +11,24 @@ use crate::dom::bindings::conversions::{get_dom_class, DOM_OBJECT_SLOT};
use crate::dom::bindings::guard::Guard;
use crate::dom::bindings::principals::ServoJSPrincipals;
use crate::dom::bindings::utils::{
get_proto_or_iface_array, ProtoOrIfaceArray, DOM_PROTOTYPE_SLOT, JSCLASS_DOM_GLOBAL,
callargs_is_constructing, get_proto_or_iface_array, DOMJSClass, ProtoOrIfaceArray,
DOM_PROTOTYPE_SLOT, JSCLASS_DOM_GLOBAL,
};
use crate::script_runtime::JSContext as SafeJSContext;
use js::error::throw_type_error;
use js::glue::UncheckedUnwrapObject;
use js::jsapi::CheckedUnwrapStatic;
use js::jsapi::CurrentGlobalOrNull;
use js::jsapi::GetFunctionRealm;
use js::jsapi::GetNonCCWObjectGlobal;
use js::jsapi::GetRealmGlobalOrNull;
use js::jsapi::GetWellKnownSymbol;
use js::jsapi::HandleObject as RawHandleObject;
use js::jsapi::JS_GetProperty;
use js::jsapi::JS_WrapObject;
use js::jsapi::{jsid, JSClass, JSClassOps};
use js::jsapi::{
Compartment, CompartmentSpecifier, IsSharableCompartment, IsSystemCompartment,
CallArgs, Compartment, CompartmentSpecifier, IsSharableCompartment, IsSystemCompartment,
JS_IterateCompartments, JS::CompartmentIterResult,
};
use js::jsapi::{JSAutoRealm, JSContext, JSFunctionSpec, JSObject, JSFUN_CONSTRUCTOR};
@ -31,13 +39,15 @@ use js::jsapi::{JS_NewStringCopyN, JS_SetReservedSlot};
use js::jsapi::{ObjectOps, OnNewGlobalHookOption, SymbolCode};
use js::jsapi::{TrueHandleValue, Value};
use js::jsapi::{JSPROP_PERMANENT, JSPROP_READONLY, JSPROP_RESOLVING};
use js::jsval::NullValue;
use js::jsval::{JSVal, PrivateValue};
use js::rust::is_dom_class;
use js::rust::wrappers::JS_FireOnNewGlobalObject;
use js::rust::wrappers::RUST_SYMBOL_TO_JSID;
use js::rust::wrappers::{JS_DefineProperty, JS_DefineProperty5};
use js::rust::wrappers::{JS_DefineProperty3, JS_DefineProperty4, JS_DefinePropertyById5};
use js::rust::wrappers::{JS_LinkConstructorAndPrototype, JS_NewObjectWithGivenProto};
use js::rust::{define_methods, define_properties, get_object_class};
use js::rust::{define_methods, define_properties, get_object_class, maybe_wrap_object};
use js::rust::{HandleObject, HandleValue, MutableHandleObject, RealmOptions};
use servo_url::MutableOrigin;
use std::convert::TryFrom;
@ -592,3 +602,113 @@ pub fn define_dom_interface(
get_per_interface_object_handle(cx, global, id, creator, proto.handle_mut());
assert!(!proto.is_null());
}
fn get_proto_id_for_new_target(new_target: HandleObject) -> Option<PrototypeList::ID> {
unsafe {
let new_target_class = get_object_class(*new_target);
if is_dom_class(&*new_target_class) {
let domjsclass: *const DOMJSClass = new_target_class as *const DOMJSClass;
let dom_class = &(*domjsclass).dom_class;
return Some(dom_class.interface_chain[dom_class.depth as usize]);
}
return None;
}
}
pub fn get_desired_proto(
cx: SafeJSContext,
args: &CallArgs,
proto_id: PrototypeList::ID,
creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
mut desired_proto: MutableHandleObject,
) -> Result<(), ()> {
unsafe {
// This basically implements
// https://heycam.github.io/webidl/#internally-create-a-new-object-implementing-the-interface
// step 3.
assert!(callargs_is_constructing(args));
// The desired prototype depends on the actual constructor that was invoked,
// which is passed to us as the newTarget in the callargs. We want to do
// something akin to the ES6 specification's GetProtototypeFromConstructor (so
// get .prototype on the newTarget, with a fallback to some sort of default).
// First, a fast path for the case when the the constructor is in fact one of
// our DOM constructors. This is safe because on those the "constructor"
// property is non-configurable and non-writable, so we don't have to do the
// slow JS_GetProperty call.
rooted!(in(*cx) let mut new_target = args.new_target().to_object());
rooted!(in(*cx) let original_new_target = *new_target);
// See whether we have a known DOM constructor here, such that we can take a
// fast path.
let target_proto_id = get_proto_id_for_new_target(new_target.handle()).or_else(|| {
// We might still have a cross-compartment wrapper for a known DOM
// constructor. CheckedUnwrapStatic is fine here, because we're looking for
// DOM constructors and those can't be cross-origin objects.
*new_target = CheckedUnwrapStatic(*new_target);
if !new_target.is_null() && &*new_target != &*original_new_target {
get_proto_id_for_new_target(new_target.handle())
} else {
None
}
});
if let Some(proto_id) = target_proto_id {
let global = GetNonCCWObjectGlobal(*new_target);
let proto_or_iface_cache = get_proto_or_iface_array(global);
desired_proto.set((*proto_or_iface_cache)[proto_id as usize]);
if &*new_target != &*original_new_target {
if !JS_WrapObject(*cx, desired_proto.into()) {
return Err(());
}
}
return Ok(());
}
// Slow path. This basically duplicates the ES6 spec's
// GetPrototypeFromConstructor except that instead of taking a string naming
// the fallback prototype we determine the fallback based on the proto id we
// were handed.
rooted!(in(*cx) let mut proto_val = NullValue());
if !JS_GetProperty(
*cx,
original_new_target.handle().into(),
b"prototype\0".as_ptr() as *const libc::c_char,
proto_val.handle_mut().into(),
) {
return Err(());
}
if proto_val.is_object() {
desired_proto.set(proto_val.to_object());
return Ok(());
}
// Fall back to getting the proto for our given proto id in the realm that
// GetFunctionRealm(newTarget) returns.
let realm = GetFunctionRealm(*cx, new_target.handle().into());
if realm.is_null() {
return Err(());
}
{
let _realm = JSAutoRealm::new(*cx, GetRealmGlobalOrNull(realm));
rooted!(in(*cx) let global = CurrentGlobalOrNull(*cx));
get_per_interface_object_handle(
cx,
global.handle(),
ProtoOrIfaceIndex::ID(proto_id),
creator,
desired_proto,
);
if desired_proto.is_null() {
return Err(());
}
}
maybe_wrap_object(*cx, desired_proto);
return Ok(());
}
}

View file

@ -20,7 +20,7 @@ use dom_struct::dom_struct;
use js::conversions::ToJSValConvertible;
use js::jsapi::{Heap, JSObject};
use js::jsval::UndefinedValue;
use js::rust::{HandleValue, MutableHandleObject};
use js::rust::{HandleObject, HandleValue, MutableHandleObject};
use std::cell::Cell;
use std::ptr;
use std::ptr::NonNull;
@ -118,7 +118,12 @@ impl<T: DomObjectIteratorWrap + JSTraceable + Iterable> IterableIterator<T> {
}
impl<T: DomObjectIteratorWrap + JSTraceable + Iterable> DomObjectWrap for IterableIterator<T> {
const WRAP: unsafe fn(JSContext, &GlobalScope, Box<Self>) -> Root<Dom<Self>> = T::ITER_WRAP;
const WRAP: unsafe fn(
JSContext,
&GlobalScope,
Option<HandleObject>,
Box<Self>,
) -> Root<Dom<Self>> = T::ITER_WRAP;
}
fn dict_return(

View file

@ -23,7 +23,20 @@ where
U: DerivedFrom<GlobalScope>,
{
let global_scope = global.upcast();
unsafe { T::WRAP(GlobalScope::get_cx(), global_scope, obj) }
unsafe { T::WRAP(GlobalScope::get_cx(), global_scope, None, obj) }
}
pub fn reflect_dom_object_with_proto<T, U>(
obj: Box<T>,
global: &U,
proto: Option<HandleObject>,
) -> DomRoot<T>
where
T: DomObject + DomObjectWrap,
U: DerivedFrom<GlobalScope>,
{
let global_scope = global.upcast();
unsafe { T::WRAP(GlobalScope::get_cx(), global_scope, proto, obj) }
}
/// A struct to store a reference to the reflector of a DOM object.
@ -109,7 +122,12 @@ impl MutDomObject for Reflector {
/// A trait to provide a function pointer to wrap function for DOM objects.
pub trait DomObjectWrap: Sized + DomObject {
/// Function pointer to the general wrap function type
const WRAP: unsafe fn(JSContext, &GlobalScope, Box<Self>) -> Root<Dom<Self>>;
const WRAP: unsafe fn(
JSContext,
&GlobalScope,
Option<HandleObject>,
Box<Self>,
) -> Root<Dom<Self>>;
}
/// A trait to provide a function pointer to wrap function for
@ -119,6 +137,7 @@ pub trait DomObjectIteratorWrap: DomObjectWrap + JSTraceable + Iterable {
const ITER_WRAP: unsafe fn(
JSContext,
&GlobalScope,
Option<HandleObject>,
Box<IterableIterator<Self>>,
) -> Root<Dom<IterableIterator<Self>>>;
}

View file

@ -99,6 +99,9 @@ pub struct DOMClass {
/// derivedness.
pub interface_chain: [PrototypeList::ID; MAX_PROTO_CHAIN_LENGTH],
/// The last valid index of `interface_chain`.
pub depth: u8,
/// The type ID of that interface.
pub type_id: TopTypeId,
@ -112,6 +115,7 @@ unsafe impl Sync for DOMClass {}
/// The JSClass used for DOM object reflectors.
#[derive(Copy)]
#[repr(C)]
pub struct DOMJSClass {
/// The actual JSClass.
pub base: js::jsapi::JSClass,
@ -633,3 +637,7 @@ impl AsCCharPtrPtr for [u8] {
self as *const [u8] as *const c_char
}
}
pub unsafe fn callargs_is_constructing(args: &CallArgs) -> bool {
(*args.argv_.offset(-1)).is_magic()
}

View file

@ -13,10 +13,11 @@ use crate::dom::bindings::codegen::Bindings::BiquadFilterNodeBinding::BiquadFilt
use crate::dom::bindings::codegen::Bindings::BiquadFilterNodeBinding::BiquadFilterOptions;
use crate::dom::bindings::codegen::Bindings::BiquadFilterNodeBinding::BiquadFilterType;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_media::audio::biquad_filter_node::BiquadFilterNodeMessage;
use servo_media::audio::biquad_filter_node::{BiquadFilterNodeOptions, FilterType};
use servo_media::audio::node::{AudioNodeInit, AudioNodeMessage};
@ -104,23 +105,33 @@ impl BiquadFilterNode {
})
}
#[allow(unrooted_must_root)]
pub fn new(
window: &Window,
context: &BaseAudioContext,
options: &BiquadFilterOptions,
) -> Fallible<DomRoot<BiquadFilterNode>> {
Self::new_with_proto(window, None, context, options)
}
#[allow(unrooted_must_root)]
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &BiquadFilterOptions,
) -> Fallible<DomRoot<BiquadFilterNode>> {
let node = BiquadFilterNode::new_inherited(window, context, options)?;
Ok(reflect_dom_object(Box::new(node), window))
Ok(reflect_dom_object_with_proto(Box::new(node), window, proto))
}
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &BiquadFilterOptions,
) -> Fallible<DomRoot<BiquadFilterNode>> {
BiquadFilterNode::new(window, context, options)
BiquadFilterNode::new_with_proto(window, proto, context, options)
}
}

View file

@ -7,7 +7,7 @@ use crate::dom::bindings::codegen::Bindings::BlobBinding;
use crate::dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
use crate::dom::bindings::codegen::UnionTypes::ArrayBufferOrArrayBufferViewOrBlobOrString;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::serializable::{Serializable, StorageKey};
use crate::dom::bindings::str::DOMString;
@ -20,6 +20,7 @@ use crate::script_runtime::JSContext;
use dom_struct::dom_struct;
use encoding_rs::UTF_8;
use js::jsapi::JSObject;
use js::rust::HandleObject;
use msg::constellation_msg::{BlobId, BlobIndex, PipelineNamespaceId};
use net_traits::filemanager_thread::RelativePos;
use script_traits::serializable::BlobImpl;
@ -38,7 +39,16 @@ pub struct Blob {
impl Blob {
pub fn new(global: &GlobalScope, blob_impl: BlobImpl) -> DomRoot<Blob> {
let dom_blob = reflect_dom_object(Box::new(Blob::new_inherited(&blob_impl)), global);
Self::new_with_proto(global, None, blob_impl)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
blob_impl: BlobImpl,
) -> DomRoot<Blob> {
let dom_blob =
reflect_dom_object_with_proto(Box::new(Blob::new_inherited(&blob_impl)), global, proto);
global.track_blob(&dom_blob, blob_impl);
dom_blob
}
@ -55,6 +65,7 @@ impl Blob {
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
blobParts: Option<Vec<ArrayBufferOrArrayBufferViewOrBlobOrString>>,
blobPropertyBag: &BlobBinding::BlobPropertyBag,
) -> Fallible<DomRoot<Blob>> {
@ -69,7 +80,7 @@ impl Blob {
let type_string = normalize_type_string(&blobPropertyBag.type_.to_string());
let blob_impl = BlobImpl::new_from_bytes(bytes, type_string);
Ok(Blob::new(global, blob_impl))
Ok(Blob::new_with_proto(global, proto, blob_impl))
}
/// Get a slice to inner data, this might incur synchronous read and caching

View file

@ -7,7 +7,7 @@ use crate::dom::bindings::codegen::Bindings::BluetoothAdvertisingEventBinding::B
use crate::dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::bluetoothdevice::BluetoothDevice;
@ -15,6 +15,7 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_atoms::Atom;
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothadvertisingevent
@ -47,8 +48,9 @@ impl BluetoothAdvertisingEvent {
}
}
pub fn new(
fn new(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: Atom,
bubbles: EventBubbles,
cancelable: EventCancelable,
@ -58,11 +60,12 @@ impl BluetoothAdvertisingEvent {
txPower: Option<i8>,
rssi: Option<i8>,
) -> DomRoot<BluetoothAdvertisingEvent> {
let ev = reflect_dom_object(
let ev = reflect_dom_object_with_proto(
Box::new(BluetoothAdvertisingEvent::new_inherited(
device, name, appearance, txPower, rssi,
)),
global,
proto,
);
{
let event = ev.upcast::<Event>();
@ -74,6 +77,7 @@ impl BluetoothAdvertisingEvent {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothadvertisingevent-bluetoothadvertisingevent
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
type_: DOMString,
init: &BluetoothAdvertisingEventInit,
) -> Fallible<DomRoot<BluetoothAdvertisingEvent>> {
@ -86,6 +90,7 @@ impl BluetoothAdvertisingEvent {
let cancelable = EventCancelable::from(init.parent.cancelable);
Ok(BluetoothAdvertisingEvent::new(
global,
proto,
Atom::from(type_),
bubbles,
cancelable,

View file

@ -4,7 +4,7 @@
use crate::dom::bindings::codegen::Bindings::BroadcastChannelBinding::BroadcastChannelMethods;
use crate::dom::bindings::error::{Error, ErrorResult};
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::structuredclone;
@ -12,7 +12,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::script_runtime::JSContext as SafeJSContext;
use dom_struct::dom_struct;
use js::rust::HandleValue;
use js::rust::{HandleObject, HandleValue};
use script_traits::BroadcastMsg;
use std::cell::Cell;
use uuid::Uuid;
@ -28,12 +28,24 @@ pub struct BroadcastChannel {
impl BroadcastChannel {
/// <https://html.spec.whatwg.org/multipage/#broadcastchannel>
#[allow(non_snake_case)]
pub fn Constructor(global: &GlobalScope, name: DOMString) -> DomRoot<BroadcastChannel> {
BroadcastChannel::new(global, name)
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
name: DOMString,
) -> DomRoot<BroadcastChannel> {
BroadcastChannel::new(global, proto, name)
}
pub fn new(global: &GlobalScope, name: DOMString) -> DomRoot<BroadcastChannel> {
let channel = reflect_dom_object(Box::new(BroadcastChannel::new_inherited(name)), global);
fn new(
global: &GlobalScope,
proto: Option<HandleObject>,
name: DOMString,
) -> DomRoot<BroadcastChannel> {
let channel = reflect_dom_object_with_proto(
Box::new(BroadcastChannel::new_inherited(name)),
global,
proto,
);
global.track_broadcast_channel(&*channel);
channel
}

View file

@ -9,10 +9,11 @@ use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
};
use crate::dom::bindings::codegen::Bindings::ChannelMergerNodeBinding::ChannelMergerOptions;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_media::audio::channel_node::ChannelNodeOptions;
use servo_media::audio::node::AudioNodeInit;
@ -52,23 +53,33 @@ impl ChannelMergerNode {
Ok(ChannelMergerNode { node })
}
#[allow(unrooted_must_root)]
pub fn new(
window: &Window,
context: &BaseAudioContext,
options: &ChannelMergerOptions,
) -> Fallible<DomRoot<ChannelMergerNode>> {
Self::new_with_proto(window, None, context, options)
}
#[allow(unrooted_must_root)]
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &ChannelMergerOptions,
) -> Fallible<DomRoot<ChannelMergerNode>> {
let node = ChannelMergerNode::new_inherited(window, context, options)?;
Ok(reflect_dom_object(Box::new(node), window))
Ok(reflect_dom_object_with_proto(Box::new(node), window, proto))
}
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &ChannelMergerOptions,
) -> Fallible<DomRoot<ChannelMergerNode>> {
ChannelMergerNode::new(window, context, options)
ChannelMergerNode::new_with_proto(window, proto, context, options)
}
}

View file

@ -9,10 +9,11 @@ use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
};
use crate::dom::bindings::codegen::Bindings::ChannelSplitterNodeBinding::ChannelSplitterOptions;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_media::audio::node::AudioNodeInit;
#[dom_struct]
@ -54,22 +55,32 @@ impl ChannelSplitterNode {
Ok(ChannelSplitterNode { node })
}
#[allow(unrooted_must_root)]
pub fn new(
window: &Window,
context: &BaseAudioContext,
options: &ChannelSplitterOptions,
) -> Fallible<DomRoot<ChannelSplitterNode>> {
Self::new_with_proto(window, None, context, options)
}
#[allow(unrooted_must_root)]
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &ChannelSplitterOptions,
) -> Fallible<DomRoot<ChannelSplitterNode>> {
let node = ChannelSplitterNode::new_inherited(window, context, options)?;
Ok(reflect_dom_object(Box::new(node), window))
Ok(reflect_dom_object_with_proto(Box::new(node), window, proto))
}
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &ChannelSplitterOptions,
) -> Fallible<DomRoot<ChannelSplitterNode>> {
ChannelSplitterNode::new(window, context, options)
ChannelSplitterNode::new_with_proto(window, proto, context, options)
}
}

View file

@ -43,7 +43,7 @@ impl CharacterData {
pub fn clone_with_data(&self, data: DOMString, document: &Document) -> DomRoot<Node> {
match self.upcast::<Node>().type_id() {
NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => {
DomRoot::upcast(Comment::new(data, &document))
DomRoot::upcast(Comment::new(data, &document, None))
},
NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) => {
let pi = self.downcast::<ProcessingInstruction>().unwrap();

View file

@ -7,12 +7,13 @@ use crate::dom::bindings::codegen::Bindings::CloseEventBinding::CloseEventMethod
use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_atoms::Atom;
#[dom_struct]
@ -42,9 +43,24 @@ impl CloseEvent {
wasClean: bool,
code: u16,
reason: DOMString,
) -> DomRoot<CloseEvent> {
Self::new_with_proto(
global, None, type_, bubbles, cancelable, wasClean, code, reason,
)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: Atom,
bubbles: EventBubbles,
cancelable: EventCancelable,
wasClean: bool,
code: u16,
reason: DOMString,
) -> DomRoot<CloseEvent> {
let event = Box::new(CloseEvent::new_inherited(wasClean, code, reason));
let ev = reflect_dom_object(event, global);
let ev = reflect_dom_object_with_proto(event, global, proto);
{
let event = ev.upcast::<Event>();
event.init_event(type_, bool::from(bubbles), bool::from(cancelable));
@ -54,13 +70,15 @@ impl CloseEvent {
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: DOMString,
init: &CloseEventBinding::CloseEventInit,
) -> Fallible<DomRoot<CloseEvent>> {
let bubbles = EventBubbles::from(init.parent.bubbles);
let cancelable = EventCancelable::from(init.parent.cancelable);
Ok(CloseEvent::new(
Ok(CloseEvent::new_with_proto(
global,
proto,
Atom::from(type_),
bubbles,
cancelable,

View file

@ -11,6 +11,7 @@ use crate::dom::document::Document;
use crate::dom::node::Node;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
/// An HTML comment.
#[dom_struct]
@ -25,13 +26,25 @@ impl Comment {
}
}
pub fn new(text: DOMString, document: &Document) -> DomRoot<Comment> {
Node::reflect_node(Box::new(Comment::new_inherited(text, document)), document)
pub fn new(
text: DOMString,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<Comment> {
Node::reflect_node_with_proto(
Box::new(Comment::new_inherited(text, document)),
document,
proto,
)
}
#[allow(non_snake_case)]
pub fn Constructor(window: &Window, data: DOMString) -> Fallible<DomRoot<Comment>> {
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
data: DOMString,
) -> Fallible<DomRoot<Comment>> {
let document = window.Document();
Ok(Comment::new(data, &document))
Ok(Comment::new(data, &document, proto))
}
}

View file

@ -7,12 +7,13 @@ use crate::dom::bindings::codegen::Bindings::CompositionEventBinding::{
};
use crate::dom::bindings::codegen::Bindings::UIEventBinding::UIEventBinding::UIEventMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::{reflect_dom_object, reflect_dom_object_with_proto};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::uievent::UIEvent;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
#[dom_struct]
pub struct CompositionEvent {
@ -41,12 +42,28 @@ impl CompositionEvent {
detail: i32,
data: DOMString,
) -> DomRoot<CompositionEvent> {
let ev = reflect_dom_object(
Self::new_with_proto(
window, None, type_, can_bubble, cancelable, view, detail, data,
)
}
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
type_: DOMString,
can_bubble: bool,
cancelable: bool,
view: Option<&Window>,
detail: i32,
data: DOMString,
) -> DomRoot<CompositionEvent> {
let ev = reflect_dom_object_with_proto(
Box::new(CompositionEvent {
uievent: UIEvent::new_inherited(),
data: data,
}),
window,
proto,
);
ev.uievent
.InitUIEvent(type_, can_bubble, cancelable, view, detail);
@ -56,11 +73,13 @@ impl CompositionEvent {
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
type_: DOMString,
init: &CompositionEventBinding::CompositionEventInit,
) -> Fallible<DomRoot<CompositionEvent>> {
let event = CompositionEvent::new(
let event = CompositionEvent::new_with_proto(
window,
proto,
type_,
init.parent.parent.bubbles,
init.parent.parent.cancelable,

View file

@ -9,10 +9,11 @@ use crate::dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate;
use crate::dom::bindings::codegen::Bindings::ConstantSourceNodeBinding::ConstantSourceNodeMethods;
use crate::dom::bindings::codegen::Bindings::ConstantSourceNodeBinding::ConstantSourceOptions;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_media::audio::constant_source_node::ConstantSourceNodeOptions as ServoMediaConstantSourceOptions;
use servo_media::audio::node::AudioNodeInit;
use servo_media::audio::param::ParamType;
@ -57,23 +58,33 @@ impl ConstantSourceNode {
})
}
#[allow(unrooted_must_root)]
pub fn new(
window: &Window,
context: &BaseAudioContext,
options: &ConstantSourceOptions,
) -> Fallible<DomRoot<ConstantSourceNode>> {
Self::new_with_proto(window, None, context, options)
}
#[allow(unrooted_must_root)]
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &ConstantSourceOptions,
) -> Fallible<DomRoot<ConstantSourceNode>> {
let node = ConstantSourceNode::new_inherited(window, context, options)?;
Ok(reflect_dom_object(Box::new(node), window))
Ok(reflect_dom_object_with_proto(Box::new(node), window, proto))
}
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &ConstantSourceOptions,
) -> Fallible<DomRoot<ConstantSourceNode>> {
ConstantSourceNode::new(window, context, options)
ConstantSourceNode::new_with_proto(window, proto, context, options)
}
}

View file

@ -85,28 +85,30 @@ use crate::dom::svgsvgelement::SVGSVGElement;
use crate::realms::{enter_realm, InRealm};
use crate::script_thread::ScriptThread;
use html5ever::{LocalName, Prefix, QualName};
use js::rust::HandleObject;
use servo_config::pref;
fn create_svg_element(
name: QualName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<Element> {
assert_eq!(name.ns, ns!(svg));
macro_rules! make(
($ctor:ident) => ({
let obj = $ctor::new(name.local, prefix, document);
let obj = $ctor::new(name.local, prefix, document, proto);
DomRoot::upcast(obj)
});
($ctor:ident, $($arg:expr),+) => ({
let obj = $ctor::new(name.local, prefix, document, $($arg),+);
let obj = $ctor::new(name.local, prefix, document, proto, $($arg),+);
DomRoot::upcast(obj)
})
);
if !pref!(dom.svg.enabled) {
return Element::new(name.local, name.ns, prefix, document);
return Element::new(name.local, name.ns, prefix, document, proto);
}
match name.local {
@ -124,6 +126,7 @@ fn create_html_element(
document: &Document,
creator: ElementCreator,
mode: CustomElementCreationMode,
proto: Option<HandleObject>,
) -> DomRoot<Element> {
assert_eq!(name.ns, ns!(html));
@ -138,6 +141,7 @@ fn create_html_element(
name.local.clone(),
prefix.clone(),
document,
proto,
));
result.set_custom_element_state(CustomElementState::Undefined);
ScriptThread::enqueue_upgrade_reaction(&*result, definition);
@ -145,6 +149,7 @@ fn create_html_element(
},
CustomElementCreationMode::Synchronous => {
let local_name = name.local.clone();
//TODO(jdm) Pass proto to create_element?
return match definition.create_element(document, prefix.clone()) {
Ok(element) => {
element.set_custom_element_definition(definition.clone());
@ -165,7 +170,7 @@ fn create_html_element(
// Step 6.1.2
let element = DomRoot::upcast::<Element>(HTMLUnknownElement::new(
local_name, prefix, document,
local_name, prefix, document, proto,
));
element.set_custom_element_state(CustomElementState::Failed);
element
@ -175,7 +180,7 @@ fn create_html_element(
}
} else {
// Steps 5.1-5.2
let element = create_native_html_element(name, prefix, document, creator);
let element = create_native_html_element(name, prefix, document, creator, proto);
element.set_is(definition.name.clone());
element.set_custom_element_state(CustomElementState::Undefined);
match mode {
@ -191,7 +196,7 @@ fn create_html_element(
}
// Steps 7.1-7.3
let result = create_native_html_element(name.clone(), prefix, document, creator);
let result = create_native_html_element(name.clone(), prefix, document, creator, proto);
match is {
Some(is) => {
result.set_is(is);
@ -215,16 +220,17 @@ pub fn create_native_html_element(
prefix: Option<Prefix>,
document: &Document,
creator: ElementCreator,
proto: Option<HandleObject>,
) -> DomRoot<Element> {
assert_eq!(name.ns, ns!(html));
macro_rules! make(
($ctor:ident) => ({
let obj = $ctor::new(name.local, prefix, document);
let obj = $ctor::new(name.local, prefix, document, proto);
DomRoot::upcast(obj)
});
($ctor:ident, $($arg:expr),+) => ({
let obj = $ctor::new(name.local, prefix, document, $($arg),+);
let obj = $ctor::new(name.local, prefix, document, proto, $($arg),+);
DomRoot::upcast(obj)
})
);
@ -386,11 +392,12 @@ pub fn create_element(
document: &Document,
creator: ElementCreator,
mode: CustomElementCreationMode,
proto: Option<HandleObject>,
) -> DomRoot<Element> {
let prefix = name.prefix.clone();
match name.ns {
ns!(html) => create_html_element(name, prefix, is, document, creator, mode),
ns!(svg) => create_svg_element(name, prefix, document),
_ => Element::new(name.local, name.ns, prefix, document),
ns!(html) => create_html_element(name, prefix, is, document, creator, mode, proto),
ns!(svg) => create_svg_element(name, prefix, document, proto),
_ => Element::new(name.local, name.ns, prefix, document, proto),
}
}

View file

@ -7,7 +7,7 @@ use crate::dom::bindings::codegen::Bindings::CustomEventBinding::CustomEventMeth
use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::trace::RootedTraceableBox;
@ -17,6 +17,7 @@ use crate::script_runtime::JSContext;
use dom_struct::dom_struct;
use js::jsapi::Heap;
use js::jsval::JSVal;
use js::rust::HandleObject;
use js::rust::HandleValue;
use servo_atoms::Atom;
@ -37,16 +38,25 @@ impl CustomEvent {
}
pub fn new_uninitialized(global: &GlobalScope) -> DomRoot<CustomEvent> {
reflect_dom_object(Box::new(CustomEvent::new_inherited()), global)
Self::new_uninitialized_with_proto(global, None)
}
pub fn new(
fn new_uninitialized_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
) -> DomRoot<CustomEvent> {
reflect_dom_object_with_proto(Box::new(CustomEvent::new_inherited()), global, proto)
}
fn new(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: Atom,
bubbles: bool,
cancelable: bool,
detail: HandleValue,
) -> DomRoot<CustomEvent> {
let ev = CustomEvent::new_uninitialized(global);
let ev = CustomEvent::new_uninitialized_with_proto(global, proto);
ev.init_custom_event(type_, bubbles, cancelable, detail);
ev
}
@ -54,11 +64,13 @@ impl CustomEvent {
#[allow(unsafe_code, non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: DOMString,
init: RootedTraceableBox<CustomEventBinding::CustomEventInit>,
) -> Fallible<DomRoot<CustomEvent>> {
Ok(CustomEvent::new(
global,
proto,
Atom::from(type_),
init.parent.bubbles,
init.parent.cancelable,

View file

@ -31,7 +31,7 @@ use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject};
use crate::dom::bindings::root::{Dom, DomRoot, DomSlice, LayoutDom, MutNullableDom};
use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::bindings::xmlname::XMLName::InvalidXMLName;
@ -123,6 +123,7 @@ use html5ever::{LocalName, Namespace, QualName};
use hyper_serde::Serde;
use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::JSObject;
use js::rust::HandleObject;
use keyboard_types::{Code, Key, KeyState};
use metrics::{
InteractiveFlag, InteractiveMetrics, InteractiveWindow, ProfilerMetadataFactory,
@ -3248,11 +3249,15 @@ impl Document {
// https://dom.spec.whatwg.org/#dom-document-document
#[allow(non_snake_case)]
pub fn Constructor(window: &Window) -> Fallible<DomRoot<Document>> {
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
) -> Fallible<DomRoot<Document>> {
let doc = window.Document();
let docloader = DocumentLoader::new(&*doc.loader());
Ok(Document::new(
Ok(Document::new_with_proto(
window,
proto,
HasBrowsingContext::No,
None,
doc.origin().clone(),
@ -3283,7 +3288,41 @@ impl Document {
referrer_policy: Option<ReferrerPolicy>,
canceller: FetchCanceller,
) -> DomRoot<Document> {
let document = reflect_dom_object(
Self::new_with_proto(
window,
None,
has_browsing_context,
url,
origin,
doctype,
content_type,
last_modified,
activity,
source,
doc_loader,
referrer,
referrer_policy,
canceller,
)
}
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
has_browsing_context: HasBrowsingContext,
url: Option<ServoUrl>,
origin: MutableOrigin,
doctype: IsHTMLDocument,
content_type: Option<Mime>,
last_modified: Option<String>,
activity: DocumentActivity,
source: DocumentSource,
doc_loader: DocumentLoader,
referrer: Option<String>,
referrer_policy: Option<ReferrerPolicy>,
canceller: FetchCanceller,
) -> DomRoot<Document> {
let document = reflect_dom_object_with_proto(
Box::new(Document::new_inherited(
window,
has_browsing_context,
@ -3300,6 +3339,7 @@ impl Document {
canceller,
)),
window,
proto,
);
{
let node = document.upcast::<Node>();
@ -4143,6 +4183,7 @@ impl DocumentMethods for Document {
self,
ElementCreator::ScriptCreated,
CustomElementCreationMode::Synchronous,
None,
))
}
@ -4167,6 +4208,7 @@ impl DocumentMethods for Document {
self,
ElementCreator::ScriptCreated,
CustomElementCreationMode::Synchronous,
None,
))
}
@ -4241,7 +4283,7 @@ impl DocumentMethods for Document {
// https://dom.spec.whatwg.org/#dom-document-createcomment
fn CreateComment(&self, data: DOMString) -> DomRoot<Comment> {
Comment::new(data, self)
Comment::new(data, self, None)
}
// https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction
@ -4361,7 +4403,7 @@ impl DocumentMethods for Document {
// https://dom.spec.whatwg.org/#dom-document-createrange
fn CreateRange(&self) -> DomRoot<Range> {
Range::new_with_doc(self)
Range::new_with_doc(self, None)
}
// https://dom.spec.whatwg.org/#dom-document-createnodeiteratorroot-whattoshow-filter
@ -4434,6 +4476,7 @@ impl DocumentMethods for Document {
self,
ElementCreator::ScriptCreated,
CustomElementCreationMode::Synchronous,
None,
);
let parent = root.upcast::<Node>();
let child = elem.upcast::<Node>();
@ -4458,6 +4501,7 @@ impl DocumentMethods for Document {
self,
ElementCreator::ScriptCreated,
CustomElementCreationMode::Synchronous,
None,
);
head.upcast::<Node>().AppendChild(elem.upcast()).unwrap()
},

View file

@ -17,6 +17,7 @@ use crate::dom::node::{window_from_node, Node};
use crate::dom::nodelist::NodeList;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_atoms::Atom;
use std::collections::HashMap;
@ -38,17 +39,28 @@ impl DocumentFragment {
}
pub fn new(document: &Document) -> DomRoot<DocumentFragment> {
Node::reflect_node(
Self::new_with_proto(document, None)
}
fn new_with_proto(
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<DocumentFragment> {
Node::reflect_node_with_proto(
Box::new(DocumentFragment::new_inherited(document)),
document,
proto,
)
}
#[allow(non_snake_case)]
pub fn Constructor(window: &Window) -> Fallible<DomRoot<DocumentFragment>> {
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
) -> Fallible<DomRoot<DocumentFragment>> {
let document = window.Document();
Ok(DocumentFragment::new(&document))
Ok(DocumentFragment::new_with_proto(&document, proto))
}
pub fn id_map(&self) -> &DomRefCell<HashMap<Atom, Vec<Dom<Element>>>> {

View file

@ -5,11 +5,14 @@
use crate::dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionConstants;
use crate::dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods;
use crate::dom::bindings::error::Error;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::reflector::{
reflect_dom_object, reflect_dom_object_with_proto, Reflector,
};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::rust::HandleObject;
#[repr(u16)]
#[derive(Clone, Copy, Debug, Eq, JSTraceable, MallocSizeOf, Ord, PartialEq, PartialOrd)]
@ -139,12 +142,14 @@ impl DOMException {
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
message: DOMString,
name: DOMString,
) -> Result<DomRoot<DOMException>, Error> {
Ok(reflect_dom_object(
Ok(reflect_dom_object_with_proto(
Box::new(DOMException::new_inherited(message, name)),
global,
proto,
))
}

View file

@ -167,14 +167,22 @@ impl DOMImplementationMethods for DOMImplementation {
{
// Step 4.
let doc_node = doc.upcast::<Node>();
let doc_html =
DomRoot::upcast::<Node>(HTMLHtmlElement::new(local_name!("html"), None, &doc));
let doc_html = DomRoot::upcast::<Node>(HTMLHtmlElement::new(
local_name!("html"),
None,
&doc,
None,
));
doc_node.AppendChild(&doc_html).expect("Appending failed");
{
// Step 5.
let doc_head =
DomRoot::upcast::<Node>(HTMLHeadElement::new(local_name!("head"), None, &doc));
let doc_head = DomRoot::upcast::<Node>(HTMLHeadElement::new(
local_name!("head"),
None,
&doc,
None,
));
doc_html.AppendChild(&doc_head).unwrap();
// Step 6.
@ -184,6 +192,7 @@ impl DOMImplementationMethods for DOMImplementation {
local_name!("title"),
None,
&doc,
None,
));
doc_head.AppendChild(&doc_title).unwrap();
@ -194,7 +203,7 @@ impl DOMImplementationMethods for DOMImplementation {
}
// Step 7.
let doc_body = HTMLBodyElement::new(local_name!("body"), None, &doc);
let doc_body = HTMLBodyElement::new(local_name!("body"), None, &doc, None);
doc_html.AppendChild(doc_body.upcast()).unwrap();
}

View file

@ -8,7 +8,7 @@ use crate::dom::bindings::codegen::UnionTypes::StringOrUnrestrictedDoubleSequenc
use crate::dom::bindings::error;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::dommatrixreadonly::{
dommatrixinit_to_matrix, entries_to_matrix, transform_to_matrix, DOMMatrixReadOnly,
@ -17,7 +17,7 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use euclid::default::Transform3D;
use js::rust::CustomAutoRooterGuard;
use js::rust::{CustomAutoRooterGuard, HandleObject};
use js::typedarray::{Float32Array, Float64Array};
#[dom_struct]
@ -27,10 +27,19 @@ pub struct DOMMatrix {
#[allow(non_snake_case)]
impl DOMMatrix {
#[allow(unrooted_must_root)]
pub fn new(global: &GlobalScope, is2D: bool, matrix: Transform3D<f64>) -> DomRoot<Self> {
Self::new_with_proto(global, None, is2D, matrix)
}
#[allow(unrooted_must_root)]
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
is2D: bool,
matrix: Transform3D<f64>,
) -> DomRoot<Self> {
let dommatrix = Self::new_inherited(is2D, matrix);
reflect_dom_object(Box::new(dommatrix), global)
reflect_dom_object_with_proto(Box::new(dommatrix), global, proto)
}
pub fn new_inherited(is2D: bool, matrix: Transform3D<f64>) -> Self {
@ -42,10 +51,16 @@ impl DOMMatrix {
// https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-dommatrixreadonly
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
init: Option<StringOrUnrestrictedDoubleSequence>,
) -> Fallible<DomRoot<Self>> {
if init.is_none() {
return Ok(Self::new(global, true, Transform3D::identity()));
return Ok(Self::new_with_proto(
global,
proto,
true,
Transform3D::identity(),
));
}
match init.unwrap() {
StringOrUnrestrictedDoubleSequence::String(ref s) => {
@ -58,11 +73,11 @@ impl DOMMatrix {
return Ok(Self::new(global, true, Transform3D::identity()));
}
transform_to_matrix(s.to_string())
.map(|(is2D, matrix)| Self::new(global, is2D, matrix))
.map(|(is2D, matrix)| Self::new_with_proto(global, proto, is2D, matrix))
},
StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(ref entries) => {
entries_to_matrix(&entries[..])
.map(|(is2D, matrix)| Self::new(global, is2D, matrix))
.map(|(is2D, matrix)| Self::new_with_proto(global, proto, is2D, matrix))
},
}
}
@ -84,6 +99,7 @@ impl DOMMatrix {
let vec: Vec<f64> = array.to_vec().iter().map(|&x| x as f64).collect();
DOMMatrix::Constructor(
global,
None,
Some(StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(vec)),
)
}
@ -96,6 +112,7 @@ impl DOMMatrix {
let vec: Vec<f64> = array.to_vec();
DOMMatrix::Constructor(
global,
None,
Some(StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(vec)),
)
}

View file

@ -10,7 +10,7 @@ use crate::dom::bindings::codegen::UnionTypes::StringOrUnrestrictedDoubleSequenc
use crate::dom::bindings::error;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::dommatrix::DOMMatrix;
use crate::dom::dompoint::DOMPoint;
@ -21,7 +21,7 @@ use cssparser::{Parser, ParserInput};
use dom_struct::dom_struct;
use euclid::{default::Transform3D, Angle};
use js::jsapi::JSObject;
use js::rust::CustomAutoRooterGuard;
use js::rust::{CustomAutoRooterGuard, HandleObject};
use js::typedarray::CreateWith;
use js::typedarray::{Float32Array, Float64Array};
use std::cell::Cell;
@ -40,10 +40,19 @@ pub struct DOMMatrixReadOnly {
#[allow(non_snake_case)]
impl DOMMatrixReadOnly {
#[allow(unrooted_must_root)]
pub fn new(global: &GlobalScope, is2D: bool, matrix: Transform3D<f64>) -> DomRoot<Self> {
Self::new_with_proto(global, None, is2D, matrix)
}
#[allow(unrooted_must_root)]
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
is2D: bool,
matrix: Transform3D<f64>,
) -> DomRoot<Self> {
let dommatrix = Self::new_inherited(is2D, matrix);
reflect_dom_object(Box::new(dommatrix), global)
reflect_dom_object_with_proto(Box::new(dommatrix), global, proto)
}
pub fn new_inherited(is2D: bool, matrix: Transform3D<f64>) -> Self {
@ -57,10 +66,16 @@ impl DOMMatrixReadOnly {
// https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-dommatrixreadonly
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
init: Option<StringOrUnrestrictedDoubleSequence>,
) -> Fallible<DomRoot<Self>> {
if init.is_none() {
return Ok(Self::new(global, true, Transform3D::identity()));
return Ok(Self::new_with_proto(
global,
proto,
true,
Transform3D::identity(),
));
}
match init.unwrap() {
StringOrUnrestrictedDoubleSequence::String(ref s) => {
@ -73,11 +88,11 @@ impl DOMMatrixReadOnly {
return Ok(Self::new(global, true, Transform3D::identity()));
}
transform_to_matrix(s.to_string())
.map(|(is2D, matrix)| Self::new(global, is2D, matrix))
.map(|(is2D, matrix)| Self::new_with_proto(global, proto, is2D, matrix))
},
StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(ref entries) => {
entries_to_matrix(&entries[..])
.map(|(is2D, matrix)| Self::new(global, is2D, matrix))
.map(|(is2D, matrix)| Self::new_with_proto(global, proto, is2D, matrix))
},
}
}
@ -392,6 +407,7 @@ impl DOMMatrixReadOnly {
let vec: Vec<f64> = array.to_vec().iter().map(|&x| x as f64).collect();
DOMMatrixReadOnly::Constructor(
global,
None,
Some(StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(vec)),
)
}
@ -405,6 +421,7 @@ impl DOMMatrixReadOnly {
let vec: Vec<f64> = array.to_vec();
DOMMatrixReadOnly::Constructor(
global,
None,
Some(StringOrUnrestrictedDoubleSequence::UnrestrictedDoubleSequence(vec)),
)
}

View file

@ -12,7 +12,7 @@ use crate::dom::bindings::codegen::Bindings::DOMParserBinding::SupportedType::Te
use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentReadyState;
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::document::DocumentSource;
@ -20,6 +20,7 @@ use crate::dom::document::{Document, HasBrowsingContext, IsHTMLDocument};
use crate::dom::servoparser::ServoParser;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use script_traits::DocumentActivity;
#[dom_struct]
@ -36,13 +37,16 @@ impl DOMParser {
}
}
pub fn new(window: &Window) -> DomRoot<DOMParser> {
reflect_dom_object(Box::new(DOMParser::new_inherited(window)), window)
fn new(window: &Window, proto: Option<HandleObject>) -> DomRoot<DOMParser> {
reflect_dom_object_with_proto(Box::new(DOMParser::new_inherited(window)), window, proto)
}
#[allow(non_snake_case)]
pub fn Constructor(window: &Window) -> Fallible<DomRoot<DOMParser>> {
Ok(DOMParser::new(window))
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
) -> Fallible<DomRoot<DOMParser>> {
Ok(DOMParser::new(window, proto))
}
}

View file

@ -5,11 +5,12 @@
use crate::dom::bindings::codegen::Bindings::DOMPointBinding::{DOMPointInit, DOMPointMethods};
use crate::dom::bindings::codegen::Bindings::DOMPointReadOnlyBinding::DOMPointReadOnlyMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::dompointreadonly::{DOMPointReadOnly, DOMPointWriteMethods};
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::rust::HandleObject;
// http://dev.w3.org/fxtf/geometry/Overview.html#dompoint
#[dom_struct]
@ -26,17 +27,29 @@ impl DOMPoint {
}
pub fn new(global: &GlobalScope, x: f64, y: f64, z: f64, w: f64) -> DomRoot<DOMPoint> {
reflect_dom_object(Box::new(DOMPoint::new_inherited(x, y, z, w)), global)
Self::new_with_proto(global, None, x, y, z, w)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
x: f64,
y: f64,
z: f64,
w: f64,
) -> DomRoot<DOMPoint> {
reflect_dom_object_with_proto(Box::new(DOMPoint::new_inherited(x, y, z, w)), global, proto)
}
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
x: f64,
y: f64,
z: f64,
w: f64,
) -> Fallible<DomRoot<DOMPoint>> {
Ok(DOMPoint::new(global, x, y, z, w))
Ok(DOMPoint::new_with_proto(global, proto, x, y, z, w))
}
// https://drafts.fxtf.org/geometry/#dom-dompoint-frompoint

View file

@ -5,10 +5,11 @@
use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit;
use crate::dom::bindings::codegen::Bindings::DOMPointReadOnlyBinding::DOMPointReadOnlyMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use std::cell::Cell;
// http://dev.w3.org/fxtf/geometry/Overview.html#dompointreadonly
@ -34,20 +35,33 @@ impl DOMPointReadOnly {
}
pub fn new(global: &GlobalScope, x: f64, y: f64, z: f64, w: f64) -> DomRoot<DOMPointReadOnly> {
reflect_dom_object(
Self::new_with_proto(global, None, x, y, z, w)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
x: f64,
y: f64,
z: f64,
w: f64,
) -> DomRoot<DOMPointReadOnly> {
reflect_dom_object_with_proto(
Box::new(DOMPointReadOnly::new_inherited(x, y, z, w)),
global,
proto,
)
}
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
x: f64,
y: f64,
z: f64,
w: f64,
) -> Fallible<DomRoot<DOMPointReadOnly>> {
Ok(DOMPointReadOnly::new(global, x, y, z, w))
Ok(DOMPointReadOnly::new_with_proto(global, proto, x, y, z, w))
}
// https://drafts.fxtf.org/geometry/#dom-dompointreadonly-frompoint

View file

@ -6,12 +6,13 @@ use crate::dom::bindings::codegen::Bindings::DOMPointBinding::{DOMPointInit, DOM
use crate::dom::bindings::codegen::Bindings::DOMQuadBinding::{DOMQuadInit, DOMQuadMethods};
use crate::dom::bindings::codegen::Bindings::DOMRectReadOnlyBinding::DOMRectInit;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::dompoint::DOMPoint;
use crate::dom::domrect::DOMRect;
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::rust::HandleObject;
// https://drafts.fxtf.org/geometry/#DOMQuad
#[dom_struct]
@ -42,18 +43,35 @@ impl DOMQuad {
p3: &DOMPoint,
p4: &DOMPoint,
) -> DomRoot<DOMQuad> {
reflect_dom_object(Box::new(DOMQuad::new_inherited(p1, p2, p3, p4)), global)
Self::new_with_proto(global, None, p1, p2, p3, p4)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
p1: &DOMPoint,
p2: &DOMPoint,
p3: &DOMPoint,
p4: &DOMPoint,
) -> DomRoot<DOMQuad> {
reflect_dom_object_with_proto(
Box::new(DOMQuad::new_inherited(p1, p2, p3, p4)),
global,
proto,
)
}
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
p1: &DOMPointInit,
p2: &DOMPointInit,
p3: &DOMPointInit,
p4: &DOMPointInit,
) -> Fallible<DomRoot<DOMQuad>> {
Ok(DOMQuad::new(
Ok(DOMQuad::new_with_proto(
global,
proto,
&*DOMPoint::new_from_init(global, p1),
&*DOMPoint::new_from_init(global, p2),
&*DOMPoint::new_from_init(global, p3),

View file

@ -5,11 +5,12 @@
use crate::dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods;
use crate::dom::bindings::codegen::Bindings::DOMRectReadOnlyBinding::DOMRectReadOnlyMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::domrectreadonly::DOMRectReadOnly;
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::rust::HandleObject;
#[dom_struct]
pub struct DOMRect {
@ -24,21 +25,34 @@ impl DOMRect {
}
pub fn new(global: &GlobalScope, x: f64, y: f64, width: f64, height: f64) -> DomRoot<DOMRect> {
reflect_dom_object(
Self::new_with_proto(global, None, x, y, width, height)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
x: f64,
y: f64,
width: f64,
height: f64,
) -> DomRoot<DOMRect> {
reflect_dom_object_with_proto(
Box::new(DOMRect::new_inherited(x, y, width, height)),
global,
proto,
)
}
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
x: f64,
y: f64,
width: f64,
height: f64,
) -> Fallible<DomRoot<DOMRect>> {
Ok(DOMRect::new(global, x, y, width, height))
Ok(DOMRect::new_with_proto(global, proto, x, y, width, height))
}
}

View file

@ -4,10 +4,11 @@
use crate::dom::bindings::codegen::Bindings::DOMRectReadOnlyBinding::DOMRectReadOnlyMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use std::cell::Cell;
#[dom_struct]
@ -30,28 +31,31 @@ impl DOMRectReadOnly {
}
}
pub fn new(
fn new(
global: &GlobalScope,
proto: Option<HandleObject>,
x: f64,
y: f64,
width: f64,
height: f64,
) -> DomRoot<DOMRectReadOnly> {
reflect_dom_object(
reflect_dom_object_with_proto(
Box::new(DOMRectReadOnly::new_inherited(x, y, width, height)),
global,
proto,
)
}
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
x: f64,
y: f64,
width: f64,
height: f64,
) -> Fallible<DomRoot<DOMRectReadOnly>> {
Ok(DOMRectReadOnly::new(global, x, y, width, height))
Ok(DOMRectReadOnly::new(global, proto, x, y, width, height))
}
pub fn set_x(&self, value: f64) {

View file

@ -95,6 +95,7 @@ use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode};
use html5ever::{LocalName, Namespace, Prefix, QualName};
use js::jsapi::Heap;
use js::jsval::JSVal;
use js::rust::HandleObject;
use msg::constellation_msg::InputMethodType;
use net_traits::request::CorsSettings;
use net_traits::ReferrerPolicy;
@ -241,8 +242,9 @@ impl Element {
document: &Document,
creator: ElementCreator,
mode: CustomElementCreationMode,
proto: Option<HandleObject>,
) -> DomRoot<Element> {
create_element(name, is, document, creator, mode)
create_element(name, is, document, creator, mode, proto)
}
pub fn new_inherited(
@ -290,12 +292,14 @@ impl Element {
namespace: Namespace,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<Element> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(Element::new_inherited(
local_name, namespace, prefix, document,
)),
document,
proto,
)
}
@ -1817,7 +1821,12 @@ impl Element {
{
DomRoot::from_ref(elem)
},
_ => DomRoot::upcast(HTMLBodyElement::new(local_name!("body"), None, owner_doc)),
_ => DomRoot::upcast(HTMLBodyElement::new(
local_name!("body"),
None,
owner_doc,
None,
)),
}
}
@ -2588,6 +2597,7 @@ impl ElementMethods for Element {
&context_document,
ElementCreator::ScriptCreated,
CustomElementCreationMode::Synchronous,
None,
);
DomRoot::upcast(body_elem)
},

View file

@ -8,7 +8,7 @@ use crate::dom::bindings::codegen::Bindings::ErrorEventBinding::ErrorEventMethod
use crate::dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::trace::RootedTraceableBox;
@ -18,7 +18,7 @@ use crate::script_runtime::JSContext;
use dom_struct::dom_struct;
use js::jsapi::Heap;
use js::jsval::JSVal;
use js::rust::HandleValue;
use js::rust::{HandleObject, HandleValue};
use servo_atoms::Atom;
use std::cell::Cell;
@ -45,8 +45,8 @@ impl ErrorEvent {
}
}
pub fn new_uninitialized(global: &GlobalScope) -> DomRoot<ErrorEvent> {
reflect_dom_object(Box::new(ErrorEvent::new_inherited()), global)
fn new_uninitialized(global: &GlobalScope, proto: Option<HandleObject>) -> DomRoot<ErrorEvent> {
reflect_dom_object_with_proto(Box::new(ErrorEvent::new_inherited()), global, proto)
}
pub fn new(
@ -60,7 +60,24 @@ impl ErrorEvent {
colno: u32,
error: HandleValue,
) -> DomRoot<ErrorEvent> {
let ev = ErrorEvent::new_uninitialized(global);
Self::new_with_proto(
global, None, type_, bubbles, cancelable, message, filename, lineno, colno, error,
)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: Atom,
bubbles: EventBubbles,
cancelable: EventCancelable,
message: DOMString,
filename: DOMString,
lineno: u32,
colno: u32,
error: HandleValue,
) -> DomRoot<ErrorEvent> {
let ev = ErrorEvent::new_uninitialized(global, proto);
{
let event = ev.upcast::<Event>();
event.init_event(type_, bool::from(bubbles), bool::from(cancelable));
@ -76,6 +93,7 @@ impl ErrorEvent {
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: DOMString,
init: RootedTraceableBox<ErrorEventBinding::ErrorEventInit>,
) -> Fallible<DomRoot<ErrorEvent>> {
@ -97,8 +115,9 @@ impl ErrorEvent {
let cancelable = EventCancelable::from(init.parent.cancelable);
let event = ErrorEvent::new(
let event = ErrorEvent::new_with_proto(
global,
proto,
Atom::from(type_),
bubbles,
cancelable,

View file

@ -12,7 +12,7 @@ use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector};
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
@ -28,6 +28,7 @@ use crate::dom::window::Window;
use crate::task::TaskOnce;
use devtools_traits::{TimelineMarker, TimelineMarkerType};
use dom_struct::dom_struct;
use js::rust::HandleObject;
use metrics::ToMs;
use servo_atoms::Atom;
use std::cell::Cell;
@ -72,7 +73,14 @@ impl Event {
}
pub fn new_uninitialized(global: &GlobalScope) -> DomRoot<Event> {
reflect_dom_object(Box::new(Event::new_inherited()), global)
Self::new_uninitialized_with_proto(global, None)
}
pub fn new_uninitialized_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
) -> DomRoot<Event> {
reflect_dom_object_with_proto(Box::new(Event::new_inherited()), global, proto)
}
pub fn new(
@ -81,7 +89,17 @@ impl Event {
bubbles: EventBubbles,
cancelable: EventCancelable,
) -> DomRoot<Event> {
let event = Event::new_uninitialized(global);
Self::new_with_proto(global, None, type_, bubbles, cancelable)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: Atom,
bubbles: EventBubbles,
cancelable: EventCancelable,
) -> DomRoot<Event> {
let event = Event::new_uninitialized_with_proto(global, proto);
event.init_event(type_, bool::from(bubbles), bool::from(cancelable));
event
}
@ -89,12 +107,19 @@ impl Event {
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: DOMString,
init: &EventBinding::EventInit,
) -> Fallible<DomRoot<Event>> {
let bubbles = EventBubbles::from(init.bubbles);
let cancelable = EventCancelable::from(init.cancelable);
Ok(Event::new(global, Atom::from(type_), bubbles, cancelable))
Ok(Event::new_with_proto(
global,
proto,
Atom::from(type_),
bubbles,
cancelable,
))
}
pub fn init_event(&self, type_: Atom, bubbles: bool, cancelable: bool) {

View file

@ -9,7 +9,7 @@ use crate::dom::bindings::codegen::Bindings::EventSourceBinding::{
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::event::Event;
@ -30,6 +30,7 @@ use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use js::conversions::ToJSValConvertible;
use js::jsval::UndefinedValue;
use js::rust::HandleObject;
use mime::{self, Mime};
use net_traits::request::{CacheMode, CorsSettings, Destination, RequestBuilder};
use net_traits::{CoreResourceMsg, FetchChannels, FetchMetadata, FilteredMetadata};
@ -459,10 +460,16 @@ impl EventSource {
}
}
fn new(global: &GlobalScope, url: ServoUrl, with_credentials: bool) -> DomRoot<EventSource> {
reflect_dom_object(
fn new(
global: &GlobalScope,
proto: Option<HandleObject>,
url: ServoUrl,
with_credentials: bool,
) -> DomRoot<EventSource> {
reflect_dom_object_with_proto(
Box::new(EventSource::new_inherited(url, with_credentials)),
global,
proto,
)
}
@ -501,6 +508,7 @@ impl EventSource {
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
url: DOMString,
event_source_init: &EventSourceInit,
) -> Fallible<DomRoot<EventSource>> {
@ -515,6 +523,7 @@ impl EventSource {
// Step 1, 5
let ev = EventSource::new(
global,
proto,
url_record.clone(),
event_source_init.withCredentials,
);

View file

@ -21,7 +21,7 @@ use crate::dom::bindings::codegen::UnionTypes::EventListenerOptionsOrBoolean;
use crate::dom::bindings::codegen::UnionTypes::EventOrString;
use crate::dom::bindings::error::{report_pending_exception, Error, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::element::Element;
@ -39,7 +39,7 @@ use fnv::FnvHasher;
use js::jsapi::JS_GetFunctionObject;
use js::rust::transform_u16_to_source_text;
use js::rust::wrappers::CompileFunction;
use js::rust::{CompileOptionsWrapper, RootedObjectVectorWrapper};
use js::rust::{CompileOptionsWrapper, HandleObject, RootedObjectVectorWrapper};
use libc::c_char;
use servo_atoms::Atom;
use servo_url::ServoUrl;
@ -355,13 +355,16 @@ impl EventTarget {
}
}
fn new(global: &GlobalScope) -> DomRoot<EventTarget> {
reflect_dom_object(Box::new(EventTarget::new_inherited()), global)
fn new(global: &GlobalScope, proto: Option<HandleObject>) -> DomRoot<EventTarget> {
reflect_dom_object_with_proto(Box::new(EventTarget::new_inherited()), global, proto)
}
#[allow(non_snake_case)]
pub fn Constructor(global: &GlobalScope) -> Fallible<DomRoot<EventTarget>> {
Ok(EventTarget::new(global))
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
) -> Fallible<DomRoot<EventTarget>> {
Ok(EventTarget::new(global, proto))
}
pub fn has_listeners_for(&self, type_: &Atom) -> bool {

View file

@ -6,14 +6,14 @@ use crate::dom::bindings::codegen::Bindings::EventBinding::{self, EventMethods};
use crate::dom::bindings::codegen::Bindings::ExtendableEventBinding;
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::event::Event;
use crate::dom::serviceworkerglobalscope::ServiceWorkerGlobalScope;
use crate::script_runtime::JSContext;
use dom_struct::dom_struct;
use js::rust::HandleValue;
use js::rust::{HandleObject, HandleValue};
use servo_atoms::Atom;
// https://w3c.github.io/ServiceWorker/#extendable-event
@ -31,13 +31,28 @@ impl ExtendableEvent {
extensions_allowed: true,
}
}
pub fn new(
worker: &ServiceWorkerGlobalScope,
type_: Atom,
bubbles: bool,
cancelable: bool,
) -> DomRoot<ExtendableEvent> {
let ev = reflect_dom_object(Box::new(ExtendableEvent::new_inherited()), worker);
Self::new_with_proto(worker, None, type_, bubbles, cancelable)
}
fn new_with_proto(
worker: &ServiceWorkerGlobalScope,
proto: Option<HandleObject>,
type_: Atom,
bubbles: bool,
cancelable: bool,
) -> DomRoot<ExtendableEvent> {
let ev = reflect_dom_object_with_proto(
Box::new(ExtendableEvent::new_inherited()),
worker,
proto,
);
{
let event = ev.upcast::<Event>();
event.init_event(type_, bubbles, cancelable);
@ -47,11 +62,13 @@ impl ExtendableEvent {
pub fn Constructor(
worker: &ServiceWorkerGlobalScope,
proto: Option<HandleObject>,
type_: DOMString,
init: &ExtendableEventBinding::ExtendableEventInit,
) -> Fallible<DomRoot<ExtendableEvent>> {
Ok(ExtendableEvent::new(
Ok(ExtendableEvent::new_with_proto(
worker,
proto,
Atom::from(type_),
init.parent.bubbles,
init.parent.cancelable,

View file

@ -7,7 +7,7 @@ use crate::dom::bindings::codegen::Bindings::ExtendableMessageEventBinding;
use crate::dom::bindings::codegen::Bindings::ExtendableMessageEventBinding::ExtendableMessageEventMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::trace::RootedTraceableBox;
@ -22,7 +22,7 @@ use crate::script_runtime::JSContext;
use dom_struct::dom_struct;
use js::jsapi::Heap;
use js::jsval::JSVal;
use js::rust::HandleValue;
use js::rust::{HandleObject, HandleValue};
use servo_atoms::Atom;
#[dom_struct]
@ -72,13 +72,37 @@ impl ExtendableMessageEvent {
origin: DOMString,
lastEventId: DOMString,
ports: Vec<DomRoot<MessagePort>>,
) -> DomRoot<ExtendableMessageEvent> {
Self::new_with_proto(
global,
None,
type_,
bubbles,
cancelable,
data,
origin,
lastEventId,
ports,
)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: Atom,
bubbles: bool,
cancelable: bool,
data: HandleValue,
origin: DOMString,
lastEventId: DOMString,
ports: Vec<DomRoot<MessagePort>>,
) -> DomRoot<ExtendableMessageEvent> {
let ev = Box::new(ExtendableMessageEvent::new_inherited(
origin,
lastEventId,
ports,
));
let ev = reflect_dom_object(ev, global);
let ev = reflect_dom_object_with_proto(ev, global, proto);
{
let event = ev.upcast::<Event>();
event.init_event(type_, bubbles, cancelable);
@ -90,12 +114,14 @@ impl ExtendableMessageEvent {
pub fn Constructor(
worker: &ServiceWorkerGlobalScope,
proto: Option<HandleObject>,
type_: DOMString,
init: RootedTraceableBox<ExtendableMessageEventBinding::ExtendableMessageEventInit>,
) -> Fallible<DomRoot<ExtendableMessageEvent>> {
let global = worker.upcast::<GlobalScope>();
let ev = ExtendableMessageEvent::new(
let ev = ExtendableMessageEvent::new_with_proto(
global,
proto,
Atom::from(type_),
init.parent.parent.bubbles,
init.parent.parent.cancelable,

View file

@ -7,13 +7,14 @@ use crate::dom::bindings::codegen::Bindings::FileBinding::FileMethods;
use crate::dom::bindings::codegen::UnionTypes::ArrayBufferOrArrayBufferViewOrBlobOrString;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::blob::{blob_parts_to_bytes, normalize_type_string, Blob};
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use net_traits::filemanager_thread::SelectedFile;
use script_traits::serializable::BlobImpl;
@ -41,16 +42,27 @@ impl File {
}
}
#[allow(unrooted_must_root)]
pub fn new(
global: &GlobalScope,
blob_impl: BlobImpl,
name: DOMString,
modified: Option<i64>,
) -> DomRoot<File> {
let file = reflect_dom_object(
Self::new_with_proto(global, None, blob_impl, name, modified)
}
#[allow(unrooted_must_root)]
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
blob_impl: BlobImpl,
name: DOMString,
modified: Option<i64>,
) -> DomRoot<File> {
let file = reflect_dom_object_with_proto(
Box::new(File::new_inherited(&blob_impl, name, modified)),
global,
proto,
);
global.track_file(&file, blob_impl);
file
@ -82,6 +94,7 @@ impl File {
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
fileBits: Vec<ArrayBufferOrArrayBufferViewOrBlobOrString>,
filename: DOMString,
filePropertyBag: &FileBinding::FilePropertyBag,
@ -98,8 +111,9 @@ impl File {
// see https://github.com/w3c/FileAPI/issues/41
let replaced_filename = DOMString::from_string(filename.replace("/", ":"));
let type_string = normalize_type_string(&blobPropertyBag.type_.to_string());
Ok(File::new(
Ok(File::new_with_proto(
global,
proto,
BlobImpl::new_from_bytes(bytes, type_string),
replaced_filename,
modified,

View file

@ -11,7 +11,7 @@ use crate::dom::bindings::codegen::UnionTypes::StringOrObject;
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject};
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::trace::RootedTraceableBox;
@ -31,6 +31,7 @@ use encoding_rs::{Encoding, UTF_8};
use js::jsapi::Heap;
use js::jsapi::JSObject;
use js::jsval::{self, JSVal};
use js::rust::HandleObject;
use js::typedarray::{ArrayBuffer, CreateWith};
use mime::{self, Mime};
use servo_atoms::Atom;
@ -151,13 +152,16 @@ impl FileReader {
}
}
pub fn new(global: &GlobalScope) -> DomRoot<FileReader> {
reflect_dom_object(Box::new(FileReader::new_inherited()), global)
fn new(global: &GlobalScope, proto: Option<HandleObject>) -> DomRoot<FileReader> {
reflect_dom_object_with_proto(Box::new(FileReader::new_inherited()), global, proto)
}
#[allow(non_snake_case)]
pub fn Constructor(global: &GlobalScope) -> Fallible<DomRoot<FileReader>> {
Ok(FileReader::new(global))
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
) -> Fallible<DomRoot<FileReader>> {
Ok(FileReader::new(global, proto))
}
//https://w3c.github.io/FileAPI/#dfn-error-steps

View file

@ -5,7 +5,7 @@
use crate::dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
use crate::dom::bindings::codegen::Bindings::FileReaderSyncBinding::FileReaderSyncMethods;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::blob::Blob;
@ -14,6 +14,7 @@ use crate::dom::globalscope::GlobalScope;
use crate::script_runtime::JSContext;
use dom_struct::dom_struct;
use js::jsapi::JSObject;
use js::rust::HandleObject;
use js::typedarray::{ArrayBuffer, CreateWith};
use std::ptr;
use std::ptr::NonNull;
@ -30,13 +31,16 @@ impl FileReaderSync {
}
}
pub fn new(global: &GlobalScope) -> DomRoot<FileReaderSync> {
reflect_dom_object(Box::new(FileReaderSync::new_inherited()), global)
fn new(global: &GlobalScope, proto: Option<HandleObject>) -> DomRoot<FileReaderSync> {
reflect_dom_object_with_proto(Box::new(FileReaderSync::new_inherited()), global, proto)
}
#[allow(non_snake_case)]
pub fn Constructor(global: &GlobalScope) -> Fallible<DomRoot<FileReaderSync>> {
Ok(FileReaderSync::new(global))
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
) -> Fallible<DomRoot<FileReaderSync>> {
Ok(FileReaderSync::new(global, proto))
}
fn get_blob_bytes(blob: &Blob) -> Result<Vec<u8>, Error> {

View file

@ -7,7 +7,7 @@ use crate::dom::bindings::codegen::Bindings::FocusEventBinding::FocusEventMethod
use crate::dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::event::{EventBubbles, EventCancelable};
@ -15,6 +15,7 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::uievent::UIEvent;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use std::default::Default;
#[dom_struct]
@ -32,7 +33,14 @@ impl FocusEvent {
}
pub fn new_uninitialized(window: &Window) -> DomRoot<FocusEvent> {
reflect_dom_object(Box::new(FocusEvent::new_inherited()), window)
Self::new_uninitialized_with_proto(window, None)
}
pub fn new_uninitialized_with_proto(
window: &Window,
proto: Option<HandleObject>,
) -> DomRoot<FocusEvent> {
reflect_dom_object_with_proto(Box::new(FocusEvent::new_inherited()), window, proto)
}
pub fn new(
@ -44,7 +52,29 @@ impl FocusEvent {
detail: i32,
related_target: Option<&EventTarget>,
) -> DomRoot<FocusEvent> {
let ev = FocusEvent::new_uninitialized(window);
Self::new_with_proto(
window,
None,
type_,
can_bubble,
cancelable,
view,
detail,
related_target,
)
}
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
type_: DOMString,
can_bubble: EventBubbles,
cancelable: EventCancelable,
view: Option<&Window>,
detail: i32,
related_target: Option<&EventTarget>,
) -> DomRoot<FocusEvent> {
let ev = FocusEvent::new_uninitialized_with_proto(window, proto);
ev.upcast::<UIEvent>().InitUIEvent(
type_,
bool::from(can_bubble),
@ -59,13 +89,15 @@ impl FocusEvent {
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
type_: DOMString,
init: &FocusEventBinding::FocusEventInit,
) -> Fallible<DomRoot<FocusEvent>> {
let bubbles = EventBubbles::from(init.parent.parent.bubbles);
let cancelable = EventCancelable::from(init.parent.parent.cancelable);
let event = FocusEvent::new(
let event = FocusEvent::new_with_proto(
window,
proto,
type_,
bubbles,
cancelable,

View file

@ -8,7 +8,7 @@ use crate::dom::bindings::codegen::UnionTypes::FileOrUSVString;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::iterable::Iterable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::blob::Blob;
@ -17,6 +17,7 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlformelement::{FormDatum, FormDatumValue, HTMLFormElement};
use dom_struct::dom_struct;
use html5ever::LocalName;
use js::rust::HandleObject;
use script_traits::serializable::BlobImpl;
#[dom_struct]
@ -42,23 +43,36 @@ impl FormData {
}
pub fn new(form_datums: Option<Vec<FormDatum>>, global: &GlobalScope) -> DomRoot<FormData> {
reflect_dom_object(Box::new(FormData::new_inherited(form_datums)), global)
Self::new_with_proto(form_datums, global, None)
}
fn new_with_proto(
form_datums: Option<Vec<FormDatum>>,
global: &GlobalScope,
proto: Option<HandleObject>,
) -> DomRoot<FormData> {
reflect_dom_object_with_proto(
Box::new(FormData::new_inherited(form_datums)),
global,
proto,
)
}
// https://xhr.spec.whatwg.org/#dom-formdata
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
form: Option<&HTMLFormElement>,
) -> Fallible<DomRoot<FormData>> {
if let Some(opt_form) = form {
return match opt_form.get_form_dataset(None, None) {
Some(form_datums) => Ok(FormData::new(Some(form_datums), global)),
Some(form_datums) => Ok(FormData::new_with_proto(Some(form_datums), global, proto)),
None => Err(Error::InvalidState),
};
}
Ok(FormData::new(None, global))
Ok(FormData::new_with_proto(None, global, proto))
}
}

View file

@ -7,7 +7,7 @@ use crate::dom::bindings::codegen::Bindings::FormDataEventBinding;
use crate::dom::bindings::codegen::Bindings::FormDataEventBinding::FormDataEventMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::event::Event;
@ -16,6 +16,7 @@ use crate::dom::formdata::FormData;
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_atoms::Atom;
#[dom_struct]
@ -32,12 +33,24 @@ impl FormDataEvent {
cancelable: EventCancelable,
form_data: &FormData,
) -> DomRoot<FormDataEvent> {
let ev = reflect_dom_object(
Self::new_with_proto(global, None, type_, can_bubble, cancelable, form_data)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: Atom,
can_bubble: EventBubbles,
cancelable: EventCancelable,
form_data: &FormData,
) -> DomRoot<FormDataEvent> {
let ev = reflect_dom_object_with_proto(
Box::new(FormDataEvent {
event: Event::new_inherited(),
form_data: Dom::from_ref(form_data),
}),
global,
proto,
);
{
@ -50,14 +63,16 @@ impl FormDataEvent {
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
type_: DOMString,
init: &FormDataEventBinding::FormDataEventInit,
) -> Fallible<DomRoot<FormDataEvent>> {
let bubbles = EventBubbles::from(init.parent.bubbles);
let cancelable = EventCancelable::from(init.parent.cancelable);
let event = FormDataEvent::new(
let event = FormDataEvent::new_with_proto(
&window.global(),
proto,
Atom::from(type_),
bubbles,
cancelable,

View file

@ -11,10 +11,11 @@ use crate::dom::bindings::codegen::Bindings::AudioNodeBinding::{
use crate::dom::bindings::codegen::Bindings::AudioParamBinding::AutomationRate;
use crate::dom::bindings::codegen::Bindings::GainNodeBinding::{GainNodeMethods, GainOptions};
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_media::audio::gain_node::GainNodeOptions;
use servo_media::audio::node::AudioNodeInit;
use servo_media::audio::param::ParamType;
@ -60,23 +61,33 @@ impl GainNode {
})
}
#[allow(unrooted_must_root)]
pub fn new(
window: &Window,
context: &BaseAudioContext,
options: &GainOptions,
) -> Fallible<DomRoot<GainNode>> {
Self::new_with_proto(window, None, context, options)
}
#[allow(unrooted_must_root)]
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &GainOptions,
) -> Fallible<DomRoot<GainNode>> {
let node = GainNode::new_inherited(window, context, options)?;
Ok(reflect_dom_object(Box::new(node), window))
Ok(reflect_dom_object_with_proto(Box::new(node), window, proto))
}
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
context: &BaseAudioContext,
options: &GainOptions,
) -> Fallible<DomRoot<GainNode>> {
GainNode::new(window, context, options)
GainNode::new_with_proto(window, proto, context, options)
}
}

View file

@ -7,7 +7,7 @@ use crate::dom::bindings::codegen::Bindings::GamepadEventBinding;
use crate::dom::bindings::codegen::Bindings::GamepadEventBinding::GamepadEventMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::event::Event;
@ -15,6 +15,7 @@ use crate::dom::gamepad::Gamepad;
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_atoms::Atom;
#[dom_struct]
@ -43,7 +44,22 @@ impl GamepadEvent {
cancelable: bool,
gamepad: &Gamepad,
) -> DomRoot<GamepadEvent> {
let ev = reflect_dom_object(Box::new(GamepadEvent::new_inherited(&gamepad)), global);
Self::new_with_proto(global, None, type_, bubbles, cancelable, gamepad)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: Atom,
bubbles: bool,
cancelable: bool,
gamepad: &Gamepad,
) -> DomRoot<GamepadEvent> {
let ev = reflect_dom_object_with_proto(
Box::new(GamepadEvent::new_inherited(&gamepad)),
global,
proto,
);
{
let event = ev.upcast::<Event>();
event.init_event(type_, bubbles, cancelable);
@ -68,11 +84,13 @@ impl GamepadEvent {
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
type_: DOMString,
init: &GamepadEventBinding::GamepadEventInit,
) -> Fallible<DomRoot<GamepadEvent>> {
Ok(GamepadEvent::new(
Ok(GamepadEvent::new_with_proto(
&window.global(),
proto,
Atom::from(type_),
init.parent.bubbles,
init.parent.cancelable,

View file

@ -2,10 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::rust::HandleObject;
#[dom_struct]
pub struct GPUOutOfMemoryError {
@ -20,12 +21,20 @@ impl GPUOutOfMemoryError {
}
pub fn new(global: &GlobalScope) -> DomRoot<Self> {
reflect_dom_object(Box::new(GPUOutOfMemoryError::new_inherited()), global)
Self::new_with_proto(global, None)
}
fn new_with_proto(global: &GlobalScope, proto: Option<HandleObject>) -> DomRoot<Self> {
reflect_dom_object_with_proto(
Box::new(GPUOutOfMemoryError::new_inherited()),
global,
proto,
)
}
/// https://gpuweb.github.io/gpuweb/#dom-gpuoutofmemoryerror-gpuoutofmemoryerror
#[allow(non_snake_case)]
pub fn Constructor(global: &GlobalScope) -> DomRoot<Self> {
GPUOutOfMemoryError::new(global)
pub fn Constructor(global: &GlobalScope, proto: Option<HandleObject>) -> DomRoot<Self> {
GPUOutOfMemoryError::new_with_proto(global, proto)
}
}

View file

@ -7,12 +7,13 @@ use crate::dom::bindings::codegen::Bindings::GPUUncapturedErrorEventBinding::{
GPUUncapturedErrorEventInit, GPUUncapturedErrorEventMethods,
};
use crate::dom::bindings::codegen::Bindings::GPUValidationErrorBinding::GPUError;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::event::Event;
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_atoms::Atom;
#[dom_struct]
@ -35,9 +36,19 @@ impl GPUUncapturedErrorEvent {
type_: DOMString,
init: &GPUUncapturedErrorEventInit,
) -> DomRoot<Self> {
let ev = reflect_dom_object(
Self::new_with_proto(global, None, type_, init)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: DOMString,
init: &GPUUncapturedErrorEventInit,
) -> DomRoot<Self> {
let ev = reflect_dom_object_with_proto(
Box::new(GPUUncapturedErrorEvent::new_inherited(init)),
global,
proto,
);
ev.event.init_event(
Atom::from(type_),
@ -51,10 +62,11 @@ impl GPUUncapturedErrorEvent {
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
type_: DOMString,
init: &GPUUncapturedErrorEventInit,
) -> DomRoot<Self> {
GPUUncapturedErrorEvent::new(global, type_, init)
GPUUncapturedErrorEvent::new_with_proto(global, proto, type_, init)
}
}

View file

@ -3,11 +3,12 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::codegen::Bindings::GPUValidationErrorBinding::GPUValidationErrorMethods;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::rust::HandleObject;
#[dom_struct]
pub struct GPUValidationError {
@ -24,13 +25,29 @@ impl GPUValidationError {
}
pub fn new(global: &GlobalScope, message: DOMString) -> DomRoot<Self> {
reflect_dom_object(Box::new(GPUValidationError::new_inherited(message)), global)
Self::new_with_proto(global, None, message)
}
fn new_with_proto(
global: &GlobalScope,
proto: Option<HandleObject>,
message: DOMString,
) -> DomRoot<Self> {
reflect_dom_object_with_proto(
Box::new(GPUValidationError::new_inherited(message)),
global,
proto,
)
}
/// https://gpuweb.github.io/gpuweb/#dom-gpuvalidationerror-gpuvalidationerror
#[allow(non_snake_case)]
pub fn Constructor(global: &GlobalScope, message: DOMString) -> DomRoot<Self> {
GPUValidationError::new(global, message)
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
message: DOMString,
) -> DomRoot<Self> {
GPUValidationError::new_with_proto(global, proto, message)
}
}

View file

@ -7,12 +7,13 @@ use crate::dom::bindings::codegen::Bindings::HashChangeEventBinding;
use crate::dom::bindings::codegen::Bindings::HashChangeEventBinding::HashChangeEventMethods;
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::event::Event;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::rust::HandleObject;
use servo_atoms::Atom;
// https://html.spec.whatwg.org/multipage/#hashchangeevent
@ -33,9 +34,17 @@ impl HashChangeEvent {
}
pub fn new_uninitialized(window: &Window) -> DomRoot<HashChangeEvent> {
reflect_dom_object(
Self::new_uninitialized_with_proto(window, None)
}
fn new_uninitialized_with_proto(
window: &Window,
proto: Option<HandleObject>,
) -> DomRoot<HashChangeEvent> {
reflect_dom_object_with_proto(
Box::new(HashChangeEvent::new_inherited(String::new(), String::new())),
window,
proto,
)
}
@ -47,9 +56,22 @@ impl HashChangeEvent {
old_url: String,
new_url: String,
) -> DomRoot<HashChangeEvent> {
let ev = reflect_dom_object(
Self::new_with_proto(window, None, type_, bubbles, cancelable, old_url, new_url)
}
fn new_with_proto(
window: &Window,
proto: Option<HandleObject>,
type_: Atom,
bubbles: bool,
cancelable: bool,
old_url: String,
new_url: String,
) -> DomRoot<HashChangeEvent> {
let ev = reflect_dom_object_with_proto(
Box::new(HashChangeEvent::new_inherited(old_url, new_url)),
window,
proto,
);
{
let event = ev.upcast::<Event>();
@ -61,11 +83,13 @@ impl HashChangeEvent {
#[allow(non_snake_case)]
pub fn Constructor(
window: &Window,
proto: Option<HandleObject>,
type_: DOMString,
init: &HashChangeEventBinding::HashChangeEventInit,
) -> Fallible<DomRoot<HashChangeEvent>> {
Ok(HashChangeEvent::new(
Ok(HashChangeEvent::new_with_proto(
window,
proto,
Atom::from(type_),
init.parent.bubbles,
init.parent.cancelable,

View file

@ -6,13 +6,14 @@ use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::HeadersBinding::{HeadersInit, HeadersMethods};
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::iterable::Iterable;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::{is_token, ByteString};
use crate::dom::globalscope::GlobalScope;
use data_url::mime::Mime as DataUrlMime;
use dom_struct::dom_struct;
use http::header::{HeaderMap as HyperHeaders, HeaderName, HeaderValue};
use js::rust::HandleObject;
use net_traits::{
fetch::headers::get_value_from_header_list, request::is_cors_safelisted_request_header,
};
@ -47,16 +48,21 @@ impl Headers {
}
pub fn new(global: &GlobalScope) -> DomRoot<Headers> {
reflect_dom_object(Box::new(Headers::new_inherited()), global)
Self::new_with_proto(global, None)
}
fn new_with_proto(global: &GlobalScope, proto: Option<HandleObject>) -> DomRoot<Headers> {
reflect_dom_object_with_proto(Box::new(Headers::new_inherited()), global, proto)
}
// https://fetch.spec.whatwg.org/#dom-headers
#[allow(non_snake_case)]
pub fn Constructor(
global: &GlobalScope,
proto: Option<HandleObject>,
init: Option<HeadersInit>,
) -> Fallible<DomRoot<Headers>> {
let dom_headers_new = Headers::new(global);
let dom_headers_new = Headers::new_with_proto(global, proto);
dom_headers_new.fill(init)?;
Ok(dom_headers_new)
}

View file

@ -29,6 +29,7 @@ use crate::dom::virtualmethods::VirtualMethods;
use crate::task_source::TaskSource;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use net_traits::request::Referrer;
use num_traits::ToPrimitive;
use script_traits::{HistoryEntryReplacement, LoadData, LoadOrigin};
@ -62,12 +63,14 @@ impl HTMLAnchorElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLAnchorElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLAnchorElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}

View file

@ -19,6 +19,7 @@ use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use euclid::default::Point2D;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use servo_atoms::Atom;
use std::default::Default;
use std::f32;
@ -253,10 +254,12 @@ impl HTMLAreaElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLAreaElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLAreaElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}

View file

@ -15,6 +15,7 @@ use crate::dom::node::Node;
use crate::dom::window::Window;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix, QualName};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLAudioElement {
@ -37,24 +38,31 @@ impl HTMLAudioElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLAudioElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLAudioElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
// https://html.spec.whatwg.org/multipage/#dom-audio
#[allow(non_snake_case)]
pub fn Audio(window: &Window, src: Option<DOMString>) -> Fallible<DomRoot<HTMLAudioElement>> {
pub fn Audio(
window: &Window,
proto: Option<HandleObject>,
src: Option<DOMString>,
) -> Fallible<DomRoot<HTMLAudioElement>> {
let element = Element::create(
QualName::new(None, ns!(html), local_name!("audio")),
None,
&window.Document(),
ElementCreator::ScriptCreated,
CustomElementCreationMode::Synchronous,
proto,
);
let audio = DomRoot::downcast::<HTMLAudioElement>(element).unwrap();

View file

@ -14,6 +14,7 @@ use crate::dom::node::{document_from_node, BindContext, Node, UnbindContext};
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use servo_url::ServoUrl;
#[dom_struct]
@ -37,10 +38,12 @@ impl HTMLBaseElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLBaseElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLBaseElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}

View file

@ -18,6 +18,7 @@ use cssparser::RGBA;
use dom_struct::dom_struct;
use embedder_traits::EmbedderMsg;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use servo_url::ServoUrl;
use style::attr::AttrValue;
@ -46,10 +47,12 @@ impl HTMLBodyElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLBodyElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLBodyElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}

View file

@ -8,6 +8,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLBRElement {
@ -30,10 +31,12 @@ impl HTMLBRElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLBRElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLBRElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}
}

View file

@ -24,6 +24,7 @@ use crate::dom::validitystate::ValidityState;
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use std::cell::Cell;
use std::default::Default;
use style::element_state::ElementState;
@ -69,12 +70,14 @@ impl HTMLButtonElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLButtonElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLButtonElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}

View file

@ -41,7 +41,7 @@ use image::codecs::png::PngEncoder;
use image::{ColorType, ImageEncoder};
use ipc_channel::ipc::{self as ipcchan, IpcSharedMemory};
use js::error::throw_type_error;
use js::rust::HandleValue;
use js::rust::{HandleObject, HandleValue};
use profile_traits::ipc;
use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource};
use script_traits::ScriptMsg;
@ -84,12 +84,14 @@ impl HTMLCanvasElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLCanvasElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLCanvasElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}

View file

@ -10,6 +10,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLDataElement {
@ -32,10 +33,12 @@ impl HTMLDataElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLDataElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLDataElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}
}

View file

@ -13,6 +13,7 @@ use crate::dom::htmloptionelement::HTMLOptionElement;
use crate::dom::node::{window_from_node, Node};
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLDataListElement {
@ -35,12 +36,14 @@ impl HTMLDataListElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLDataListElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLDataListElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -16,6 +16,7 @@ use crate::dom::virtualmethods::VirtualMethods;
use crate::task_source::TaskSource;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use std::cell::Cell;
#[dom_struct]
@ -41,12 +42,14 @@ impl HTMLDetailsElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLDetailsElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLDetailsElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}

View file

@ -14,6 +14,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{window_from_node, Node};
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLDialogElement {
@ -38,12 +39,14 @@ impl HTMLDialogElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLDialogElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLDialogElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -8,6 +8,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLDirectoryElement {
@ -30,12 +31,14 @@ impl HTMLDirectoryElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLDirectoryElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLDirectoryElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -10,6 +10,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLDivElement {
@ -32,10 +33,12 @@ impl HTMLDivElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLDivElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLDivElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}
}

View file

@ -8,6 +8,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLDListElement {
@ -30,12 +31,14 @@ impl HTMLDListElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLDListElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLDListElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -36,6 +36,7 @@ use crate::dom::text::Text;
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use script_layout_interface::message::QueryMsg;
use std::collections::HashSet;
use std::default::Default;
@ -83,10 +84,12 @@ impl HTMLElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}
@ -487,7 +490,7 @@ impl HTMLElementMethods for HTMLElement {
text = String::new();
}
let br = HTMLBRElement::new(local_name!("br"), None, &document);
let br = HTMLBRElement::new(local_name!("br"), None, &document, None);
fragment.upcast::<Node>().AppendChild(&br.upcast()).unwrap();
},
_ => {

View file

@ -8,6 +8,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLEmbedElement {
@ -30,12 +31,14 @@ impl HTMLEmbedElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLEmbedElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLEmbedElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -19,6 +19,7 @@ use crate::dom::validitystate::ValidityState;
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use std::default::Default;
use style::element_state::ElementState;
@ -52,12 +53,14 @@ impl HTMLFieldSetElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLFieldSetElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLFieldSetElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -15,6 +15,7 @@ use crate::dom::virtualmethods::VirtualMethods;
use cssparser::RGBA;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use servo_atoms::Atom;
use style::attr::AttrValue;
use style::str::{read_numbers, HTML_SPACE_CHARACTERS};
@ -40,10 +41,12 @@ impl HTMLFontElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLFontElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLFontElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}
}

View file

@ -62,6 +62,7 @@ use encoding_rs::{Encoding, UTF_8};
use headers::{ContentType, HeaderMapExt};
use html5ever::{LocalName, Prefix};
use http::Method;
use js::rust::HandleObject;
use mime::{self, Mime};
use net_traits::http_percent_encode;
use net_traits::request::Referrer;
@ -120,10 +121,12 @@ impl HTMLFormElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLFormElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLFormElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}

View file

@ -8,6 +8,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLFrameElement {
@ -30,12 +31,14 @@ impl HTMLFrameElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLFrameElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLFrameElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -11,6 +11,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{document_from_node, Node};
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLFrameSetElement {
@ -33,12 +34,14 @@ impl HTMLFrameSetElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLFrameSetElement> {
let n = Node::reflect_node(
let n = Node::reflect_node_with_proto(
Box::new(HTMLFrameSetElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
);
n.upcast::<Node>().set_weird_parser_insertion_mode();
n

View file

@ -14,6 +14,7 @@ use crate::dom::userscripts::load_script;
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLHeadElement {
@ -36,10 +37,12 @@ impl HTMLHeadElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLHeadElement> {
let n = Node::reflect_node(
let n = Node::reflect_node_with_proto(
Box::new(HTMLHeadElement::new_inherited(local_name, prefix, document)),
document,
proto,
);
n.upcast::<Node>().set_weird_parser_insertion_mode();

View file

@ -8,6 +8,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[derive(JSTraceable, MallocSizeOf)]
pub enum HeadingLevel {
@ -43,13 +44,15 @@ impl HTMLHeadingElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
level: HeadingLevel,
) -> DomRoot<HTMLHeadingElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLHeadingElement::new_inherited(
local_name, prefix, document, level,
)),
document,
proto,
)
}
}

View file

@ -14,6 +14,7 @@ use crate::dom::virtualmethods::VirtualMethods;
use cssparser::RGBA;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
#[dom_struct]
@ -37,10 +38,12 @@ impl HTMLHRElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLHRElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLHRElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}
}

View file

@ -9,6 +9,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLHtmlElement {
@ -32,10 +33,12 @@ impl HTMLHtmlElement {
localName: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLHtmlElement> {
let n = Node::reflect_node(
let n = Node::reflect_node_with_proto(
Box::new(HTMLHtmlElement::new_inherited(localName, prefix, document)),
document,
proto,
);
n.upcast::<Node>().set_weird_parser_insertion_mode();

View file

@ -28,6 +28,7 @@ use crate::script_thread::ScriptThread;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use ipc_channel::ipc;
use js::rust::HandleObject;
use msg::constellation_msg::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId};
use profile_traits::ipc as ProfiledIpc;
use script_layout_interface::message::ReflowGoal;
@ -441,12 +442,14 @@ impl HTMLIFrameElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLIFrameElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLIFrameElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}

View file

@ -58,6 +58,7 @@ use ipc_channel::ipc;
use ipc_channel::ipc::IpcSender;
use ipc_channel::router::ROUTER;
use js::jsapi::JSAutoRealm;
use js::rust::HandleObject;
use mime::{self, Mime};
use msg::constellation_msg::PipelineId;
use net_traits::image::base::{Image, ImageMetadata};
@ -1246,17 +1247,20 @@ impl HTMLImageElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLImageElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLImageElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
pub fn Image(
window: &Window,
proto: Option<HandleObject>,
width: Option<u32>,
height: Option<u32>,
) -> Fallible<DomRoot<HTMLImageElement>> {
@ -1266,6 +1270,7 @@ impl HTMLImageElement {
&window.Document(),
ElementCreator::ScriptCreated,
CustomElementCreationMode::Synchronous,
proto,
);
let image = DomRoot::downcast::<HTMLImageElement>(element).unwrap();

View file

@ -330,12 +330,14 @@ impl HTMLInputElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLInputElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLInputElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}

View file

@ -22,6 +22,7 @@ use crate::dom::node::{Node, ShadowIncluding};
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use style::attr::AttrValue;
#[dom_struct]
@ -45,12 +46,14 @@ impl HTMLLabelElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLLabelElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLLabelElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -15,6 +15,7 @@ use crate::dom::node::{BindContext, Node, UnbindContext};
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLLegendElement {
@ -39,12 +40,14 @@ impl HTMLLegendElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLLegendElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLLegendElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -12,6 +12,7 @@ use crate::dom::node::Node;
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use style::attr::AttrValue;
#[dom_struct]
@ -35,10 +36,12 @@ impl HTMLLIElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLLIElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLLIElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}
}

View file

@ -29,6 +29,7 @@ use cssparser::{Parser as CssParser, ParserInput};
use dom_struct::dom_struct;
use embedder_traits::EmbedderMsg;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use net_traits::ReferrerPolicy;
use servo_arc::Arc;
use servo_atoms::Atom;
@ -94,13 +95,15 @@ impl HTMLLinkElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
creator: ElementCreator,
) -> DomRoot<HTMLLinkElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLLinkElement::new_inherited(
local_name, prefix, document, creator,
)),
document,
proto,
)
}

View file

@ -10,6 +10,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{Node, ShadowIncluding};
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLMapElement {
@ -32,10 +33,12 @@ impl HTMLMapElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLMapElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLMapElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}

View file

@ -1865,6 +1865,7 @@ impl HTMLMediaElement {
local_name!("script"),
None,
&document,
None,
ElementCreator::ScriptCreated,
);
let mut media_controls_script = resources::read_string(EmbedderResource::MediaControlsJS);
@ -1892,6 +1893,7 @@ impl HTMLMediaElement {
local_name!("script"),
None,
&document,
None,
ElementCreator::ScriptCreated,
);
style

View file

@ -9,6 +9,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLMenuElement {
@ -31,10 +32,12 @@ impl HTMLMenuElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLMenuElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLMenuElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}
}

View file

@ -21,6 +21,7 @@ use crate::dom::node::{
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use servo_arc::Arc;
use servo_config::pref;
use std::sync::atomic::AtomicBool;
@ -54,10 +55,12 @@ impl HTMLMetaElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLMetaElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLMetaElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}

View file

@ -11,6 +11,7 @@ use crate::dom::node::Node;
use crate::dom::nodelist::NodeList;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLMeterElement {
@ -35,12 +36,14 @@ impl HTMLMeterElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLMeterElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLMeterElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -8,6 +8,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLModElement {
@ -30,10 +31,12 @@ impl HTMLModElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLModElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLModElement::new_inherited(local_name, prefix, document)),
document,
proto,
)
}
}

View file

@ -18,6 +18,7 @@ use crate::dom::validitystate::ValidityState;
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use net_traits::image::base::Image;
use servo_arc::Arc;
use std::default::Default;
@ -50,12 +51,14 @@ impl HTMLObjectElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLObjectElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLObjectElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -8,6 +8,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
#[dom_struct]
pub struct HTMLOListElement {
@ -30,12 +31,14 @@ impl HTMLOListElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLOListElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLOListElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

View file

@ -14,6 +14,7 @@ use crate::dom::node::Node;
use crate::dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use style::element_state::ElementState;
#[dom_struct]
@ -42,12 +43,14 @@ impl HTMLOptGroupElement {
local_name: LocalName,
prefix: Option<Prefix>,
document: &Document,
proto: Option<HandleObject>,
) -> DomRoot<HTMLOptGroupElement> {
Node::reflect_node(
Node::reflect_node_with_proto(
Box::new(HTMLOptGroupElement::new_inherited(
local_name, prefix, document,
)),
document,
proto,
)
}
}

Some files were not shown because too many files have changed in this diff Show more