diff options
author | Bruno de Oliveira Abinader <bruno.d@partner.samsung.com> | 2014-06-27 15:25:09 -0400 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno.d@partner.samsung.com> | 2014-08-05 11:01:53 -0400 |
commit | 7771350898ae1dd8e81dd1863da431e8cc7486e3 (patch) | |
tree | f53c25429020386995afac1ea043211c7616f790 /src/components/script/dom/node.rs | |
parent | 40048b791c44a0ef250d09633af38be0a9f257fd (diff) | |
download | servo-7771350898ae1dd8e81dd1863da431e8cc7486e3.tar.gz servo-7771350898ae1dd8e81dd1863da431e8cc7486e3.zip |
Implement support for :disabled CSS selector
Diffstat (limited to 'src/components/script/dom/node.rs')
-rw-r--r-- | src/components/script/dom/node.rs | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index a73c4d7e879..425d3b95ef5 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -16,6 +16,8 @@ use dom::bindings::codegen::InheritTypes::{CommentCast, DocumentCast, DocumentTy use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, NodeCast, ElementDerived}; use dom::bindings::codegen::InheritTypes::{CharacterDataCast, NodeBase, NodeDerived}; use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, EventTargetCast}; +use dom::bindings::codegen::InheritTypes::{HTMLLegendElementDerived, HTMLFieldSetElementDerived}; +use dom::bindings::codegen::InheritTypes::HTMLOptGroupElementDerived; use dom::bindings::error::{ErrorResult, Fallible, NotFound, HierarchyRequest, Syntax}; use dom::bindings::global::{GlobalRef, Window}; use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, Root, OptionalUnrootable}; @@ -123,8 +125,10 @@ bitflags! { flags NodeFlags: u8 { #[doc = "Specifies whether this node is in a document."] static IsInDoc = 0x01, - #[doc = "Specifies whether this node is hover state for this node"] - static InHoverState = 0x02 + #[doc = "Specifies whether this node is in hover state."] + static InHoverState = 0x02, + #[doc = "Specifies whether this node is in disabled state."] + static InDisabledState = 0x04 } } @@ -383,6 +387,9 @@ pub trait NodeHelpers { fn get_hover_state(&self) -> bool; fn set_hover_state(&self, state: bool); + fn get_disabled_state(&self) -> bool; + fn set_disabled_state(&self, state: bool); + fn dump(&self); fn dump_indent(&self, indent: uint); fn debug_str(&self) -> String; @@ -500,6 +507,18 @@ impl<'a> NodeHelpers for JSRef<'a, Node> { } } + fn get_disabled_state(&self) -> bool { + self.flags.deref().borrow().contains(InDisabledState) + } + + fn set_disabled_state(&self, state: bool) { + if state { + self.flags.deref().borrow_mut().insert(InDisabledState); + } else { + self.flags.deref().borrow_mut().remove(InDisabledState); + } + } + /// Iterates over this node and all its descendants, in preorder. fn traverse_preorder<'a>(&'a self) -> TreeIterator<'a> { let mut nodes = vec!(); @@ -728,12 +747,16 @@ 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; } impl RawLayoutNodeHelpers for Node { unsafe fn get_hover_state_for_layout(&self) -> bool { self.flags.deref().borrow().contains(InHoverState) } + unsafe fn get_disabled_state_for_layout(&self) -> bool { + self.flags.deref().borrow().contains(InDisabledState) + } } @@ -1966,3 +1989,47 @@ impl<'a> style::TNode<JSRef<'a, Element>> for JSRef<'a, Node> { } } } + +pub trait DisabledStateHelpers { + fn check_ancestors_disabled_state_for_form_control(&self); + fn check_parent_disabled_state_for_option(&self); + fn check_disabled_attribute(&self); +} + +impl<'a> DisabledStateHelpers for JSRef<'a, Node> { + fn check_ancestors_disabled_state_for_form_control(&self) { + if self.get_disabled_state() { return; } + for ancestor in self.ancestors().filter(|ancestor| ancestor.is_htmlfieldsetelement()) { + if !ancestor.get_disabled_state() { continue; } + if ancestor.is_parent_of(self) { + self.set_disabled_state(true); + return; + } + match ancestor.children().find(|child| child.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); + return; + } + } + + fn check_parent_disabled_state_for_option(&self) { + if self.get_disabled_state() { return; } + match self.parent_node().root() { + Some(ref parent) if parent.is_htmloptgroupelement() && parent.get_disabled_state() => { + self.set_disabled_state(true); + }, + _ => () + } + } + + fn check_disabled_attribute(&self) { + 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); + } +} |