diff --git a/servo/components/layout/wrapper.rs b/servo/components/layout/wrapper.rs index d36d44809761..9a040947a3c7 100644 --- a/servo/components/layout/wrapper.rs +++ b/servo/components/layout/wrapper.rs @@ -48,8 +48,8 @@ use script::dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, HTMLTex use script::dom::bindings::codegen::InheritTypes::{NodeCast, NodeTypeId, TextCast}; use script::dom::bindings::js::LayoutJS; use script::dom::characterdata::LayoutCharacterDataHelpers; -use script::dom::element::Element; -use script::dom::element::{LayoutElementHelpers, RawLayoutElementHelpers}; +use script::dom::element; +use script::dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers}; use script::dom::htmlcanvaselement::LayoutHTMLCanvasElementHelpers; use script::dom::htmlimageelement::LayoutHTMLImageElementHelpers; use script::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers}; @@ -468,20 +468,17 @@ impl<'le> ::selectors::Element for LayoutElement<'le> { #[inline] fn get_hover_state(&self) -> bool { - let node = NodeCast::from_layout_js(&self.element); - node.get_hover_state_for_layout() + self.element.get_event_state_for_layout().contains(element::IN_HOVER_STATE) } #[inline] fn get_focus_state(&self) -> bool { - let node = NodeCast::from_layout_js(&self.element); - node.get_focus_state_for_layout() + self.element.get_event_state_for_layout().contains(element::IN_FOCUS_STATE) } #[inline] fn get_active_state(&self) -> bool { - let node = NodeCast::from_layout_js(&self.element); - node.get_active_state_for_layout() + self.element.get_event_state_for_layout().contains(element::IN_ACTIVE_STATE) } #[inline] @@ -493,14 +490,12 @@ impl<'le> ::selectors::Element for LayoutElement<'le> { #[inline] fn get_disabled_state(&self) -> bool { - let node = NodeCast::from_layout_js(&self.element); - node.get_disabled_state_for_layout() + self.element.get_event_state_for_layout().contains(element::IN_DISABLED_STATE) } #[inline] fn get_enabled_state(&self) -> bool { - let node = NodeCast::from_layout_js(&self.element); - node.get_enabled_state_for_layout() + self.element.get_event_state_for_layout().contains(element::IN_ENABLED_STATE) } #[inline] diff --git a/servo/components/script/dom/document.rs b/servo/components/script/dom/document.rs index 175cc68ea9d3..7ce96fe94245 100644 --- a/servo/components/script/dom/document.rs +++ b/servo/components/script/dom/document.rs @@ -516,15 +516,13 @@ impl Document { //TODO: dispatch blur, focus, focusout, and focusin events if let Some(ref elem) = self.focused.get_rooted() { - let node = NodeCast::from_ref(elem.r()); - node.set_focus_state(false); + elem.set_focus_state(false); } self.focused.set(self.possibly_focused.get().r()); if let Some(ref elem) = self.focused.get_rooted() { - let node = NodeCast::from_ref(elem.r()); - node.set_focus_state(true); + elem.set_focus_state(true); // Update the focus state for all elements in the focus chain. // https://html.spec.whatwg.org/multipage/#focus-chain @@ -593,7 +591,7 @@ impl Document { debug!("{} on {:?}", mouse_event_type_string, node.debug_str()); // Prevent click event if form control element is disabled. if let MouseEventType::Click = mouse_event_type { - if node.click_event_filter_by_disabled_state() { + if el.click_event_filter_by_disabled_state() { return; } @@ -661,15 +659,16 @@ impl Document { pub fn handle_mouse_move_event(&self, js_runtime: *mut JSRuntime, point: Point2D, - prev_mouse_over_targets: &mut RootedVec>) { + prev_mouse_over_targets: &mut RootedVec>) { // Build a list of elements that are currently under the mouse. let mouse_over_addresses = self.get_nodes_under_mouse(&point); - let mut mouse_over_targets: RootedVec> = RootedVec::new(); + let mut mouse_over_targets: RootedVec> = RootedVec::new(); for node_address in &mouse_over_addresses { let node = node::from_untrusted_node_address(js_runtime, *node_address); mouse_over_targets.push(node.r().inclusive_ancestors() .find(|node| node.r().is_element()) - .map(|node| JS::from_rooted(&node)).unwrap()); + .map(|node| JS::from_ref(ElementCast::to_ref(node.r()).unwrap())) + .unwrap()); }; // Remove hover from any elements in the previous list that are no longer @@ -1126,9 +1125,10 @@ impl Document { } -impl Node { +impl Element { fn click_event_filter_by_disabled_state(&self) -> bool { - match self.type_id() { + let node = NodeCast::from_ref(self); + match node.type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) | // NodeTypeId::Element(ElementTypeId::HTMLKeygenElement) | diff --git a/servo/components/script/dom/element.rs b/servo/components/script/dom/element.rs index 089d3199058f..f6f19fffcfbc 100644 --- a/servo/components/script/dom/element.rs +++ b/servo/components/script/dom/element.rs @@ -22,8 +22,9 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::InheritTypes::{CharacterDataCast, DocumentDerived, ElementCast}; use dom::bindings::codegen::InheritTypes::{ElementDerived, ElementTypeId, EventTargetCast}; use dom::bindings::codegen::InheritTypes::{HTMLAnchorElementCast, HTMLBodyElementCast}; -use dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, HTMLFontElementCast}; +use dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, HTMLFieldSetElementDerived, HTMLFontElementCast}; use dom::bindings::codegen::InheritTypes::{HTMLIFrameElementCast, HTMLInputElementCast}; +use dom::bindings::codegen::InheritTypes::{HTMLLegendElementDerived, HTMLOptGroupElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLTableCellElementCast, HTMLTableElementCast}; use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementCast, HTMLTableSectionElementCast}; use dom::bindings::codegen::InheritTypes::{HTMLTemplateElementCast, HTMLTextAreaElementCast}; @@ -48,7 +49,7 @@ use dom::htmltableelement::HTMLTableElement; use dom::htmltextareaelement::RawLayoutHTMLTextAreaElementHelpers; use dom::namednodemap::NamedNodeMap; use dom::node::{CLICK_IN_PROGRESS, LayoutNodeHelpers, Node}; -use dom::node::{NodeDamage, NodeFlags, SEQUENTIALLY_FOCUSABLE}; +use dom::node::{NodeDamage, SEQUENTIALLY_FOCUSABLE}; use dom::node::{document_from_node, window_from_node}; use dom::nodelist::NodeList; use dom::virtualmethods::{VirtualMethods, vtable_for}; @@ -63,7 +64,7 @@ use selectors::parser::{AttrSelector, NamespaceConstraint}; use smallvec::VecLike; use std::ascii::AsciiExt; use std::borrow::{Cow, ToOwned}; -use std::cell::Ref; +use std::cell::{Cell, Ref}; use std::default::Default; use std::mem; use std::sync::Arc; @@ -77,6 +78,25 @@ use style::values::specified::{self, CSSColor, CSSRGBA}; use url::UrlParser; use util::str::{DOMString, LengthOrPercentageOrAuto}; +bitflags! { + #[doc = "Element Event States."] + #[derive(JSTraceable, HeapSizeOf)] + flags EventState: u8 { + #[doc = "The mouse is down on this element. \ + (https://html.spec.whatwg.org/multipage/#selector-active). \ + FIXME(#7333): set/unset this when appropriate"] + const IN_ACTIVE_STATE = 0x01, + #[doc = "This element has focus."] + const IN_FOCUS_STATE = 0x02, + #[doc = "The mouse is hovering over this element."] + const IN_HOVER_STATE = 0x04, + #[doc = "Content is enabled (and can be disabled)."] + const IN_ENABLED_STATE = 0x08, + #[doc = "Content is disabled."] + const IN_DISABLED_STATE = 0x10, + } +} + #[dom_struct] pub struct Element { node: Node, @@ -88,6 +108,7 @@ pub struct Element { style_attribute: DOMRefCell>, attr_list: MutNullableHeap>, class_list: MutNullableHeap>, + event_state: Cell, } impl PartialEq for Element { @@ -116,16 +137,16 @@ impl Element { pub fn new_inherited(local_name: DOMString, namespace: Namespace, prefix: Option, document: &Document) -> Element { - Element::new_inherited_with_flags(NodeFlags::new(), local_name, + Element::new_inherited_with_state(EventState::empty(), local_name, namespace, prefix, document) } - pub fn new_inherited_with_flags(flags: NodeFlags, local_name: DOMString, + pub fn new_inherited_with_state(state: EventState, local_name: DOMString, namespace: Namespace, prefix: Option, document: &Document) -> Element { Element { - node: Node::new_inherited_with_flags(flags, document), + node: Node::new_inherited(document), local_name: Atom::from_slice(&local_name), namespace: namespace, prefix: prefix, @@ -134,6 +155,7 @@ impl Element { class_list: Default::default(), id_attribute: DOMRefCell::new(None), style_attribute: DOMRefCell::new(None), + event_state: Cell::new(state), } } @@ -225,6 +247,8 @@ pub trait LayoutElementHelpers { fn namespace(&self) -> &Namespace; fn get_checked_state_for_layout(&self) -> bool; fn get_indeterminate_state_for_layout(&self) -> bool; + + fn get_event_state_for_layout(&self) -> EventState; } impl LayoutElementHelpers for LayoutJS { @@ -575,6 +599,14 @@ impl LayoutElementHelpers for LayoutJS { None => false, } } + + #[inline] + #[allow(unsafe_code)] + fn get_event_state_for_layout(&self) -> EventState { + unsafe { + (*self.unsafe_get()).event_state.get() + } + } } #[derive(PartialEq, Eq, Copy, Clone, HeapSizeOf)] @@ -828,7 +860,7 @@ impl Element { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOptionElement)) => { - node.get_disabled_state() + self.get_disabled_state() } // TODO: // an optgroup element that has a disabled attribute @@ -1626,31 +1658,30 @@ impl<'a> ::selectors::Element for Root { fn get_namespace<'b>(&'b self) -> &'b Namespace { self.namespace() } + fn get_hover_state(&self) -> bool { - let node = NodeCast::from_ref(&**self); - node.get_hover_state() + Element::get_hover_state(self) } + fn get_active_state(&self) -> bool { - let node = NodeCast::from_ref(&**self); - node.get_active_state() + Element::get_active_state(self) } + fn get_focus_state(&self) -> bool { // TODO: Also check whether the top-level browsing context has the system focus, // and whether this element is a browsing context container. // https://html.spec.whatwg.org/multipage/#selector-focus - let node = NodeCast::from_ref(&**self); - node.get_focus_state() + Element::get_focus_state(self) } + fn get_id(&self) -> Option { self.id_attribute.borrow().clone() } fn get_disabled_state(&self) -> bool { - let node = NodeCast::from_ref(&**self); - node.get_disabled_state() + Element::get_disabled_state(self) } fn get_enabled_state(&self) -> bool { - let node = NodeCast::from_ref(&**self); - node.get_enabled_state() + Element::get_enabled_state(self) } fn get_checked_state(&self) -> bool { let input_element: Option<&HTMLInputElement> = HTMLInputElementCast::to_ref(&**self); @@ -1818,6 +1849,105 @@ impl Element { // Step 7 self.set_click_in_progress(false); } + + fn set_state(&self, which: EventState, value: bool) { + let mut state = self.event_state.get(); + match value { + true => state.insert(which), + false => state.remove(which), + }; + self.event_state.set(state); + + let node = NodeCast::from_ref(self); + node.dirty(NodeDamage::NodeStyleDamaged); + } + + pub fn get_active_state(&self) -> bool { + self.event_state.get().contains(IN_ACTIVE_STATE) + } + + pub fn set_active_state(&self, value: bool) { + self.set_state(IN_ACTIVE_STATE, value) + } + + pub fn get_focus_state(&self) -> bool { + self.event_state.get().contains(IN_FOCUS_STATE) + } + + pub fn set_focus_state(&self, value: bool) { + self.set_state(IN_FOCUS_STATE, value) + } + + pub fn get_hover_state(&self) -> bool { + self.event_state.get().contains(IN_HOVER_STATE) + } + + pub fn set_hover_state(&self, value: bool) { + self.set_state(IN_HOVER_STATE, value) + } + + pub fn get_enabled_state(&self) -> bool { + self.event_state.get().contains(IN_ENABLED_STATE) + } + + pub fn set_enabled_state(&self, value: bool) { + self.set_state(IN_ENABLED_STATE, value) + } + + pub fn get_disabled_state(&self) -> bool { + self.event_state.get().contains(IN_DISABLED_STATE) + } + + pub fn set_disabled_state(&self, value: bool) { + self.set_state(IN_DISABLED_STATE, value) + } +} + +impl Element { + pub fn check_ancestors_disabled_state_for_form_control(&self) { + let node = NodeCast::from_ref(self); + if self.get_disabled_state() { return; } + for ancestor in node.ancestors() { + let ancestor = ancestor; + let ancestor = ancestor.r(); + if !ancestor.is_htmlfieldsetelement() { continue; } + if !ElementCast::to_ref(ancestor).unwrap().get_disabled_state() { continue; } + if ancestor.is_parent_of(node) { + self.set_disabled_state(true); + self.set_enabled_state(false); + return; + } + match ancestor.children() + .find(|child| child.r().is_htmllegendelement()) + { + Some(ref legend) => { + // XXXabinader: should we save previous ancestor to avoid this iteration? + if node.ancestors().any(|ancestor| ancestor == *legend) { continue; } + }, + None => () + } + self.set_disabled_state(true); + self.set_enabled_state(false); + return; + } + } + + pub fn check_parent_disabled_state_for_option(&self) { + if self.get_disabled_state() { return; } + let node = NodeCast::from_ref(self); + if let Some(ref parent) = node.GetParentNode() { + if parent.r().is_htmloptgroupelement() && ElementCast::to_ref(parent.r()).unwrap().get_disabled_state() { + self.set_disabled_state(true); + self.set_enabled_state(false); + } + } + } + + pub fn check_disabled_attribute(&self) { + let has_disabled_attrib = self.has_attribute(&atom!("disabled")); + self.set_disabled_state(has_disabled_attrib); + self.set_enabled_state(!has_disabled_attrib); + } } #[derive(Clone, Copy, PartialEq)] diff --git a/servo/components/script/dom/htmlbuttonelement.rs b/servo/components/script/dom/htmlbuttonelement.rs index 104619aecbbb..c2538fd9bd2c 100644 --- a/servo/components/script/dom/htmlbuttonelement.rs +++ b/servo/components/script/dom/htmlbuttonelement.rs @@ -10,14 +10,13 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLButtonElementCast, H use dom::bindings::codegen::InheritTypes::{HTMLFieldSetElementDerived, NodeCast}; use dom::bindings::js::Root; use dom::document::Document; -use dom::element::{AttributeMutation, Element}; +use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE}; use dom::event::Event; use dom::eventtarget::EventTarget; use dom::htmlelement::HTMLElement; use dom::htmlformelement::{FormControl, FormSubmitter}; use dom::htmlformelement::{SubmittedFrom, HTMLFormElement}; -use dom::node::{IN_ENABLED_STATE, Node, NodeFlags}; -use dom::node::{document_from_node, window_from_node}; +use dom::node::{Node, document_from_node, window_from_node}; use dom::validitystate::ValidityState; use dom::virtualmethods::VirtualMethods; use std::ascii::AsciiExt; @@ -47,7 +46,7 @@ impl HTMLButtonElement { document: &Document) -> HTMLButtonElement { HTMLButtonElement { htmlelement: - HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE, + HTMLElement::new_inherited_with_state(IN_ENABLED_STATE, localName, prefix, document), //TODO: implement button_type in attribute_mutated button_type: Cell::new(ButtonType::ButtonSubmit) @@ -144,17 +143,17 @@ impl VirtualMethods for HTMLButtonElement { self.super_type().unwrap().attribute_mutated(attr, mutation); match attr.local_name() { &atom!(disabled) => { - let node = NodeCast::from_ref(self); + let el = ElementCast::from_ref(self); match mutation { AttributeMutation::Set(Some(_)) => {} AttributeMutation::Set(None) => { - node.set_disabled_state(true); - node.set_enabled_state(false); + el.set_disabled_state(true); + el.set_enabled_state(false); }, AttributeMutation::Removed => { - node.set_disabled_state(false); - node.set_enabled_state(true); - node.check_ancestors_disabled_state_for_form_control(); + el.set_disabled_state(false); + el.set_enabled_state(true); + el.check_ancestors_disabled_state_for_form_control(); } } }, @@ -167,8 +166,8 @@ impl VirtualMethods for HTMLButtonElement { s.bind_to_tree(tree_in_doc); } - let node = NodeCast::from_ref(self); - node.check_ancestors_disabled_state_for_form_control(); + let el = ElementCast::from_ref(self); + el.check_ancestors_disabled_state_for_form_control(); } fn unbind_from_tree(&self, tree_in_doc: bool) { @@ -177,10 +176,11 @@ impl VirtualMethods for HTMLButtonElement { } let node = NodeCast::from_ref(self); + let el = ElementCast::from_ref(self); if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) { - node.check_ancestors_disabled_state_for_form_control(); + el.check_ancestors_disabled_state_for_form_control(); } else { - node.check_disabled_attribute(); + el.check_disabled_attribute(); } } } @@ -194,8 +194,8 @@ impl<'a> Activatable for &'a HTMLButtonElement { fn is_instance_activatable(&self) -> bool { //https://html.spec.whatwg.org/multipage/#the-button-element - let node = NodeCast::from_ref(*self); - !(node.get_disabled_state()) + let el = ElementCast::from_ref(*self); + !(el.get_disabled_state()) } // https://html.spec.whatwg.org/multipage/#run-pre-click-activation-steps diff --git a/servo/components/script/dom/htmlelement.rs b/servo/components/script/dom/htmlelement.rs index 48154d250429..ae25eb3dc17a 100644 --- a/servo/components/script/dom/htmlelement.rs +++ b/servo/components/script/dom/htmlelement.rs @@ -20,9 +20,9 @@ use dom::bindings::utils::Reflectable; use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration}; use dom::document::Document; use dom::domstringmap::DOMStringMap; -use dom::element::{AttributeMutation, Element}; +use dom::element::{AttributeMutation, Element, EventState}; use dom::htmlinputelement::HTMLInputElement; -use dom::node::{Node, NodeFlags, SEQUENTIALLY_FOCUSABLE}; +use dom::node::{Node, SEQUENTIALLY_FOCUSABLE}; use dom::node::{document_from_node, window_from_node}; use dom::virtualmethods::VirtualMethods; use msg::constellation_msg::FocusType; @@ -49,15 +49,15 @@ impl PartialEq for HTMLElement { impl HTMLElement { pub fn new_inherited(tag_name: DOMString, prefix: Option, document: &Document) -> HTMLElement { - HTMLElement::new_inherited_with_flags(NodeFlags::new(), tag_name, prefix, document) + HTMLElement::new_inherited_with_state(EventState::empty(), tag_name, prefix, document) } - pub fn new_inherited_with_flags(flags: NodeFlags, tag_name: DOMString, + pub fn new_inherited_with_state(state: EventState, tag_name: DOMString, prefix: Option, document: &Document) -> HTMLElement { HTMLElement { element: - Element::new_inherited_with_flags(flags, tag_name, ns!(HTML), prefix, document), + Element::new_inherited_with_state(state, tag_name, ns!(HTML), prefix, document), style_decl: Default::default(), dataset: Default::default(), } @@ -194,8 +194,8 @@ impl HTMLElementMethods for HTMLElement { // https://html.spec.whatwg.org/multipage/#dom-blur fn Blur(&self) { // TODO: Run the unfocusing steps. - let node = NodeCast::from_ref(self); - if !node.get_focus_state() { + let el = ElementCast::from_ref(self); + if !el.get_focus_state() { return; } // https://html.spec.whatwg.org/multipage/#unfocusing-steps diff --git a/servo/components/script/dom/htmlfieldsetelement.rs b/servo/components/script/dom/htmlfieldsetelement.rs index c50f3bf67568..2eb696affb88 100644 --- a/servo/components/script/dom/htmlfieldsetelement.rs +++ b/servo/components/script/dom/htmlfieldsetelement.rs @@ -5,16 +5,16 @@ use dom::attr::Attr; use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding; use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding::HTMLFieldSetElementMethods; -use dom::bindings::codegen::InheritTypes::{ElementTypeId, HTMLElementCast}; +use dom::bindings::codegen::InheritTypes::{ElementCast, ElementTypeId, HTMLElementCast}; use dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, HTMLLegendElementDerived}; use dom::bindings::codegen::InheritTypes::{NodeCast, NodeTypeId}; use dom::bindings::js::{Root, RootedReference}; use dom::document::Document; -use dom::element::{AttributeMutation, Element}; +use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE}; use dom::htmlcollection::{CollectionFilter, HTMLCollection}; use dom::htmlelement::HTMLElement; use dom::htmlformelement::{FormControl, HTMLFormElement}; -use dom::node::{IN_ENABLED_STATE, Node, NodeFlags, window_from_node}; +use dom::node::{Node, window_from_node}; use dom::validitystate::ValidityState; use dom::virtualmethods::VirtualMethods; use util::str::{DOMString, StaticStringVec}; @@ -30,7 +30,7 @@ impl HTMLFieldSetElement { document: &Document) -> HTMLFieldSetElement { HTMLFieldSetElement { htmlelement: - HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE, + HTMLElement::new_inherited_with_state(IN_ENABLED_STATE, localName, prefix, document) } } @@ -99,8 +99,9 @@ impl VirtualMethods for HTMLFieldSetElement { AttributeMutation::Removed => false, }; let node = NodeCast::from_ref(self); - node.set_disabled_state(disabled_state); - node.set_enabled_state(!disabled_state); + let el = ElementCast::from_ref(self); + el.set_disabled_state(disabled_state); + el.set_enabled_state(!disabled_state); let mut found_legend = false; let children = node.children().filter(|node| { if found_legend { @@ -135,13 +136,15 @@ impl VirtualMethods for HTMLFieldSetElement { }); if disabled_state { for field in fields { - field.set_disabled_state(true); - field.set_enabled_state(false); + let el = ElementCast::to_ref(field.r()).unwrap(); + el.set_disabled_state(true); + el.set_enabled_state(false); } } else { for field in fields { - field.check_disabled_attribute(); - field.check_ancestors_disabled_state_for_form_control(); + let el = ElementCast::to_ref(field.r()).unwrap(); + el.check_disabled_attribute(); + el.check_ancestors_disabled_state_for_form_control(); } } }, diff --git a/servo/components/script/dom/htmlformelement.rs b/servo/components/script/dom/htmlformelement.rs index 46caced7d45d..8fa12c02c6c7 100644 --- a/servo/components/script/dom/htmlformelement.rs +++ b/servo/components/script/dom/htmlformelement.rs @@ -223,9 +223,11 @@ impl HTMLFormElement { // TODO: This is an incorrect way of getting controls owned // by the form, but good enough until html5ever lands node.traverse_preorder().filter_map(|child| { - if child.r().get_disabled_state() { - return None; + match ElementCast::to_ref(child.r()) { + Some(el) if !el.get_disabled_state() => (), + _ => return None, } + if child.r().ancestors() .any(|a| HTMLDataListElementCast::to_root(a).is_some()) { return None; diff --git a/servo/components/script/dom/htmlinputelement.rs b/servo/components/script/dom/htmlinputelement.rs index cdfe87167752..5d93d186a071 100644 --- a/servo/components/script/dom/htmlinputelement.rs +++ b/servo/components/script/dom/htmlinputelement.rs @@ -17,14 +17,14 @@ use dom::bindings::codegen::InheritTypes::{KeyboardEventCast, NodeCast}; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, LayoutJS, Root, RootedReference}; use dom::document::Document; -use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers}; +use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE, RawLayoutElementHelpers}; use dom::event::{Event, EventBubbles, EventCancelable}; use dom::eventtarget::EventTarget; use dom::htmlelement::HTMLElement; use dom::htmlformelement::{FormControl, FormDatum, FormSubmitter, HTMLFormElement}; use dom::htmlformelement::{ResetFrom, SubmittedFrom}; use dom::keyboardevent::KeyboardEvent; -use dom::node::{IN_ENABLED_STATE, Node, NodeDamage, NodeFlags}; +use dom::node::{Node, NodeDamage}; use dom::node::{document_from_node, window_from_node}; use dom::virtualmethods::VirtualMethods; use msg::constellation_msg::ConstellationChan; @@ -109,7 +109,7 @@ impl HTMLInputElement { let chan = document.window().r().constellation_chan(); HTMLInputElement { htmlelement: - HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE, + HTMLElement::new_inherited_with_state(IN_ENABLED_STATE, localName, prefix, document), input_type: Cell::new(InputType::InputText), checked: Cell::new(false), @@ -472,8 +472,8 @@ impl HTMLInputElement { fn mutable(&self) -> bool { // https://html.spec.whatwg.org/multipage/#the-input-element:concept-fe-mutable // https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable - let node = NodeCast::from_ref(self); - !(node.get_disabled_state() || self.ReadOnly()) + let el = ElementCast::from_ref(self); + !(el.get_disabled_state() || self.ReadOnly()) } // https://html.spec.whatwg.org/multipage/#the-input-element:concept-form-reset-control @@ -511,10 +511,10 @@ impl VirtualMethods for HTMLInputElement { }, AttributeMutation::Removed => false, }; - let node = NodeCast::from_ref(self); - node.set_disabled_state(disabled_state); - node.set_enabled_state(!disabled_state); - node.check_ancestors_disabled_state_for_form_control(); + let el = ElementCast::from_ref(self); + el.set_disabled_state(disabled_state); + el.set_enabled_state(!disabled_state); + el.check_ancestors_disabled_state_for_form_control(); }, &atom!(checked) if !self.checked_changed.get() => { let checked_state = match mutation { @@ -596,8 +596,8 @@ impl VirtualMethods for HTMLInputElement { s.bind_to_tree(tree_in_doc); } - let node = NodeCast::from_ref(self); - node.check_ancestors_disabled_state_for_form_control(); + let el = ElementCast::from_ref(self); + el.check_ancestors_disabled_state_for_form_control(); } fn unbind_from_tree(&self, tree_in_doc: bool) { @@ -606,10 +606,11 @@ impl VirtualMethods for HTMLInputElement { } let node = NodeCast::from_ref(self); + let el = ElementCast::from_ref(self); if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) { - node.check_ancestors_disabled_state_for_form_control(); + el.check_ancestors_disabled_state_for_form_control(); } else { - node.check_disabled_attribute(); + el.check_disabled_attribute(); } } diff --git a/servo/components/script/dom/htmloptgroupelement.rs b/servo/components/script/dom/htmloptgroupelement.rs index b90eacff87fb..cabb19936abc 100644 --- a/servo/components/script/dom/htmloptgroupelement.rs +++ b/servo/components/script/dom/htmloptgroupelement.rs @@ -5,12 +5,13 @@ use dom::attr::Attr; use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding; use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding::HTMLOptGroupElementMethods; -use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLOptionElementDerived, NodeCast}; +use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLOptionElementCast}; +use dom::bindings::codegen::InheritTypes::{HTMLOptionElementDerived, NodeCast}; use dom::bindings::js::Root; use dom::document::Document; -use dom::element::AttributeMutation; +use dom::element::{AttributeMutation, IN_ENABLED_STATE}; use dom::htmlelement::HTMLElement; -use dom::node::{IN_ENABLED_STATE, Node, NodeFlags}; +use dom::node::{Node}; use dom::virtualmethods::VirtualMethods; use util::str::DOMString; @@ -25,7 +26,7 @@ impl HTMLOptGroupElement { document: &Document) -> HTMLOptGroupElement { HTMLOptGroupElement { htmlelement: - HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE, + HTMLElement::new_inherited_with_state(IN_ENABLED_STATE, localName, prefix, document) } } @@ -66,19 +67,22 @@ impl VirtualMethods for HTMLOptGroupElement { AttributeMutation::Removed => false, }; let node = NodeCast::from_ref(self); - node.set_disabled_state(disabled_state); - node.set_enabled_state(!disabled_state); + let el = ElementCast::from_ref(self); + el.set_disabled_state(disabled_state); + el.set_enabled_state(!disabled_state); let options = node.children().filter(|child| { child.is_htmloptionelement() - }); + }).map(|child| Root::from_ref(HTMLOptionElementCast::to_ref(child.r()).unwrap())); if disabled_state { for option in options { - option.set_disabled_state(true); - option.set_enabled_state(false); + let el = ElementCast::from_ref(option.r()); + el.set_disabled_state(true); + el.set_enabled_state(false); } } else { for option in options { - option.check_disabled_attribute(); + let el = ElementCast::from_ref(option.r()); + el.check_disabled_attribute(); } } }, diff --git a/servo/components/script/dom/htmloptionelement.rs b/servo/components/script/dom/htmloptionelement.rs index 74454c143551..b84fc43af341 100644 --- a/servo/components/script/dom/htmloptionelement.rs +++ b/servo/components/script/dom/htmloptionelement.rs @@ -12,9 +12,9 @@ use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLScriptElementDer use dom::bindings::codegen::InheritTypes::{NodeCast, TextDerived}; use dom::bindings::js::Root; use dom::document::Document; -use dom::element::{AttributeMutation, Element}; +use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE}; use dom::htmlelement::HTMLElement; -use dom::node::{IN_ENABLED_STATE, Node, NodeFlags}; +use dom::node::{Node}; use dom::virtualmethods::VirtualMethods; use std::cell::Cell; use util::str::{DOMString, split_html_space_chars, str_join}; @@ -36,7 +36,7 @@ impl HTMLOptionElement { document: &Document) -> HTMLOptionElement { HTMLOptionElement { htmlelement: - HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE, + HTMLElement::new_inherited_with_state(IN_ENABLED_STATE, localName, prefix, document), selectedness: Cell::new(false), dirtiness: Cell::new(false), @@ -151,16 +151,16 @@ impl VirtualMethods for HTMLOptionElement { self.super_type().unwrap().attribute_mutated(attr, mutation); match attr.local_name() { &atom!(disabled) => { - let node = NodeCast::from_ref(self); + let el = ElementCast::from_ref(self); match mutation { AttributeMutation::Set(_) => { - node.set_disabled_state(true); - node.set_enabled_state(false); + el.set_disabled_state(true); + el.set_enabled_state(false); }, AttributeMutation::Removed => { - node.set_disabled_state(false); - node.set_enabled_state(true); - node.check_parent_disabled_state_for_option(); + el.set_disabled_state(false); + el.set_enabled_state(true); + el.check_parent_disabled_state_for_option(); } } }, @@ -189,8 +189,8 @@ impl VirtualMethods for HTMLOptionElement { s.bind_to_tree(tree_in_doc); } - let node = NodeCast::from_ref(self); - node.check_parent_disabled_state_for_option(); + let el = ElementCast::from_ref(self); + el.check_parent_disabled_state_for_option(); } fn unbind_from_tree(&self, tree_in_doc: bool) { @@ -199,10 +199,11 @@ impl VirtualMethods for HTMLOptionElement { } let node = NodeCast::from_ref(self); + let el = ElementCast::from_ref(self); if node.GetParentNode().is_some() { - node.check_parent_disabled_state_for_option(); + el.check_parent_disabled_state_for_option(); } else { - node.check_disabled_attribute(); + el.check_disabled_attribute(); } } } diff --git a/servo/components/script/dom/htmlselectelement.rs b/servo/components/script/dom/htmlselectelement.rs index 33a46acace14..878bfe2538cf 100644 --- a/servo/components/script/dom/htmlselectelement.rs +++ b/servo/components/script/dom/htmlselectelement.rs @@ -5,15 +5,15 @@ use dom::attr::{Attr, AttrValue}; use dom::bindings::codegen::Bindings::HTMLSelectElementBinding; use dom::bindings::codegen::Bindings::HTMLSelectElementBinding::HTMLSelectElementMethods; -use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLFieldSetElementDerived, NodeCast}; +use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLFieldSetElementDerived, NodeCast}; use dom::bindings::codegen::UnionTypes::HTMLElementOrLong; use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement; use dom::bindings::js::Root; use dom::document::Document; -use dom::element::AttributeMutation; +use dom::element::{AttributeMutation, IN_ENABLED_STATE}; use dom::htmlelement::HTMLElement; use dom::htmlformelement::{FormControl, HTMLFormElement}; -use dom::node::{IN_ENABLED_STATE, Node, NodeFlags, window_from_node}; +use dom::node::{Node, window_from_node}; use dom::validitystate::ValidityState; use dom::virtualmethods::VirtualMethods; use std::borrow::ToOwned; @@ -33,7 +33,7 @@ impl HTMLSelectElement { document: &Document) -> HTMLSelectElement { HTMLSelectElement { htmlelement: - HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE, + HTMLElement::new_inherited_with_state(IN_ENABLED_STATE, localName, prefix, document) } } @@ -107,16 +107,16 @@ impl VirtualMethods for HTMLSelectElement { fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { self.super_type().unwrap().attribute_mutated(attr, mutation); if attr.local_name() == &atom!(disabled) { - let node = NodeCast::from_ref(self); + let el = ElementCast::from_ref(self); match mutation { AttributeMutation::Set(_) => { - node.set_disabled_state(true); - node.set_enabled_state(false); + el.set_disabled_state(true); + el.set_enabled_state(false); }, AttributeMutation::Removed => { - node.set_disabled_state(false); - node.set_enabled_state(true); - node.check_ancestors_disabled_state_for_form_control(); + el.set_disabled_state(false); + el.set_enabled_state(true); + el.check_ancestors_disabled_state_for_form_control(); } } } @@ -127,8 +127,8 @@ impl VirtualMethods for HTMLSelectElement { s.bind_to_tree(tree_in_doc); } - let node = NodeCast::from_ref(self); - node.check_ancestors_disabled_state_for_form_control(); + let el = ElementCast::from_ref(self); + el.check_ancestors_disabled_state_for_form_control(); } fn unbind_from_tree(&self, tree_in_doc: bool) { @@ -137,10 +137,11 @@ impl VirtualMethods for HTMLSelectElement { } let node = NodeCast::from_ref(self); + let el = ElementCast::from_ref(self); if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) { - node.check_ancestors_disabled_state_for_form_control(); + el.check_ancestors_disabled_state_for_form_control(); } else { - node.check_disabled_attribute(); + el.check_disabled_attribute(); } } diff --git a/servo/components/script/dom/htmltextareaelement.rs b/servo/components/script/dom/htmltextareaelement.rs index 19cd81e65190..8982fda94a14 100644 --- a/servo/components/script/dom/htmltextareaelement.rs +++ b/servo/components/script/dom/htmltextareaelement.rs @@ -15,13 +15,13 @@ use dom::bindings::global::GlobalRef; use dom::bindings::js::{LayoutJS, Root}; use dom::bindings::refcounted::Trusted; use dom::document::Document; -use dom::element::AttributeMutation; +use dom::element::{AttributeMutation, IN_ENABLED_STATE}; use dom::event::{Event, EventBubbles, EventCancelable}; use dom::htmlelement::HTMLElement; use dom::htmlformelement::{FormControl, HTMLFormElement}; use dom::keyboardevent::KeyboardEvent; -use dom::node::{ChildrenMutation, IN_ENABLED_STATE, Node, NodeDamage}; -use dom::node::{NodeFlags, document_from_node, window_from_node}; +use dom::node::{ChildrenMutation, Node, NodeDamage}; +use dom::node::{document_from_node, window_from_node}; use dom::virtualmethods::VirtualMethods; use msg::constellation_msg::ConstellationChan; use script_task::ScriptTaskEventCategory::InputEvent; @@ -87,7 +87,7 @@ impl HTMLTextAreaElement { let chan = document.window().r().constellation_chan(); HTMLTextAreaElement { htmlelement: - HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE, + HTMLElement::new_inherited_with_state(IN_ENABLED_STATE, localName, prefix, document), textinput: DOMRefCell::new(TextInput::new(Lines::Multiple, "".to_owned(), chan)), cols: Cell::new(DEFAULT_COLS), @@ -245,16 +245,16 @@ impl VirtualMethods for HTMLTextAreaElement { self.super_type().unwrap().attribute_mutated(attr, mutation); match attr.local_name() { &atom!(disabled) => { - let node = NodeCast::from_ref(self); + let el = ElementCast::from_ref(self); match mutation { AttributeMutation::Set(_) => { - node.set_disabled_state(true); - node.set_enabled_state(false); + el.set_disabled_state(true); + el.set_enabled_state(false); }, AttributeMutation::Removed => { - node.set_disabled_state(false); - node.set_enabled_state(true); - node.check_ancestors_disabled_state_for_form_control(); + el.set_disabled_state(false); + el.set_enabled_state(true); + el.check_ancestors_disabled_state_for_form_control(); } } }, @@ -279,8 +279,8 @@ impl VirtualMethods for HTMLTextAreaElement { s.bind_to_tree(tree_in_doc); } - let node = NodeCast::from_ref(self); - node.check_ancestors_disabled_state_for_form_control(); + let el = ElementCast::from_ref(self); + el.check_ancestors_disabled_state_for_form_control(); } fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue { @@ -297,10 +297,11 @@ impl VirtualMethods for HTMLTextAreaElement { } let node = NodeCast::from_ref(self); + let el = ElementCast::from_ref(self); if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) { - node.check_ancestors_disabled_state_for_form_control(); + el.check_ancestors_disabled_state_for_form_control(); } else { - node.check_disabled_attribute(); + el.check_disabled_attribute(); } } diff --git a/servo/components/script/dom/node.rs b/servo/components/script/dom/node.rs index 7fbb409daca4..36f6fd04bcc4 100644 --- a/servo/components/script/dom/node.rs +++ b/servo/components/script/dom/node.rs @@ -25,8 +25,7 @@ use dom::bindings::codegen::InheritTypes::{CharacterDataCast, CharacterDataTypeI use dom::bindings::codegen::InheritTypes::{DocumentCast, DocumentDerived, DocumentTypeCast}; use dom::bindings::codegen::InheritTypes::{ElementCast, ElementDerived, ElementTypeId}; use dom::bindings::codegen::InheritTypes::{EventTargetCast, EventTargetTypeId}; -use dom::bindings::codegen::InheritTypes::{HTMLElementTypeId, HTMLFieldSetElementDerived}; -use dom::bindings::codegen::InheritTypes::{HTMLLegendElementDerived, HTMLOptGroupElementDerived}; +use dom::bindings::codegen::InheritTypes::{HTMLElementTypeId}; use dom::bindings::codegen::InheritTypes::{NodeBase, NodeCast, NodeTypeId}; use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, TextCast, TextDerived}; use dom::bindings::codegen::UnionTypes::NodeOrString; @@ -130,40 +129,28 @@ impl PartialEq for Node { bitflags! { #[doc = "Flags for node items."] #[derive(JSTraceable, HeapSizeOf)] - flags NodeFlags: u16 { + flags NodeFlags: u8 { #[doc = "Specifies whether this node is in a document."] const IS_IN_DOC = 0x01, - #[doc = "Specifies whether this node is in hover state."] - const IN_HOVER_STATE = 0x02, - #[doc = "Specifies whether this node is in disabled state."] - const IN_DISABLED_STATE = 0x04, - #[doc = "Specifies whether this node is in enabled state."] - const IN_ENABLED_STATE = 0x08, #[doc = "Specifies whether this node _must_ be reflowed regardless of style differences."] - const HAS_CHANGED = 0x10, + const HAS_CHANGED = 0x02, #[doc = "Specifies whether this node needs style recalc on next reflow."] - const IS_DIRTY = 0x20, + const IS_DIRTY = 0x04, #[doc = "Specifies whether this node has siblings (inclusive of itself) which \ changed since the last reflow."] - const HAS_DIRTY_SIBLINGS = 0x40, + const HAS_DIRTY_SIBLINGS = 0x08, #[doc = "Specifies whether this node has descendants (inclusive of itself) which \ have changed since the last reflow."] - const HAS_DIRTY_DESCENDANTS = 0x80, + const HAS_DIRTY_DESCENDANTS = 0x10, // TODO: find a better place to keep this (#4105) // https://critic.hoppipolla.co.uk/showcomment?chain=8873 // Perhaps using a Set in Document? #[doc = "Specifies whether or not there is an authentic click in progress on \ this element."] - const CLICK_IN_PROGRESS = 0x100, - #[doc = "Specifies whether this node has the focus."] - const IN_FOCUS_STATE = 0x200, + const CLICK_IN_PROGRESS = 0x20, #[doc = "Specifies whether this node is focusable and whether it is supposed \ to be reachable with using sequential focus navigation."] - const SEQUENTIALLY_FOCUSABLE = 0x400, - #[doc = "Specifies whether this node is [being activated]\ - (https://html.spec.whatwg.org/multipage/#selector-active). \ - FIXME(#7333): set/unset this when appropriate"] - const IN_ACTIVE_STATE = 0x800, + const SEQUENTIALLY_FOCUSABLE = 0x40, } } @@ -479,49 +466,6 @@ impl Node { self.flags.set(flags); } - pub fn get_hover_state(&self) -> bool { - self.get_flag(IN_HOVER_STATE) - } - - pub fn set_hover_state(&self, state: bool) { - self.set_flag(IN_HOVER_STATE, state); - self.dirty(NodeDamage::NodeStyleDamaged); - } - - pub fn get_focus_state(&self) -> bool { - self.get_flag(IN_FOCUS_STATE) - } - - pub fn set_focus_state(&self, state: bool) { - self.set_flag(IN_FOCUS_STATE, state); - self.dirty(NodeDamage::NodeStyleDamaged); - } - - pub fn get_active_state(&self) -> bool { - self.get_flag(IN_ACTIVE_STATE) - } - - pub fn set_active_state(&self, state: bool) { - self.set_flag(IN_ACTIVE_STATE, state); - self.dirty(NodeDamage::NodeStyleDamaged); - } - - pub fn get_disabled_state(&self) -> bool { - self.get_flag(IN_DISABLED_STATE) - } - - pub fn set_disabled_state(&self, state: bool) { - self.set_flag(IN_DISABLED_STATE, state) - } - - pub fn get_enabled_state(&self) -> bool { - self.get_flag(IN_ENABLED_STATE) - } - - pub fn set_enabled_state(&self, state: bool) { - self.set_flag(IN_ENABLED_STATE, state) - } - pub fn get_has_changed(&self) -> bool { self.get_flag(HAS_CHANGED) } @@ -1040,12 +984,6 @@ pub trait LayoutNodeHelpers { unsafe fn layout_data(&self) -> Ref>; unsafe fn layout_data_mut(&self) -> RefMut>; unsafe fn layout_data_unchecked(&self) -> *const Option; - - fn get_hover_state_for_layout(&self) -> bool; - fn get_focus_state_for_layout(&self) -> bool; - fn get_active_state_for_layout(&self) -> bool; - fn get_disabled_state_for_layout(&self) -> bool; - fn get_enabled_state_for_layout(&self) -> bool; } impl LayoutNodeHelpers for LayoutJS { @@ -1141,42 +1079,6 @@ impl LayoutNodeHelpers for LayoutJS { unsafe fn layout_data_unchecked(&self) -> *const Option { (*self.unsafe_get()).layout_data.borrow_unchecked() } - - #[inline] - #[allow(unsafe_code)] - fn get_hover_state_for_layout(&self) -> bool { - unsafe { - self.get_flag(IN_HOVER_STATE) - } - } - #[inline] - #[allow(unsafe_code)] - fn get_focus_state_for_layout(&self) -> bool { - unsafe { - self.get_flag(IN_FOCUS_STATE) - } - } - #[inline] - #[allow(unsafe_code)] - fn get_active_state_for_layout(&self) -> bool { - unsafe { - self.get_flag(IN_ACTIVE_STATE) - } - } - #[inline] - #[allow(unsafe_code)] - fn get_disabled_state_for_layout(&self) -> bool { - unsafe { - self.get_flag(IN_DISABLED_STATE) - } - } - #[inline] - #[allow(unsafe_code)] - fn get_enabled_state_for_layout(&self) -> bool { - unsafe { - self.get_flag(IN_ENABLED_STATE) - } - } } @@ -1410,11 +1312,7 @@ impl Node { } pub fn new_inherited(doc: &Document) -> Node { - Node::new_inherited_with_flags(NodeFlags::new(), doc) - } - - pub fn new_inherited_with_flags(flags: NodeFlags, doc: &Document) -> Node { - Node::new_(flags, Some(doc)) + Node::new_(NodeFlags::new(), Some(doc)) } #[allow(unrooted_must_root)] @@ -2527,53 +2425,6 @@ impl VirtualMethods for Node { } } - -impl Node { - pub fn check_ancestors_disabled_state_for_form_control(&self) { - if self.get_disabled_state() { return; } - for ancestor in self.ancestors() { - let ancestor = ancestor; - let ancestor = ancestor.r(); - if !ancestor.is_htmlfieldsetelement() { continue; } - if !ancestor.get_disabled_state() { continue; } - if ancestor.is_parent_of(self) { - self.set_disabled_state(true); - self.set_enabled_state(false); - return; - } - match ancestor.children() - .find(|child| child.r().is_htmllegendelement()) - { - Some(ref legend) => { - // XXXabinader: should we save previous ancestor to avoid this iteration? - if self.ancestors().any(|ancestor| ancestor == *legend) { continue; } - }, - None => () - } - self.set_disabled_state(true); - self.set_enabled_state(false); - return; - } - } - - pub fn check_parent_disabled_state_for_option(&self) { - if self.get_disabled_state() { return; } - if let Some(ref parent) = self.GetParentNode() { - if parent.r().is_htmloptgroupelement() && parent.r().get_disabled_state() { - self.set_disabled_state(true); - self.set_enabled_state(false); - } - } - } - - pub fn check_disabled_attribute(&self) { - let elem = ElementCast::to_ref(self).unwrap(); - let has_disabled_attrib = elem.has_attribute(&atom!("disabled")); - self.set_disabled_state(has_disabled_attrib); - self.set_enabled_state(!has_disabled_attrib); - } -} - /// A summary of the changes that happened to a node. #[derive(Copy, Clone, PartialEq, HeapSizeOf)] pub enum NodeDamage { diff --git a/servo/components/script/script_task.rs b/servo/components/script/script_task.rs index 409b2aa863c8..0caed8f074f3 100644 --- a/servo/components/script/script_task.rs +++ b/servo/components/script/script_task.rs @@ -36,7 +36,7 @@ use dom::document::{Document, DocumentProgressHandler, IsHTMLDocument}; use dom::document::{DocumentProgressTask, DocumentSource, MouseEventType}; use dom::element::Element; use dom::event::{EventBubbles, EventCancelable}; -use dom::node::{Node, NodeDamage, window_from_node}; +use dom::node::{NodeDamage, window_from_node}; use dom::servohtmlparser::{ParserContext, ServoHTMLParser}; use dom::uievent::UIEvent; use dom::window::{ReflowReason, ScriptHelpers, Window}; @@ -406,7 +406,7 @@ pub struct ScriptTask { /// The JavaScript runtime. js_runtime: Rc, - mouse_over_targets: DOMRefCell>>, + mouse_over_targets: DOMRefCell>>, /// List of pipelines that have been owned and closed by this script task. closed_pipelines: RefCell>, @@ -1718,7 +1718,7 @@ impl ScriptTask { let page = get_page(&self.root_page(), pipeline_id); let document = page.document(); - let mut prev_mouse_over_targets: RootedVec> = RootedVec::new(); + let mut prev_mouse_over_targets: RootedVec> = RootedVec::new(); for target in &*self.mouse_over_targets.borrow_mut() { prev_mouse_over_targets.push(target.clone()); } @@ -1732,7 +1732,7 @@ impl ScriptTask { // Notify Constellation about anchors that are no longer mouse over targets. for target in &*prev_mouse_over_targets { if !mouse_over_targets.contains(target) { - if target.root().r().is_anchor_element() { + if NodeCast::from_ref(target.root().r()).is_anchor_element() { let event = ConstellationMsg::NodeStatus(None); let ConstellationChan(ref chan) = self.constellation_chan; chan.send(event).unwrap(); @@ -1744,9 +1744,8 @@ impl ScriptTask { // Notify Constellation about the topmost anchor mouse over target. for target in &*mouse_over_targets { let target = target.root(); - if target.r().is_anchor_element() { - let element = ElementCast::to_ref(target.r()).unwrap(); - let status = element.get_attribute(&ns!(""), &atom!("href")) + if NodeCast::from_ref(target.r()).is_anchor_element() { + let status = target.r().get_attribute(&ns!(""), &atom!("href")) .and_then(|href| { let value = href.value(); let url = document.r().url(); diff --git a/servo/tests/unit/script/size_of.rs b/servo/tests/unit/script/size_of.rs index 7b385cdfee98..b89ca9dd837f 100644 --- a/servo/tests/unit/script/size_of.rs +++ b/servo/tests/unit/script/size_of.rs @@ -39,9 +39,9 @@ macro_rules! sizeof_checker ( // Update the sizes here sizeof_checker!(size_event_target, EventTarget, 40); sizeof_checker!(size_node, Node, 168); -sizeof_checker!(size_element, Element, 304); -sizeof_checker!(size_htmlelement, HTMLElement, 320); -sizeof_checker!(size_div, HTMLDivElement, 320); -sizeof_checker!(size_span, HTMLSpanElement, 320); +sizeof_checker!(size_element, Element, 312); +sizeof_checker!(size_htmlelement, HTMLElement, 328); +sizeof_checker!(size_div, HTMLDivElement, 328); +sizeof_checker!(size_span, HTMLSpanElement, 328); sizeof_checker!(size_text, Text, 200); sizeof_checker!(size_characterdata, CharacterData, 200);