diff options
Diffstat (limited to 'components/script/dom')
47 files changed, 430 insertions, 206 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 5b3a3de2f18..e5a90633f01 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -1722,6 +1722,25 @@ class CGNamespace(CGWrapper): return CGNamespace(namespaces[0], inner, public=public) +def EventTargetEnum(desc): + protochain = desc.prototypeChain + if protochain[0] != "EventTarget" or desc.interface.getExtendedAttribute("Abstract"): + return "None" + + inner = "" + name = desc.interface.identifier.name + if desc.interface.getUserData("hasConcreteDescendant", False): + inner = "(::dom::%s::%sTypeId::%s)" % (name.lower(), name, name) + prev_proto = "" + for proto in reversed(protochain): + if prev_proto != "": + inner = "(::dom::%s::%sTypeId::%s%s)" % (proto.lower(), proto, prev_proto, inner) + prev_proto = proto + if inner == "": + return "None" + return "Some%s" % inner + + def DOMClass(descriptor): protoList = ['PrototypeList::ID::' + proto for proto in descriptor.prototypeChain] # Pad out the list to the right length with ID::Count so we @@ -1734,7 +1753,8 @@ def DOMClass(descriptor): DOMClass { interface_chain: [ %s ], native_hooks: &sNativePropertyHooks, -}""" % prototypeChainString + type_id: %s, +}""" % (prototypeChainString, EventTargetEnum(descriptor)) class CGDOMJSClass(CGThing): diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py index 1a88968619b..2573e96fc78 100644 --- a/components/script/dom/bindings/codegen/Configuration.py +++ b/components/script/dom/bindings/codegen/Configuration.py @@ -223,8 +223,9 @@ class Descriptor(DescriptorProvider): if m.isDeleter(): addIndexedOrNamedOperation('Deleter', m) - iface.setUserData('hasConcreteDescendant', True) iface = iface.parent + if iface: + iface.setUserData('hasConcreteDescendant', True) if self.proxy: iface = self.interface diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py index 09368e45aa7..90ec9e88921 100644 --- a/components/script/dom/bindings/codegen/parser/WebIDL.py +++ b/components/script/dom/bindings/codegen/parser/WebIDL.py @@ -1357,7 +1357,8 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins): identifier == "ChromeOnly" or identifier == "Unforgeable" or identifier == "UnsafeInPrerendering" or - identifier == "LegacyEventInit"): + identifier == "LegacyEventInit" or + identifier == "Abstract"): # Known extended attributes that do not take values if not attr.noArguments(): raise WebIDLError("[%s] must take no arguments" % identifier, diff --git a/components/script/dom/bindings/codegen/parser/abstract.patch b/components/script/dom/bindings/codegen/parser/abstract.patch new file mode 100644 index 00000000000..e971a97e443 --- /dev/null +++ b/components/script/dom/bindings/codegen/parser/abstract.patch @@ -0,0 +1,12 @@ +--- WebIDL.py ++++ WebIDL.py +@@ -1357,7 +1357,8 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins): + identifier == "ChromeOnly" or + identifier == "Unforgeable" or + identifier == "UnsafeInPrerendering" or +- identifier == "LegacyEventInit"): ++ identifier == "LegacyEventInit" or ++ identifier == "Abstract"): + # Known extended attributes that do not take values + if not attr.noArguments(): + raise WebIDLError("[%s] must take no arguments" % identifier, diff --git a/components/script/dom/bindings/codegen/parser/update.sh b/components/script/dom/bindings/codegen/parser/update.sh index 5dd513812e1..26f70aac6ae 100755 --- a/components/script/dom/bindings/codegen/parser/update.sh +++ b/components/script/dom/bindings/codegen/parser/update.sh @@ -1,3 +1,4 @@ wget https://mxr.mozilla.org/mozilla-central/source/dom/bindings/parser/WebIDL.py?raw=1 -O WebIDL.py patch < external.patch patch < module.patch +patch < abstract.patch diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index 35f7be92b94..7118bef0e68 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -645,7 +645,7 @@ pub unsafe fn native_from_reflector<T>(obj: *mut JSObject) -> *const T { } /// Get the `DOMClass` from `obj`, or `Err(())` if `obj` is not a DOM object. -unsafe fn get_dom_class(obj: *mut JSObject) -> Result<DOMClass, ()> { +pub unsafe fn get_dom_class(obj: *mut JSObject) -> Result<&'static DOMClass, ()> { use dom::bindings::utils::DOMJSClass; use js::glue::GetProxyHandlerExtra; @@ -653,12 +653,12 @@ unsafe fn get_dom_class(obj: *mut JSObject) -> Result<DOMClass, ()> { if is_dom_class(&*clasp) { debug!("plain old dom object"); let domjsclass: *const DOMJSClass = clasp as *const DOMJSClass; - return Ok((*domjsclass).dom_class); + return Ok(&(&*domjsclass).dom_class); } if is_dom_proxy(obj) { debug!("proxy dom object"); let dom_class: *const DOMClass = GetProxyHandlerExtra(obj) as *const DOMClass; - return Ok(*dom_class); + return Ok(&*dom_class); } debug!("not a dom object"); Err(()) diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index f968305e08b..3ff081521cc 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -38,7 +38,6 @@ pub enum GlobalRef<'a> { } /// A stack-based rooted reference to a global object. -#[no_move] pub enum GlobalRoot { /// A root for a `Window` object. Window(Root<window::Window>), @@ -230,6 +229,11 @@ impl GlobalField { } } +/// Returns the global object of the realm that the given DOM object's reflector was created in. +pub fn global_object_for_reflector<T: Reflectable>(reflector: &T) -> GlobalRoot { + global_object_for_js_object(*reflector.reflector().get_jsobject()) +} + /// Returns the global object of the realm that the given JS object was created in. #[allow(unrooted_must_root)] pub fn global_object_for_js_object(obj: *mut JSObject) -> GlobalRoot { diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index 5345d08ee9e..e50bf68e478 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -88,6 +88,12 @@ impl<T: Reflectable> JS<T> { } } +impl<T: Reflectable> JSTraceable for JS<T> { + fn trace(&self, trc: *mut JSTracer) { + trace_reflector(trc, "", unsafe { (**self.ptr).reflector() }); + } +} + /// An unrooted reference to a DOM object for use in layout. `Layout*Helpers` /// traits must be implemented on this. #[allow_unrooted_interior] @@ -148,13 +154,6 @@ impl LayoutJS<Node> { } } -impl<T: Reflectable> Reflectable for JS<T> { - fn reflector(&self) -> &Reflector { - unsafe { - (**self.ptr).reflector() - } - } -} /// A trait to be implemented for JS-managed types that can be stored in /// mutable member fields. diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index e514e180486..5a9aa5b2abb 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -88,12 +88,6 @@ pub trait JSTraceable { fn trace(&self, trc: *mut JSTracer); } -impl<T: Reflectable> JSTraceable for JS<T> { - fn trace(&self, trc: *mut JSTracer) { - trace_reflector(trc, "", self.reflector()); - } -} - no_jsmanaged_fields!(EncodingRef); no_jsmanaged_fields!(Reflector); @@ -455,19 +449,17 @@ impl<'a, T: JSTraceable> Drop for RootedTraceable<'a, T> { } } -/// A vector of items that are rooted for the lifetime -/// of this struct. -/// Must be a reflectable +/// A vector of items that are rooted for the lifetime of this struct. #[allow(unrooted_must_root)] #[no_move] #[derive(JSTraceable)] #[allow_unrooted_interior] -pub struct RootedVec<T: JSTraceable + Reflectable> { +pub struct RootedVec<T: JSTraceable> { v: Vec<T> } -impl<T: JSTraceable + Reflectable> RootedVec<T> { +impl<T: JSTraceable> RootedVec<T> { /// Create a vector of items of type T that is rooted for /// the lifetime of this struct pub fn new() -> RootedVec<T> { @@ -495,20 +487,20 @@ impl<T: JSTraceable + Reflectable> RootedVec<JS<T>> { } } -impl<T: JSTraceable + Reflectable> Drop for RootedVec<T> { +impl<T: JSTraceable> Drop for RootedVec<T> { fn drop(&mut self) { RootedTraceableSet::remove(self); } } -impl<T: JSTraceable + Reflectable> Deref for RootedVec<T> { +impl<T: JSTraceable> Deref for RootedVec<T> { type Target = Vec<T>; fn deref(&self) -> &Vec<T> { &self.v } } -impl<T: JSTraceable + Reflectable> DerefMut for RootedVec<T> { +impl<T: JSTraceable> DerefMut for RootedVec<T> { fn deref_mut(&mut self) -> &mut Vec<T> { &mut self.v } diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 08e8fde7225..be600d807d3 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -15,6 +15,7 @@ use dom::bindings::global::GlobalRef; use dom::bindings::js::Root; use dom::bindings::trace::trace_object; use dom::browsercontext; +use dom::eventtarget::EventTargetTypeId; use dom::window; use util::mem::HeapSizeOf; use util::str::DOMString; @@ -157,6 +158,9 @@ pub struct DOMClass { /// derivedness. pub interface_chain: [PrototypeList::ID; MAX_PROTO_CHAIN_LENGTH], + /// The EventTarget type, if this is derived from an EventTarget. + pub type_id: Option<EventTargetTypeId>, + /// The NativePropertyHooks for the interface associated with this class. pub native_hooks: &'static NativePropertyHooks, } diff --git a/components/script/dom/characterdata.rs b/components/script/dom/characterdata.rs index 3efcd7c16c2..36503f8c041 100644 --- a/components/script/dom/characterdata.rs +++ b/components/script/dom/characterdata.rs @@ -158,7 +158,7 @@ impl CharacterDataMethods for CharacterData { } /// The different types of CharacterData. -#[derive(JSTraceable, Copy, Clone, PartialEq, Debug, HeapSizeOf)] +#[derive(Copy, Clone, PartialEq, Debug)] pub enum CharacterDataTypeId { Comment, Text, diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs index 9b226c73e33..55bef524640 100644 --- a/components/script/dom/create.rs +++ b/components/script/dom/create.rs @@ -116,9 +116,13 @@ pub fn create_element(name: QualName, prefix: Option<Atom>, atom!("base") => make!(HTMLBaseElement), atom!("bdi") => make!(HTMLElement), atom!("bdo") => make!(HTMLElement), - atom!("bgsound") => make!(HTMLElement), + // https://html.spec.whatwg.org/multipage/#other-elements,-attributes-and-apis:bgsound + atom!("bgsound") => make!(HTMLUnknownElement), atom!("big") => make!(HTMLElement), - atom!("blockquote") => make!(HTMLElement), + // https://html.spec.whatwg.org/multipage/#other-elements,-attributes-and-apis:blink + atom!("blink") => make!(HTMLUnknownElement), + // https://html.spec.whatwg.org/multipage/#the-blockquote-element + atom!("blockquote") => make!(HTMLQuoteElement), atom!("body") => make!(HTMLBodyElement), atom!("br") => make!(HTMLBRElement), atom!("button") => make!(HTMLButtonElement), @@ -166,7 +170,8 @@ pub fn create_element(name: QualName, prefix: Option<Atom>, atom!("img") => make!(HTMLImageElement), atom!("input") => make!(HTMLInputElement), atom!("ins") => make!(HTMLModElement), - atom!("isindex") => make!(HTMLElement), + // https://html.spec.whatwg.org/multipage/#other-elements,-attributes-and-apis:isindex-2 + atom!("isindex") => make!(HTMLUnknownElement), atom!("kbd") => make!(HTMLElement), atom!("label") => make!(HTMLLabelElement), atom!("legend") => make!(HTMLLegendElement), @@ -178,7 +183,11 @@ pub fn create_element(name: QualName, prefix: Option<Atom>, atom!("marquee") => make!(HTMLElement), atom!("meta") => make!(HTMLMetaElement), atom!("meter") => make!(HTMLMeterElement), + // https://html.spec.whatwg.org/multipage/#other-elements,-attributes-and-apis:multicol + atom!("multicol") => make!(HTMLUnknownElement), atom!("nav") => make!(HTMLElement), + // https://html.spec.whatwg.org/multipage/#other-elements,-attributes-and-apis:nextid + atom!("nextid") => make!(HTMLUnknownElement), atom!("nobr") => make!(HTMLElement), atom!("noframes") => make!(HTMLElement), atom!("noscript") => make!(HTMLElement), @@ -202,7 +211,8 @@ pub fn create_element(name: QualName, prefix: Option<Atom>, atom!("select") => make!(HTMLSelectElement), atom!("small") => make!(HTMLElement), atom!("source") => make!(HTMLSourceElement), - atom!("spacer") => make!(HTMLElement), + // https://html.spec.whatwg.org/multipage/#other-elements,-attributes-and-apis:spacer + atom!("spacer") => make!(HTMLUnknownElement), atom!("span") => make!(HTMLSpanElement), atom!("strike") => make!(HTMLElement), atom!("strong") => make!(HTMLElement), diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index a3c033e56a6..9ced7221078 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -163,8 +163,7 @@ impl DedicatedWorkerGlobalScope { -> DedicatedWorkerGlobalScope { DedicatedWorkerGlobalScope { workerglobalscope: WorkerGlobalScope::new_inherited( - WorkerGlobalScopeTypeId::DedicatedGlobalScope, init, worker_url, - runtime, from_devtools_receiver), + init, worker_url, runtime, from_devtools_receiver), id: id, receiver: receiver, own_sender: own_sender, @@ -364,7 +363,7 @@ impl DedicatedWorkerGlobalScopeMethods for DedicatedWorkerGlobalScope { impl DedicatedWorkerGlobalScopeDerived for EventTarget { fn is_dedicatedworkerglobalscope(&self) -> bool { match *self.type_id() { - EventTargetTypeId::WorkerGlobalScope(WorkerGlobalScopeTypeId::DedicatedGlobalScope) => true, + EventTargetTypeId::WorkerGlobalScope(WorkerGlobalScopeTypeId::DedicatedWorkerGlobalScope) => true, _ => false } } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 74528cac9df..de4f6a8423e 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -798,12 +798,19 @@ impl Document { match key { Key::Space if !prevented && state == KeyState::Released => { let maybe_elem: Option<&Element> = ElementCast::to_ref(target); - maybe_elem.map( - |el| el.as_maybe_activatable().map(|a| a.synthetic_click_activation(ctrl, alt, shift, meta))); + if let Some(el) = maybe_elem { + if let Some(a) = el.as_maybe_activatable() { + a.synthetic_click_activation(ctrl, alt, shift, meta); + } + } } Key::Enter if !prevented && state == KeyState::Released => { let maybe_elem: Option<&Element> = ElementCast::to_ref(target); - maybe_elem.map(|el| el.as_maybe_activatable().map(|a| a.implicit_submission(ctrl, alt, shift, meta))); + if let Some(el) = maybe_elem { + if let Some(a) = el.as_maybe_activatable() { + a.implicit_submission(ctrl, alt, shift, meta); + } + } } _ => () } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 27e8e9c7b7e..2cd65557bee 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -62,7 +62,7 @@ use devtools_traits::AttrInfo; use smallvec::VecLike; use style::legacy::{UnsignedIntegerAttribute, from_declaration}; use style::properties::DeclaredValue; -use style::properties::longhands::{self, background_image, border_spacing}; +use style::properties::longhands::{self, background_image, border_spacing, font_family}; use style::properties::{PropertyDeclarationBlock, PropertyDeclaration, parse_style_attribute}; use style::values::CSSFloat; use style::values::specified::{self, CSSColor, CSSRGBA}; @@ -116,7 +116,7 @@ impl PartialEq for Element { } } -#[derive(JSTraceable, Copy, Clone, PartialEq, Debug, HeapSizeOf)] +#[derive(Copy, Clone, PartialEq, Debug)] pub enum ElementTypeId { HTMLElement(HTMLElementTypeId), Element, @@ -302,6 +302,22 @@ impl RawLayoutElementHelpers for Element { })))); } + let font_family = if self.is_htmlfontelement() { + let this: &HTMLFontElement = mem::transmute(self); + this.get_face() + } else { + None + }; + + if let Some(font_family) = font_family { + hints.push(from_declaration( + PropertyDeclaration::FontFamily( + DeclaredValue::Value( + font_family::computed_value::T(vec![ + font_family::computed_value::FontFamily::FamilyName( + font_family)]))))); + } + let cellspacing = if self.is_htmltableelement() { let this: &HTMLTableElement = mem::transmute(self); this.get_cellspacing() @@ -634,7 +650,7 @@ impl Element { if let &mut Some(ref mut declarations) = &mut *inline_declarations { let index = declarations.normal .iter() - .position(|decl| decl.name() == property); + .position(|decl| decl.matches(property)); if let Some(index) = index { Arc::make_mut(&mut declarations.normal).remove(index); return; @@ -642,7 +658,7 @@ impl Element { let index = declarations.important .iter() - .position(|decl| decl.name() == property); + .position(|decl| decl.matches(property)); if let Some(index) = index { Arc::make_mut(&mut declarations.important).remove(index); return; @@ -699,7 +715,8 @@ impl Element { let to = Arc::make_mut(to); let mut new_from = Vec::new(); for declaration in from.drain(..) { - if properties.contains(&declaration.name()) { + let name = declaration.name(); + if properties.iter().any(|p| name == **p) { to.push(declaration) } else { new_from.push(declaration) diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index d45407a51fe..2cec78b48cc 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -19,7 +19,7 @@ use std::default::Default; use time; -#[derive(JSTraceable, Copy, Clone)] +#[derive(JSTraceable, Copy, Clone, Debug, PartialEq, Eq)] #[repr(u16)] #[derive(HeapSizeOf)] pub enum EventPhase { @@ -137,6 +137,11 @@ impl Event { } #[inline] + pub fn phase(&self) -> EventPhase { + self.phase.get() + } + + #[inline] pub fn set_phase(&self, val: EventPhase) { self.phase.set(val) } diff --git a/components/script/dom/eventdispatcher.rs b/components/script/dom/eventdispatcher.rs index 7ea4a706fea..f8cb7652529 100644 --- a/components/script/dom/eventdispatcher.rs +++ b/components/script/dom/eventdispatcher.rs @@ -5,108 +5,158 @@ use dom::bindings::callback::ExceptionHandling::Report; use dom::bindings::codegen::Bindings::EventBinding::EventMethods; use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast}; -use dom::bindings::js::JS; +use dom::bindings::global::{GlobalRoot, global_object_for_reflector}; +use dom::bindings::js::{JS, Root, RootedReference}; use dom::bindings::trace::RootedVec; use dom::event::{Event, EventPhase}; -use dom::eventtarget::{EventTarget, ListenerPhase}; +use dom::eventtarget::{EventTarget, ListenerPhase, EventListenerType}; use dom::node::Node; use dom::virtualmethods::vtable_for; +use dom::window::Window; -// See https://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm -pub fn dispatch_event(target: &EventTarget, pseudo_target: Option<&EventTarget>, - event: &Event) -> bool { - assert!(!event.dispatching()); - assert!(event.initialized()); - - event.set_target(match pseudo_target { - Some(pseudo_target) => pseudo_target, - None => target.clone(), - }); - event.set_dispatching(true); +use devtools_traits::{StartedTimelineMarker, TimelineMarker, TimelineMarkerType}; - let type_ = event.Type(); +struct AutoDOMEventMarker { + window: Root<Window>, + marker: Option<StartedTimelineMarker>, +} - //TODO: no chain if not participating in a tree - let mut chain: RootedVec<JS<EventTarget>> = RootedVec::new(); - if let Some(target_node) = NodeCast::to_ref(target) { - for ancestor in target_node.ancestors() { - let ancestor_target = EventTargetCast::from_ref(ancestor.r()); - chain.push(JS::from_ref(ancestor_target)) +impl AutoDOMEventMarker { + fn new(window: &Window) -> AutoDOMEventMarker { + AutoDOMEventMarker { + window: Root::from_ref(window), + marker: Some(TimelineMarker::start("DOMEvent".to_owned())), } } +} - event.set_phase(EventPhase::Capturing); +impl Drop for AutoDOMEventMarker { + fn drop(&mut self) { + self.window.emit_timeline_marker(self.marker.take().unwrap().end()); + } +} + +fn handle_event(window: Option<&Window>, listener: &EventListenerType, + current_target: &EventTarget, event: &Event) { + let _marker; + if let Some(window) = window { + _marker = AutoDOMEventMarker::new(window); + } + + listener.call_or_handle_event(current_target, event, Report); +} + +fn dispatch_to_listeners(event: &Event, target: &EventTarget, chain: &[&EventTarget]) { + assert!(!event.stop_propagation()); + assert!(!event.stop_immediate()); - //FIXME: The "callback this value" should be currentTarget + let window = match global_object_for_reflector(target) { + GlobalRoot::Window(window) => { + if window.need_emit_timeline_marker(TimelineMarkerType::DOMEvent) { + Some(window) + } else { + None + } + }, + _ => None, + }; + + let type_ = event.Type(); /* capturing */ - for cur_target in chain.r().iter().rev() { - let stopped = match cur_target.get_listeners_for(&type_, ListenerPhase::Capturing) { - Some(listeners) => { - event.set_current_target(cur_target); - for listener in &listeners { - // Explicitly drop any exception on the floor. - listener.call_or_handle_event(*cur_target, event, Report); - - if event.stop_immediate() { - break; - } - } + event.set_phase(EventPhase::Capturing); + for cur_target in chain.iter().rev() { + if let Some(listeners) = cur_target.get_listeners_for(&type_, ListenerPhase::Capturing) { + event.set_current_target(cur_target); + for listener in &listeners { + handle_event(window.r(), listener, *cur_target, event); - event.stop_propagation() + if event.stop_immediate() { + return; + } } - None => false - }; - if stopped { - break; + if event.stop_propagation() { + return; + } } } + assert!(!event.stop_propagation()); + assert!(!event.stop_immediate()); + /* at target */ - if !event.stop_propagation() { - event.set_phase(EventPhase::AtTarget); - event.set_current_target(target.clone()); + event.set_phase(EventPhase::AtTarget); + event.set_current_target(target); - let opt_listeners = target.get_listeners(&type_); - for listeners in opt_listeners { - for listener in listeners { - // Explicitly drop any exception on the floor. - listener.call_or_handle_event(target, event, Report); + if let Some(listeners) = target.get_listeners(&type_) { + for listener in listeners { + handle_event(window.r(), &listener, target, event); - if event.stop_immediate() { - break; - } + if event.stop_immediate() { + return; } } + if event.stop_propagation() { + return; + } } + assert!(!event.stop_propagation()); + assert!(!event.stop_immediate()); + /* bubbling */ - if event.bubbles() && !event.stop_propagation() { - event.set_phase(EventPhase::Bubbling); - - for cur_target in chain.r() { - let stopped = match cur_target.get_listeners_for(&type_, ListenerPhase::Bubbling) { - Some(listeners) => { - event.set_current_target(cur_target); - for listener in &listeners { - // Explicitly drop any exception on the floor. - listener.call_or_handle_event(*cur_target, event, Report); - - if event.stop_immediate() { - break; - } - } - - event.stop_propagation() + if !event.bubbles() { + return; + } + + event.set_phase(EventPhase::Bubbling); + for cur_target in chain { + if let Some(listeners) = cur_target.get_listeners_for(&type_, ListenerPhase::Bubbling) { + event.set_current_target(cur_target); + for listener in &listeners { + handle_event(window.r(), listener, *cur_target, event); + + if event.stop_immediate() { + return; } - None => false - }; - if stopped { - break; + } + + if event.stop_propagation() { + return; } } } +} + +// See https://dom.spec.whatwg.org/#concept-event-dispatch for the full dispatch algorithm +pub fn dispatch_event(target: &EventTarget, pseudo_target: Option<&EventTarget>, + event: &Event) -> bool { + assert!(!event.dispatching()); + assert!(event.initialized()); + assert_eq!(event.phase(), EventPhase::None); + assert!(event.GetCurrentTarget().is_none()); + + event.set_target(match pseudo_target { + Some(pseudo_target) => pseudo_target, + None => target.clone(), + }); + + if event.stop_propagation() { + return !event.DefaultPrevented(); + } + + event.set_dispatching(true); + + let mut chain: RootedVec<JS<EventTarget>> = RootedVec::new(); + if let Some(target_node) = NodeCast::to_ref(target) { + for ancestor in target_node.ancestors() { + let ancestor_target = EventTargetCast::from_ref(ancestor.r()); + chain.push(JS::from_ref(ancestor_target)) + } + } + + dispatch_to_listeners(event, target, chain.r()); /* default action */ let target = event.GetTarget(); diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index f2f228f2c0d..c6f3db73d8c 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -7,6 +7,7 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener; use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods; +use dom::bindings::conversions::get_dom_class; use dom::bindings::error::Error::InvalidState; use dom::bindings::error::{Fallible, report_pending_exception}; use dom::bindings::utils::{Reflectable, Reflector}; @@ -45,8 +46,7 @@ pub enum ListenerPhase { Bubbling, } -#[derive(JSTraceable, Copy, Clone)] -#[derive(HeapSizeOf)] +#[derive(Copy, Clone)] pub enum EventTargetTypeId { Node(NodeTypeId), WebSocket, @@ -132,15 +132,13 @@ pub struct EventListenerEntry { #[dom_struct] pub struct EventTarget { reflector_: Reflector, - type_id: EventTargetTypeId, handlers: DOMRefCell<HashMap<DOMString, Vec<EventListenerEntry>, DefaultState<FnvHasher>>>, } impl EventTarget { - pub fn new_inherited(type_id: EventTargetTypeId) -> EventTarget { + pub fn new_inherited() -> EventTarget { EventTarget { reflector_: Reflector::new(), - type_id: type_id, handlers: DOMRefCell::new(Default::default()), } } @@ -159,9 +157,12 @@ impl EventTarget { }) } - #[inline] + #[allow(unsafe_code)] pub fn type_id(&self) -> &EventTargetTypeId { - &self.type_id + let domclass = unsafe { + get_dom_class(self.reflector_.get_jsobject().get()).unwrap() + }; + domclass.type_id.as_ref().unwrap() } pub fn dispatch_event_with_target(&self, diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs index ffd74806c04..5de6f4dd5f9 100644 --- a/components/script/dom/filereader.rs +++ b/components/script/dom/filereader.rs @@ -15,7 +15,7 @@ use dom::bindings::utils::{reflect_dom_object, Reflectable}; use dom::blob::Blob; use dom::domexception::{DOMException, DOMErrorName}; use dom::event::{EventCancelable, EventBubbles}; -use dom::eventtarget::{EventTarget, EventTargetTypeId}; +use dom::eventtarget::EventTarget; use dom::progressevent::ProgressEvent; use encoding::all::UTF_8; use encoding::label::encoding_from_whatwg_label; @@ -80,7 +80,7 @@ pub struct FileReader { impl FileReader { pub fn new_inherited(global: GlobalRef) -> FileReader { FileReader { - eventtarget: EventTarget::new_inherited(EventTargetTypeId::FileReader),//? + eventtarget: EventTarget::new_inherited(),//? global: GlobalField::from_rooted(&global), ready_state: Cell::new(FileReaderReadyState::Empty), error: MutNullableHeap::new(None), diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index 67daf4e6df4..ebfd1c4deb0 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -98,6 +98,30 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement { DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel")) }) } + + // https://html.spec.whatwg.org/multipage/#dom-a-coords + make_getter!(Coords); + + // https://html.spec.whatwg.org/multipage/#dom-a-coords + make_setter!(SetCoords, "coords"); + + // https://html.spec.whatwg.org/multipage/#dom-a-name + make_getter!(Name); + + // https://html.spec.whatwg.org/multipage/#dom-a-name + make_setter!(SetName, "name"); + + // https://html.spec.whatwg.org/multipage/#dom-a-rev + make_getter!(Rev); + + // https://html.spec.whatwg.org/multipage/#dom-a-rev + make_setter!(SetRev, "rev"); + + // https://html.spec.whatwg.org/multipage/#dom-a-shape + make_getter!(Shape); + + // https://html.spec.whatwg.org/multipage/#dom-a-shape + make_setter!(SetShape, "shape"); } impl Activatable for HTMLAnchorElement { diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs index fa1ddcbdd08..a09825574a4 100644 --- a/components/script/dom/htmlbodyelement.rs +++ b/components/script/dom/htmlbodyelement.rs @@ -140,21 +140,19 @@ impl VirtualMethods for HTMLBodyElement { }); }, (name, AttributeMutation::Set(_)) if name.starts_with("on") => { - static FORWARDED_EVENTS: &'static [&'static str] = - &["onfocus", "onload", "onscroll", "onafterprint", "onbeforeprint", - "onbeforeunload", "onhashchange", "onlanguagechange", "onmessage", - "onoffline", "ononline", "onpagehide", "onpageshow", "onpopstate", - "onstorage", "onresize", "onunload", "onerror"]; let window = window_from_node(self); let (cx, url, reflector) = (window.get_cx(), window.get_url(), window.reflector().get_jsobject()); - let evtarget = - if FORWARDED_EVENTS.iter().any(|&event| &**name == event) { - EventTargetCast::from_ref(window.r()) - } else { - EventTargetCast::from_ref(self) - }; + let evtarget = match name { + &atom!(onfocus) | &atom!(onload) | &atom!(onscroll) | &atom!(onafterprint) | + &atom!(onbeforeprint) | &atom!(onbeforeunload) | &atom!(onhashchange) | + &atom!(onlanguagechange) | &atom!(onmessage) | &atom!(onoffline) | &atom!(ononline) | + &atom!(onpagehide) | &atom!(onpageshow) | &atom!(onpopstate) | &atom!(onstorage) | + &atom!(onresize) | &atom!(onunload) | &atom!(onerror) + => EventTargetCast::from_ref(window.r()), // forwarded event + _ => EventTargetCast::from_ref(self), + }; evtarget.set_event_handler_uncompiled(cx, url, reflector, &name[2..], (**attr.value()).to_owned()); diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index 661378a7fc4..9a02a47dd0f 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -344,7 +344,7 @@ impl VirtualMethods for HTMLElement { } } -#[derive(JSTraceable, Copy, Clone, Debug, HeapSizeOf)] +#[derive(Copy, Clone, Debug)] pub enum HTMLElementTypeId { HTMLElement, diff --git a/components/script/dom/htmlfontelement.rs b/components/script/dom/htmlfontelement.rs index 30dd8533242..bee1711916e 100644 --- a/components/script/dom/htmlfontelement.rs +++ b/components/script/dom/htmlfontelement.rs @@ -2,7 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use dom::attr::Attr; +use dom::attr::{Attr, AttrValue}; +use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::HTMLFontElementBinding; use dom::bindings::codegen::Bindings::HTMLFontElementBinding::HTMLFontElementMethods; use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLFontElementDerived}; @@ -13,6 +14,7 @@ use dom::eventtarget::{EventTarget, EventTargetTypeId}; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; use dom::node::{Node, NodeTypeId}; use dom::virtualmethods::VirtualMethods; +use string_cache::Atom; use util::str::{self, DOMString}; use cssparser::RGBA; @@ -22,6 +24,7 @@ use std::cell::Cell; pub struct HTMLFontElement { htmlelement: HTMLElement, color: Cell<Option<RGBA>>, + face: DOMRefCell<Option<Atom>>, } impl HTMLFontElementDerived for EventTarget { @@ -37,6 +40,7 @@ impl HTMLFontElement { HTMLFontElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLFontElement, localName, prefix, document), color: Cell::new(None), + face: DOMRefCell::new(None), } } @@ -55,6 +59,12 @@ impl HTMLFontElementMethods for HTMLFontElement { // https://html.spec.whatwg.org/multipage/#dom-font-color make_setter!(SetColor, "color"); + + // https://html.spec.whatwg.org/multipage/#dom-font-face + make_getter!(Face); + + // https://html.spec.whatwg.org/multipage/#dom-font-face + make_atomic_setter!(SetFace, "face"); } impl VirtualMethods for HTMLFontElement { @@ -66,14 +76,26 @@ impl VirtualMethods for HTMLFontElement { fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { self.super_type().unwrap().attribute_mutated(attr, mutation); match attr.local_name() { - &atom!(color) => { + &atom!(color) => { self.color.set(mutation.new_value(attr).and_then(|value| { str::parse_legacy_color(&value).ok() })); }, + &atom!(face) => { + *self.face.borrow_mut() = + mutation.new_value(attr) + .map(|value| value.as_atom().clone()) + }, _ => {}, } } + + fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue { + match name { + &atom!("face") => AttrValue::from_atomic(value), + _ => self.super_type().unwrap().parse_plain_attribute(name, value), + } + } } @@ -81,4 +103,13 @@ impl HTMLFontElement { pub fn get_color(&self) -> Option<RGBA> { self.color.get() } + + #[allow(unsafe_code)] + pub fn get_face(&self) -> Option<Atom> { + let face = unsafe { self.face.borrow_for_layout() }; + match *face { + Some(ref s) => Some(s.clone()), + None => None, + } + } } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index d0facdaa1a5..51b9a3c54f0 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -27,9 +27,9 @@ use dom::node::{Node, NodeDamage, NodeTypeId}; use dom::node::{document_from_node, window_from_node}; use dom::virtualmethods::VirtualMethods; use msg::constellation_msg::ConstellationChan; -use textinput::KeyReaction::{TriggerDefaultAction, DispatchInput, Nothing}; +use textinput::KeyReaction::{TriggerDefaultAction, DispatchInput, Nothing, RedrawSelection}; use textinput::Lines::Single; -use textinput::TextInput; +use textinput::{TextInput, TextPoint}; use string_cache::Atom; use util::str::DOMString; @@ -144,6 +144,8 @@ pub trait LayoutHTMLInputElementHelpers { unsafe fn get_value_for_layout(self) -> String; #[allow(unsafe_code)] unsafe fn get_size_for_layout(self) -> u32; + #[allow(unsafe_code)] + unsafe fn get_insertion_point_for_layout(self) -> TextPoint; } pub trait RawLayoutHTMLInputElementHelpers { @@ -194,6 +196,12 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> { unsafe fn get_size_for_layout(self) -> u32 { (*self.unsafe_get()).get_size_for_layout() } + + #[allow(unrooted_must_root)] + #[allow(unsafe_code)] + unsafe fn get_insertion_point_for_layout(self) -> TextPoint { + (*self.unsafe_get()).textinput.borrow_for_layout().edit_point + } } impl RawLayoutHTMLInputElementHelpers for HTMLInputElement { @@ -520,7 +528,7 @@ impl VirtualMethods for HTMLInputElement { self.radio_group_updated( mutation.new_value(attr).as_ref().map(|value| &***value)); }, - name if name == &Atom::from_slice("placeholder") => { + &atom!(placeholder) => { let mut placeholder = self.placeholder.borrow_mut(); placeholder.clear(); if let AttributeMutation::Set(_) = mutation { @@ -599,6 +607,9 @@ impl VirtualMethods for HTMLInputElement { self.force_relayout(); event.PreventDefault(); } + RedrawSelection => { + self.force_relayout(); + } Nothing => (), } }); diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 25f5087785e..87303ae8131 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -238,6 +238,24 @@ impl HTMLLinkElementMethods for HTMLLinkElement { DOMTokenList::new(ElementCast::from_ref(self), &atom!("rel")) }) } + + // https://html.spec.whatwg.org/multipage/#dom-link-charset + make_getter!(Charset); + + // https://html.spec.whatwg.org/multipage/#dom-link-charset + make_setter!(SetCharset, "charset"); + + // https://html.spec.whatwg.org/multipage/#dom-link-rev + make_getter!(Rev); + + // https://html.spec.whatwg.org/multipage/#dom-link-rev + make_setter!(SetRev, "rev"); + + // https://html.spec.whatwg.org/multipage/#dom-link-target + make_getter!(Target); + + // https://html.spec.whatwg.org/multipage/#dom-link-target + make_setter!(SetTarget, "target"); } pub struct StylesheetLoadDispatcher { diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 4b40e13e129..8630cf5a745 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -41,7 +41,7 @@ impl HTMLMediaElement { } } -#[derive(JSTraceable, Copy, Clone, Debug, HeapSizeOf)] +#[derive(Copy, Clone, Debug)] pub enum HTMLMediaElementTypeId { HTMLAudioElement = 0, HTMLVideoElement = 1, diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index c70a0d3541b..815ef46ea64 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -45,7 +45,6 @@ use net_traits::{Metadata, AsyncResponseListener, AsyncResponseTarget}; use std::cell::{RefCell, Cell}; use std::mem; use std::sync::{Arc, Mutex}; -use string_cache::Atom; use url::{Url, UrlParser}; use util::str::{DOMString, HTML_SPACE_CHARACTERS, StaticStringVec}; @@ -233,7 +232,7 @@ impl HTMLScriptElement { // Step 12. let for_attribute = element.get_attribute(&ns!(""), &atom!("for")); - let event_attribute = element.get_attribute(&ns!(""), &Atom::from_slice("event")); + let event_attribute = element.get_attribute(&ns!(""), &atom!("event")); match (for_attribute.r(), event_attribute.r()) { (Some(for_attribute), Some(event_attribute)) => { let for_value = for_attribute.value().to_ascii_lowercase(); @@ -252,7 +251,7 @@ impl HTMLScriptElement { } // Step 13. - if let Some(ref charset) = element.get_attribute(&ns!(""), &Atom::from_slice("charset")) { + if let Some(ref charset) = element.get_attribute(&ns!(""), &atom!("charset")) { if let Some(encodingRef) = encoding_from_whatwg_label(&charset.r().Value()) { *self.block_character_encoding.borrow_mut() = encodingRef; } diff --git a/components/script/dom/htmltablecellelement.rs b/components/script/dom/htmltablecellelement.rs index c67d02c8693..15c1acf3737 100644 --- a/components/script/dom/htmltablecellelement.rs +++ b/components/script/dom/htmltablecellelement.rs @@ -22,7 +22,7 @@ use std::cmp::max; const DEFAULT_COLSPAN: u32 = 1; -#[derive(JSTraceable, Copy, Clone, Debug, HeapSizeOf)] +#[derive(Copy, Clone, Debug)] pub enum HTMLTableCellElementTypeId { HTMLTableDataCellElement = 0, HTMLTableHeaderCellElement = 1, diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index f1682d2270b..fd1713057ee 100644 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -350,6 +350,9 @@ impl VirtualMethods for HTMLTextAreaElement { self.force_relayout(); } + KeyReaction::RedrawSelection => { + self.force_relayout(); + } KeyReaction::Nothing => (), } }); diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index b0c8d79228e..ae725d3d856 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -81,9 +81,6 @@ pub struct Node { /// The JavaScript reflector for this node. eventtarget: EventTarget, - /// The type of node that this is. - type_id: NodeTypeId, - /// The parent of this node. parent_node: MutNullableHeap<JS<Node>>, @@ -284,8 +281,7 @@ impl LayoutDataRef { } /// The different types of nodes. -#[derive(JSTraceable, Copy, Clone, PartialEq, Debug)] -#[derive(HeapSizeOf)] +#[derive(Copy, Clone, PartialEq, Debug)] pub enum NodeTypeId { CharacterData(CharacterDataTypeId), DocumentType, @@ -452,7 +448,7 @@ impl Node { /// Returns a string that describes this node. pub fn debug_str(&self) -> String { - format!("{:?}", self.type_id) + format!("{:?}", self.type_id()) } pub fn is_in_doc(&self) -> bool { @@ -461,12 +457,15 @@ impl Node { /// Returns the type ID of this node. Fails if this node is borrowed mutably. pub fn type_id(&self) -> NodeTypeId { - self.type_id + match *self.eventtarget.type_id() { + EventTargetTypeId::Node(type_id) => type_id, + _ => unreachable!(), + } } // https://dom.spec.whatwg.org/#concept-node-length pub fn len(&self) -> u32 { - match self.type_id { + match self.type_id() { NodeTypeId::DocumentType => 0, NodeTypeId::CharacterData(_) => { CharacterDataCast::to_ref(self).unwrap().Length() @@ -486,12 +485,12 @@ impl Node { #[inline] pub fn is_anchor_element(&self) -> bool { - self.type_id == NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) + self.type_id() == NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) } #[inline] pub fn is_doctype(&self) -> bool { - self.type_id == NodeTypeId::DocumentType + self.type_id() == NodeTypeId::DocumentType } pub fn get_flag(&self, flag: NodeFlags) -> bool { @@ -1026,7 +1025,7 @@ impl LayoutNodeHelpers for LayoutJS<Node> { #[inline] #[allow(unsafe_code)] unsafe fn type_id_for_layout(&self) -> NodeTypeId { - (*self.unsafe_get()).type_id + (*self.unsafe_get()).type_id() } #[inline] @@ -1393,8 +1392,7 @@ impl Node { fn new_(type_id: NodeTypeId, doc: Option<&Document>) -> Node { Node { - eventtarget: EventTarget::new_inherited(EventTargetTypeId::Node(type_id)), - type_id: type_id, + eventtarget: EventTarget::new_inherited(), parent_node: Default::default(), first_child: Default::default(), @@ -1833,7 +1831,7 @@ impl Node { } } - match node.type_id { + match node.type_id() { NodeTypeId::Element(_) => { let element = ElementCast::to_ref(node).unwrap(); // Step 1. @@ -1889,7 +1887,7 @@ impl Node { impl NodeMethods for Node { // https://dom.spec.whatwg.org/#dom-node-nodetype fn NodeType(&self) -> u16 { - match self.type_id { + match self.type_id() { NodeTypeId::CharacterData(CharacterDataTypeId::Text) => NodeConstants::TEXT_NODE, NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) => @@ -1909,7 +1907,7 @@ impl NodeMethods for Node { // https://dom.spec.whatwg.org/#dom-node-nodename fn NodeName(&self) -> DOMString { - match self.type_id { + match self.type_id() { NodeTypeId::Element(..) => { let elem: &Element = ElementCast::to_ref(self).unwrap(); elem.TagName() @@ -1937,7 +1935,7 @@ impl NodeMethods for Node { // https://dom.spec.whatwg.org/#dom-node-ownerdocument fn GetOwnerDocument(&self) -> Option<Root<Document>> { - match self.type_id { + match self.type_id() { NodeTypeId::CharacterData(..) | NodeTypeId::Element(..) | NodeTypeId::DocumentType | @@ -1992,19 +1990,30 @@ impl NodeMethods for Node { // https://dom.spec.whatwg.org/#dom-node-nodevalue fn GetNodeValue(&self) -> Option<DOMString> { - CharacterDataCast::to_ref(self).map(|c| c.Data()) + match self.type_id() { + NodeTypeId::CharacterData(..) => { + let chardata: &CharacterData = CharacterDataCast::to_ref(self).unwrap(); + Some(chardata.Data()) + } + _ => { + None + } + } } // https://dom.spec.whatwg.org/#dom-node-nodevalue fn SetNodeValue(&self, val: Option<DOMString>) { - if let NodeTypeId::CharacterData(..) = self.type_id { - self.SetTextContent(val) + match self.type_id() { + NodeTypeId::CharacterData(..) => { + self.SetTextContent(val) + } + _ => {} } } // https://dom.spec.whatwg.org/#dom-node-textcontent fn GetTextContent(&self) -> Option<DOMString> { - match self.type_id { + match self.type_id() { NodeTypeId::DocumentFragment | NodeTypeId::Element(..) => { let content = Node::collect_text_contents(self.traverse_preorder()); @@ -2024,7 +2033,7 @@ impl NodeMethods for Node { // https://dom.spec.whatwg.org/#dom-node-textcontent fn SetTextContent(&self, value: Option<DOMString>) { let value = value.unwrap_or(String::new()); - match self.type_id { + match self.type_id() { NodeTypeId::DocumentFragment | NodeTypeId::Element(..) => { // Step 1-2. @@ -2065,7 +2074,7 @@ impl NodeMethods for Node { fn ReplaceChild(&self, node: &Node, child: &Node) -> Fallible<Root<Node>> { // Step 1. - match self.type_id { + match self.type_id() { NodeTypeId::Document | NodeTypeId::DocumentFragment | NodeTypeId::Element(..) => (), @@ -2147,7 +2156,7 @@ impl NodeMethods for Node { } }, NodeTypeId::CharacterData(..) => (), - NodeTypeId::Document => unreachable!() + NodeTypeId::Document => unreachable!(), } } diff --git a/components/script/dom/webidls/CharacterData.webidl b/components/script/dom/webidls/CharacterData.webidl index b22d755438f..68ba9ab8eb8 100644 --- a/components/script/dom/webidls/CharacterData.webidl +++ b/components/script/dom/webidls/CharacterData.webidl @@ -10,6 +10,7 @@ * liability, trademark and document use rules apply. */ +[Abstract] interface CharacterData : Node { [TreatNullAs=EmptyString] attribute DOMString data; readonly attribute unsigned long length; diff --git a/components/script/dom/webidls/EventTarget.webidl b/components/script/dom/webidls/EventTarget.webidl index 1bc929851ed..403b1287fe4 100644 --- a/components/script/dom/webidls/EventTarget.webidl +++ b/components/script/dom/webidls/EventTarget.webidl @@ -6,6 +6,7 @@ * https://dom.spec.whatwg.org/#interface-eventtarget */ +[Abstract] interface EventTarget { void addEventListener(DOMString type, EventListener? listener, diff --git a/components/script/dom/webidls/HTMLAnchorElement.webidl b/components/script/dom/webidls/HTMLAnchorElement.webidl index 7622cc0ceb4..7129f0ad1ed 100644 --- a/components/script/dom/webidls/HTMLAnchorElement.webidl +++ b/components/script/dom/webidls/HTMLAnchorElement.webidl @@ -30,9 +30,9 @@ interface HTMLAnchorElement : HTMLElement { // https://www.whatwg.org/html/#HTMLAnchorElement-partial partial interface HTMLAnchorElement { - // attribute DOMString coords; + attribute DOMString coords; // attribute DOMString charset; - // attribute DOMString name; - // attribute DOMString rev; - // attribute DOMString shape; + attribute DOMString name; + attribute DOMString rev; + attribute DOMString shape; }; diff --git a/components/script/dom/webidls/HTMLFontElement.webidl b/components/script/dom/webidls/HTMLFontElement.webidl index 03b68498db7..8419fcab10f 100644 --- a/components/script/dom/webidls/HTMLFontElement.webidl +++ b/components/script/dom/webidls/HTMLFontElement.webidl @@ -6,6 +6,6 @@ // https://www.whatwg.org/html/#htmlfontelement interface HTMLFontElement : HTMLElement { [TreatNullAs=EmptyString] attribute DOMString color; - // attribute DOMString face; + attribute DOMString face; // attribute DOMString size; }; diff --git a/components/script/dom/webidls/HTMLLinkElement.webidl b/components/script/dom/webidls/HTMLLinkElement.webidl index 9d32ec5b7b3..2a94a38a836 100644 --- a/components/script/dom/webidls/HTMLLinkElement.webidl +++ b/components/script/dom/webidls/HTMLLinkElement.webidl @@ -20,7 +20,7 @@ interface HTMLLinkElement : HTMLElement { // https://www.whatwg.org/html/#HTMLLinkElement-partial partial interface HTMLLinkElement { - // attribute DOMString charset; - // attribute DOMString rev; - // attribute DOMString target; + attribute DOMString charset; + attribute DOMString rev; + attribute DOMString target; }; diff --git a/components/script/dom/webidls/HTMLMediaElement.webidl b/components/script/dom/webidls/HTMLMediaElement.webidl index e7b0383d1a3..17e86f91469 100644 --- a/components/script/dom/webidls/HTMLMediaElement.webidl +++ b/components/script/dom/webidls/HTMLMediaElement.webidl @@ -5,6 +5,7 @@ // https://www.whatwg.org/html/#htmlmediaelement //enum CanPlayTypeResult { "" /* empty string */, "maybe", "probably" }; +[Abstract] interface HTMLMediaElement : HTMLElement { // error state diff --git a/components/script/dom/webidls/HTMLTableCellElement.webidl b/components/script/dom/webidls/HTMLTableCellElement.webidl index de1211b6333..1371bea720e 100644 --- a/components/script/dom/webidls/HTMLTableCellElement.webidl +++ b/components/script/dom/webidls/HTMLTableCellElement.webidl @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // https://www.whatwg.org/html/#htmltablecellelement +[Abstract] interface HTMLTableCellElement : HTMLElement { attribute unsigned long colSpan; // attribute unsigned long rowSpan; diff --git a/components/script/dom/webidls/Node.webidl b/components/script/dom/webidls/Node.webidl index bb118820237..73635ab6f7b 100644 --- a/components/script/dom/webidls/Node.webidl +++ b/components/script/dom/webidls/Node.webidl @@ -7,6 +7,7 @@ * https://dom.spec.whatwg.org/#interface-node */ +[Abstract] interface Node : EventTarget { const unsigned short ELEMENT_NODE = 1; const unsigned short ATTRIBUTE_NODE = 2; // historical diff --git a/components/script/dom/webidls/WorkerGlobalScope.webidl b/components/script/dom/webidls/WorkerGlobalScope.webidl index c8427b95fd0..28a4f028bb5 100644 --- a/components/script/dom/webidls/WorkerGlobalScope.webidl +++ b/components/script/dom/webidls/WorkerGlobalScope.webidl @@ -2,8 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -// https://www.whatwg.org/html/#workerglobalscope -//[Exposed=Worker] +// https://html.spec.whatwg.org/multipage/#workerglobalscope +[Abstract/*, Exposed=Worker*/] interface WorkerGlobalScope : EventTarget { [BinaryName="Self_"] readonly attribute WorkerGlobalScope self; readonly attribute WorkerLocation location; diff --git a/components/script/dom/webidls/XMLHttpRequestEventTarget.webidl b/components/script/dom/webidls/XMLHttpRequestEventTarget.webidl index fa2d9625ad9..7756d9dd623 100644 --- a/components/script/dom/webidls/XMLHttpRequestEventTarget.webidl +++ b/components/script/dom/webidls/XMLHttpRequestEventTarget.webidl @@ -13,7 +13,7 @@ * http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0. */ -//[Exposed=(Window,Worker)] +[Abstract/*, Exposed=(Window,Worker)*/] interface XMLHttpRequestEventTarget : EventTarget { // event handlers attribute EventHandler onloadstart; diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 4b614786efa..2bf84d609e7 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -20,7 +20,7 @@ use dom::bindings::utils::{reflect_dom_object, Reflectable}; use dom::blob::Blob; use dom::closeevent::CloseEvent; use dom::event::{Event, EventBubbles, EventCancelable}; -use dom::eventtarget::{EventTarget, EventTargetTypeId}; +use dom::eventtarget::EventTarget; use dom::messageevent::MessageEvent; use script_task::ScriptTaskEventCategory::WebSocketEvent; use script_task::{Runnable, CommonScriptMsg}; @@ -110,7 +110,7 @@ fn establish_a_websocket_connection(resource_url: &Url, net_url: (Host, String, impl WebSocket { fn new_inherited(global: GlobalRef, url: Url) -> WebSocket { WebSocket { - eventtarget: EventTarget::new_inherited(EventTargetTypeId::WebSocket), + eventtarget: EventTarget::new_inherited(), url: url, global: GlobalField::from_rooted(&global), ready_state: Cell::new(WebSocketRequestState::Connecting), diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index a6338821d16..16c146f91fe 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -1217,16 +1217,21 @@ impl Window { sender.send(marker).unwrap(); } - pub fn set_devtools_timeline_marker(&self, - marker: TimelineMarkerType, - reply: IpcSender<TimelineMarker>) { + pub fn set_devtools_timeline_markers(&self, + markers: Vec<TimelineMarkerType>, + reply: IpcSender<TimelineMarker>) { *self.devtools_marker_sender.borrow_mut() = Some(reply); - self.devtools_markers.borrow_mut().insert(marker); + self.devtools_markers.borrow_mut().extend(markers.into_iter()); } - pub fn drop_devtools_timeline_markers(&self) { - self.devtools_markers.borrow_mut().clear(); - *self.devtools_marker_sender.borrow_mut() = None; + pub fn drop_devtools_timeline_markers(&self, markers: Vec<TimelineMarkerType>) { + let mut devtools_markers = self.devtools_markers.borrow_mut(); + for marker in markers { + devtools_markers.remove(&marker); + } + if devtools_markers.is_empty() { + *self.devtools_marker_sender.borrow_mut() = None; + } } pub fn set_webdriver_script_chan(&self, chan: Option<IpcSender<WebDriverJSResult>>) { @@ -1277,7 +1282,7 @@ impl Window { }; let win = box Window { - eventtarget: EventTarget::new_inherited(EventTargetTypeId::Window), + eventtarget: EventTarget::new_inherited(), script_chan: script_chan, image_cache_chan: image_cache_chan, control_chan: control_chan, diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 2711e8502db..92053392db7 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -17,7 +17,7 @@ use dom::bindings::utils::{Reflectable, reflect_dom_object}; use dom::dedicatedworkerglobalscope::{DedicatedWorkerGlobalScope, WorkerScriptMsg}; use dom::errorevent::ErrorEvent; use dom::event::{Event, EventBubbles, EventCancelable}; -use dom::eventtarget::{EventTarget, EventTargetTypeId}; +use dom::eventtarget::EventTarget; use dom::messageevent::MessageEvent; use dom::workerglobalscope::WorkerGlobalScopeInit; @@ -52,7 +52,7 @@ impl Worker { sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>) -> Worker { Worker { - eventtarget: EventTarget::new_inherited(EventTargetTypeId::Worker), + eventtarget: EventTarget::new_inherited(), global: GlobalField::from_rooted(&global), sender: sender, } diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 3bc805a67e6..4fbd17a7413 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -12,7 +12,7 @@ use dom::bindings::js::{JS, Root, MutNullableHeap}; use dom::bindings::utils::Reflectable; use dom::console::Console; use dom::crypto::Crypto; -use dom::eventtarget::{EventTarget, EventTargetTypeId}; +use dom::eventtarget::EventTarget; use dom::window::{base64_atob, base64_btoa}; use dom::workerlocation::WorkerLocation; use dom::workernavigator::WorkerNavigator; @@ -36,9 +36,9 @@ use std::default::Default; use std::rc::Rc; use std::sync::mpsc::Receiver; -#[derive(JSTraceable, Copy, Clone, PartialEq, HeapSizeOf)] +#[derive(Copy, Clone, PartialEq)] pub enum WorkerGlobalScopeTypeId { - DedicatedGlobalScope, + DedicatedWorkerGlobalScope, } pub struct WorkerGlobalScopeInit { @@ -90,14 +90,13 @@ pub struct WorkerGlobalScope { } impl WorkerGlobalScope { - pub fn new_inherited(type_id: WorkerGlobalScopeTypeId, - init: WorkerGlobalScopeInit, + pub fn new_inherited(init: WorkerGlobalScopeInit, worker_url: Url, runtime: Rc<Runtime>, from_devtools_receiver: Receiver<DevtoolScriptControlMsg>) -> WorkerGlobalScope { WorkerGlobalScope { - eventtarget: EventTarget::new_inherited(EventTargetTypeId::WorkerGlobalScope(type_id)), + eventtarget: EventTarget::new_inherited(), next_worker_id: Cell::new(WorkerId(0)), worker_id: init.worker_id, worker_url: worker_url, diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 4dd5647029a..743c0e2f6dd 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -155,7 +155,7 @@ pub struct XMLHttpRequest { impl XMLHttpRequest { fn new_inherited(global: GlobalRef) -> XMLHttpRequest { XMLHttpRequest { - eventtarget: XMLHttpRequestEventTarget::new_inherited(XMLHttpRequestEventTargetTypeId::XMLHttpRequest), + eventtarget: XMLHttpRequestEventTarget::new_inherited(), ready_state: Cell::new(XMLHttpRequestState::Unsent), timeout: Cell::new(0u32), with_credentials: Cell::new(false), diff --git a/components/script/dom/xmlhttprequesteventtarget.rs b/components/script/dom/xmlhttprequesteventtarget.rs index 627e4882dde..66dcb5f8211 100644 --- a/components/script/dom/xmlhttprequesteventtarget.rs +++ b/components/script/dom/xmlhttprequesteventtarget.rs @@ -8,7 +8,7 @@ use dom::bindings::codegen::InheritTypes::EventTargetCast; use dom::bindings::codegen::InheritTypes::XMLHttpRequestEventTargetDerived; use dom::eventtarget::{EventTarget, EventTargetTypeId}; -#[derive(JSTraceable, Copy, Clone, PartialEq, HeapSizeOf)] +#[derive(Copy, Clone, PartialEq)] pub enum XMLHttpRequestEventTargetTypeId { XMLHttpRequest, XMLHttpRequestUpload, @@ -20,9 +20,9 @@ pub struct XMLHttpRequestEventTarget { } impl XMLHttpRequestEventTarget { - pub fn new_inherited(type_id: XMLHttpRequestEventTargetTypeId) -> XMLHttpRequestEventTarget { + pub fn new_inherited() -> XMLHttpRequestEventTarget { XMLHttpRequestEventTarget { - eventtarget: EventTarget::new_inherited(EventTargetTypeId::XMLHttpRequestEventTarget(type_id)) + eventtarget: EventTarget::new_inherited() } } } diff --git a/components/script/dom/xmlhttprequestupload.rs b/components/script/dom/xmlhttprequestupload.rs index d112d9d1e08..c7d4d4d4ca3 100644 --- a/components/script/dom/xmlhttprequestupload.rs +++ b/components/script/dom/xmlhttprequestupload.rs @@ -19,8 +19,7 @@ pub struct XMLHttpRequestUpload { impl XMLHttpRequestUpload { fn new_inherited() -> XMLHttpRequestUpload { XMLHttpRequestUpload { - eventtarget: XMLHttpRequestEventTarget::new_inherited( - XMLHttpRequestEventTargetTypeId::XMLHttpRequestUpload) + eventtarget: XMLHttpRequestEventTarget::new_inherited(), } } pub fn new(global: GlobalRef) -> Root<XMLHttpRequestUpload> { |