mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Implement support for :disabled CSS selector
This commit is contained in:
parent
40048b791c
commit
7771350898
7 changed files with 134 additions and 6 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue