aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/components/layout/wrapper.rs6
-rw-r--r--src/components/script/dom/element.rs4
-rw-r--r--src/components/script/dom/node.rs49
-rw-r--r--src/components/style/node.rs1
-rw-r--r--src/components/style/selector_matching.rs6
-rw-r--r--src/components/style/selectors.rs4
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),