diff options
author | Bruno de Oliveira Abinader <bruno.d@partner.samsung.com> | 2014-06-27 16:06:27 -0400 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno.d@partner.samsung.com> | 2014-08-05 11:01:53 -0400 |
commit | 10a20e69fd51a734b71db0203601308da7712c96 (patch) | |
tree | 186d53f79f671c70ef7372f7e7d79e2e56ad7d9a | |
parent | 7771350898ae1dd8e81dd1863da431e8cc7486e3 (diff) | |
download | servo-10a20e69fd51a734b71db0203601308da7712c96.tar.gz servo-10a20e69fd51a734b71db0203601308da7712c96.zip |
Implement support for :enabled CSS selector
-rw-r--r-- | src/components/layout/wrapper.rs | 6 | ||||
-rw-r--r-- | src/components/script/dom/element.rs | 4 | ||||
-rw-r--r-- | src/components/script/dom/node.rs | 49 | ||||
-rw-r--r-- | src/components/style/node.rs | 1 | ||||
-rw-r--r-- | src/components/style/selector_matching.rs | 6 | ||||
-rw-r--r-- | src/components/style/selectors.rs | 4 |
6 files changed, 66 insertions, 4 deletions
diff --git a/src/components/layout/wrapper.rs b/src/components/layout/wrapper.rs index 026857d9ad7..9d1884579da 100644 --- a/src/components/layout/wrapper.rs +++ b/src/components/layout/wrapper.rs @@ -404,6 +404,12 @@ impl<'le> TElement for LayoutElement<'le> { self.element.node.get_disabled_state_for_layout() } } + + fn get_enabled_state(&self) -> bool { + unsafe { + self.element.node.get_enabled_state_for_layout() + } + } } fn get_content(content_list: &content::T) -> String { diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index a95d1ff8cc1..354d6a66a1b 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -950,4 +950,8 @@ impl<'a> style::TElement for JSRef<'a, Element> { let node: &JSRef<Node> = NodeCast::from_ref(self); node.get_disabled_state() } + fn get_enabled_state(&self) -> bool { + let node: &JSRef<Node> = NodeCast::from_ref(self); + node.get_enabled_state() + } } diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 425d3b95ef5..8b9f6ce3061 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -32,7 +32,10 @@ use dom::document::{Document, DocumentHelpers, HTMLDocument, NonHTMLDocument}; use dom::documentfragment::DocumentFragment; use dom::documenttype::DocumentType; use dom::element::{AttributeHandlers, Element, ElementTypeId}; -use dom::element::{HTMLAnchorElementTypeId, ElementHelpers}; +use dom::element::{HTMLAnchorElementTypeId, HTMLButtonElementTypeId, ElementHelpers}; +use dom::element::{HTMLInputElementTypeId, HTMLSelectElementTypeId}; +use dom::element::{HTMLTextAreaElementTypeId, HTMLOptGroupElementTypeId}; +use dom::element::{HTMLOptionElementTypeId, HTMLFieldSetElementTypeId}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::nodelist::{NodeList}; use dom::processinginstruction::ProcessingInstruction; @@ -128,7 +131,9 @@ bitflags! { #[doc = "Specifies whether this node is in hover state."] static InHoverState = 0x02, #[doc = "Specifies whether this node is in disabled state."] - static InDisabledState = 0x04 + static InDisabledState = 0x04, + #[doc = "Specifies whether this node is in enabled state."] + static InEnabledState = 0x08 } } @@ -390,6 +395,9 @@ pub trait NodeHelpers { fn get_disabled_state(&self) -> bool; fn set_disabled_state(&self, state: bool); + fn get_enabled_state(&self) -> bool; + fn set_enabled_state(&self, state: bool); + fn dump(&self); fn dump_indent(&self, indent: uint); fn debug_str(&self) -> String; @@ -519,6 +527,18 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { } } + fn get_enabled_state(&self) -> bool { + self.flags.deref().borrow().contains(InEnabledState) + } + + fn set_enabled_state(&self, state: bool) { + if state { + self.flags.deref().borrow_mut().insert(InEnabledState); + } else { + self.flags.deref().borrow_mut().remove(InEnabledState); + } + } + /// Iterates over this node and all its descendants, in preorder. fn traverse_preorder<'a>(&'a self) -> TreeIterator<'a> { let mut nodes = vec!(); @@ -748,6 +768,7 @@ impl LayoutNodeHelpers for JS<Node> { pub trait RawLayoutNodeHelpers { unsafe fn get_hover_state_for_layout(&self) -> bool; unsafe fn get_disabled_state_for_layout(&self) -> bool; + unsafe fn get_enabled_state_for_layout(&self) -> bool; } impl RawLayoutNodeHelpers for Node { @@ -757,6 +778,9 @@ impl RawLayoutNodeHelpers for Node { unsafe fn get_disabled_state_for_layout(&self) -> bool { self.flags.deref().borrow().contains(InDisabledState) } + unsafe fn get_enabled_state_for_layout(&self) -> bool { + self.flags.deref().borrow().contains(InEnabledState) + } } @@ -949,7 +973,7 @@ impl Node { } fn new_(type_id: NodeTypeId, doc: Option<JSRef<Document>>) -> Node { - Node { + let node = Node { eventtarget: EventTarget::new_inherited(NodeTargetTypeId(type_id)), type_id: type_id, @@ -964,7 +988,22 @@ impl Node { flags: Traceable::new(RefCell::new(NodeFlags::new(type_id))), layout_data: LayoutDataRef::new(), + }; + match type_id { + // The following elements are enabled by default. + ElementNodeTypeId(HTMLButtonElementTypeId) | + ElementNodeTypeId(HTMLInputElementTypeId) | + ElementNodeTypeId(HTMLSelectElementTypeId) | + ElementNodeTypeId(HTMLTextAreaElementTypeId) | + ElementNodeTypeId(HTMLOptGroupElementTypeId) | + ElementNodeTypeId(HTMLOptionElementTypeId) | + //ElementNodeTypeId(HTMLMenuItemElementTypeId) | + ElementNodeTypeId(HTMLFieldSetElementTypeId) => { + node.flags.deref().borrow_mut().insert(InEnabledState); + }, + _ => () } + node } // http://dom.spec.whatwg.org/#concept-node-adopt @@ -2003,6 +2042,7 @@ impl<'a> DisabledStateHelpers for JSRef<'a, Node> { 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.is_htmllegendelement()) { @@ -2013,6 +2053,7 @@ impl<'a> DisabledStateHelpers for JSRef<'a, Node> { None => () } self.set_disabled_state(true); + self.set_enabled_state(false); return; } } @@ -2022,6 +2063,7 @@ impl<'a> DisabledStateHelpers for JSRef<'a, Node> { match self.parent_node().root() { Some(ref parent) if parent.is_htmloptgroupelement() && parent.get_disabled_state() => { self.set_disabled_state(true); + self.set_enabled_state(false); }, _ => () } @@ -2031,5 +2073,6 @@ impl<'a> DisabledStateHelpers for JSRef<'a, Node> { let elem: &JSRef<'a, Element> = ElementCast::to_ref(self).unwrap(); let has_disabled_attrib = elem.has_attribute("disabled"); self.set_disabled_state(has_disabled_attrib); + self.set_enabled_state(!has_disabled_attrib); } } diff --git a/src/components/style/node.rs b/src/components/style/node.rs index b98d9651fca..9e8da53100a 100644 --- a/src/components/style/node.rs +++ b/src/components/style/node.rs @@ -28,5 +28,6 @@ pub trait TElement { fn get_hover_state(&self) -> bool; fn get_id(&self) -> Option<Atom>; fn get_disabled_state(&self) -> bool; + fn get_enabled_state(&self) -> bool; } diff --git a/src/components/style/selector_matching.rs b/src/components/style/selector_matching.rs index 5a2b3798ff9..2ca288f2f6c 100644 --- a/src/components/style/selector_matching.rs +++ b/src/components/style/selector_matching.rs @@ -784,6 +784,12 @@ fn matches_simple_selector<E:TElement, let elem = element.as_element(); elem.get_disabled_state() }, + // http://www.whatwg.org/html/#selector-enabled + Enabled => { + *shareable = false; + let elem = element.as_element(); + elem.get_enabled_state() + }, FirstChild => { *shareable = false; matches_first_child(element) diff --git a/src/components/style/selectors.rs b/src/components/style/selectors.rs index c1d7bf0b892..e18ad0556a9 100644 --- a/src/components/style/selectors.rs +++ b/src/components/style/selectors.rs @@ -78,6 +78,7 @@ pub enum SimpleSelector { Visited, Hover, Disabled, + Enabled, FirstChild, LastChild, OnlyChild, // Empty, Root, @@ -219,7 +220,7 @@ fn compute_specificity(mut selector: &CompoundSelector, &ClassSelector(..) | &AttrExists(..) | &AttrEqual(..) | &AttrIncludes(..) | &AttrDashMatch(..) | &AttrPrefixMatch(..) | &AttrSubstringMatch(..) | &AttrSuffixMatch(..) - | &AnyLink | &Link | &Visited | &Hover | &Disabled + | &AnyLink | &Link | &Visited | &Hover | &Disabled | &Enabled | &FirstChild | &LastChild | &OnlyChild | &Root // | &Empty | &Lang(*) | &NthChild(..) | &NthLastChild(..) @@ -481,6 +482,7 @@ fn parse_simple_pseudo_class(name: &str) -> Option<SimpleSelector> { "visited" => Some(Visited), "hover" => Some(Hover), "disabled" => Some(Disabled), + "enabled" => Some(Enabled), "first-child" => Some(FirstChild), "last-child" => Some(LastChild), "only-child" => Some(OnlyChild), |