mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Move Event States to |Element|.
Conceptually they belong there, rather than on |Node|. Fixes #7934.
This commit is contained in:
parent
628c2a0432
commit
75ec093334
14 changed files with 251 additions and 262 deletions
|
@ -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::codegen::InheritTypes::{NodeCast, NodeTypeId, TextCast};
|
||||||
use script::dom::bindings::js::LayoutJS;
|
use script::dom::bindings::js::LayoutJS;
|
||||||
use script::dom::characterdata::LayoutCharacterDataHelpers;
|
use script::dom::characterdata::LayoutCharacterDataHelpers;
|
||||||
use script::dom::element::Element;
|
use script::dom::element;
|
||||||
use script::dom::element::{LayoutElementHelpers, RawLayoutElementHelpers};
|
use script::dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers};
|
||||||
use script::dom::htmlcanvaselement::LayoutHTMLCanvasElementHelpers;
|
use script::dom::htmlcanvaselement::LayoutHTMLCanvasElementHelpers;
|
||||||
use script::dom::htmlimageelement::LayoutHTMLImageElementHelpers;
|
use script::dom::htmlimageelement::LayoutHTMLImageElementHelpers;
|
||||||
use script::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
|
use script::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
|
||||||
|
@ -468,20 +468,17 @@ impl<'le> ::selectors::Element for LayoutElement<'le> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_hover_state(&self) -> bool {
|
fn get_hover_state(&self) -> bool {
|
||||||
let node = NodeCast::from_layout_js(&self.element);
|
self.element.get_event_state_for_layout().contains(element::IN_HOVER_STATE)
|
||||||
node.get_hover_state_for_layout()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_focus_state(&self) -> bool {
|
fn get_focus_state(&self) -> bool {
|
||||||
let node = NodeCast::from_layout_js(&self.element);
|
self.element.get_event_state_for_layout().contains(element::IN_FOCUS_STATE)
|
||||||
node.get_focus_state_for_layout()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_active_state(&self) -> bool {
|
fn get_active_state(&self) -> bool {
|
||||||
let node = NodeCast::from_layout_js(&self.element);
|
self.element.get_event_state_for_layout().contains(element::IN_ACTIVE_STATE)
|
||||||
node.get_active_state_for_layout()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -493,14 +490,12 @@ impl<'le> ::selectors::Element for LayoutElement<'le> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_disabled_state(&self) -> bool {
|
fn get_disabled_state(&self) -> bool {
|
||||||
let node = NodeCast::from_layout_js(&self.element);
|
self.element.get_event_state_for_layout().contains(element::IN_DISABLED_STATE)
|
||||||
node.get_disabled_state_for_layout()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_enabled_state(&self) -> bool {
|
fn get_enabled_state(&self) -> bool {
|
||||||
let node = NodeCast::from_layout_js(&self.element);
|
self.element.get_event_state_for_layout().contains(element::IN_ENABLED_STATE)
|
||||||
node.get_enabled_state_for_layout()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -516,15 +516,13 @@ impl Document {
|
||||||
//TODO: dispatch blur, focus, focusout, and focusin events
|
//TODO: dispatch blur, focus, focusout, and focusin events
|
||||||
|
|
||||||
if let Some(ref elem) = self.focused.get_rooted() {
|
if let Some(ref elem) = self.focused.get_rooted() {
|
||||||
let node = NodeCast::from_ref(elem.r());
|
elem.set_focus_state(false);
|
||||||
node.set_focus_state(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.focused.set(self.possibly_focused.get().r());
|
self.focused.set(self.possibly_focused.get().r());
|
||||||
|
|
||||||
if let Some(ref elem) = self.focused.get_rooted() {
|
if let Some(ref elem) = self.focused.get_rooted() {
|
||||||
let node = NodeCast::from_ref(elem.r());
|
elem.set_focus_state(true);
|
||||||
node.set_focus_state(true);
|
|
||||||
|
|
||||||
// Update the focus state for all elements in the focus chain.
|
// Update the focus state for all elements in the focus chain.
|
||||||
// https://html.spec.whatwg.org/multipage/#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());
|
debug!("{} on {:?}", mouse_event_type_string, node.debug_str());
|
||||||
// Prevent click event if form control element is disabled.
|
// Prevent click event if form control element is disabled.
|
||||||
if let MouseEventType::Click = mouse_event_type {
|
if let MouseEventType::Click = mouse_event_type {
|
||||||
if node.click_event_filter_by_disabled_state() {
|
if el.click_event_filter_by_disabled_state() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,15 +659,16 @@ impl Document {
|
||||||
pub fn handle_mouse_move_event(&self,
|
pub fn handle_mouse_move_event(&self,
|
||||||
js_runtime: *mut JSRuntime,
|
js_runtime: *mut JSRuntime,
|
||||||
point: Point2D<f32>,
|
point: Point2D<f32>,
|
||||||
prev_mouse_over_targets: &mut RootedVec<JS<Node>>) {
|
prev_mouse_over_targets: &mut RootedVec<JS<Element>>) {
|
||||||
// Build a list of elements that are currently under the mouse.
|
// Build a list of elements that are currently under the mouse.
|
||||||
let mouse_over_addresses = self.get_nodes_under_mouse(&point);
|
let mouse_over_addresses = self.get_nodes_under_mouse(&point);
|
||||||
let mut mouse_over_targets: RootedVec<JS<Node>> = RootedVec::new();
|
let mut mouse_over_targets: RootedVec<JS<Element>> = RootedVec::new();
|
||||||
for node_address in &mouse_over_addresses {
|
for node_address in &mouse_over_addresses {
|
||||||
let node = node::from_untrusted_node_address(js_runtime, *node_address);
|
let node = node::from_untrusted_node_address(js_runtime, *node_address);
|
||||||
mouse_over_targets.push(node.r().inclusive_ancestors()
|
mouse_over_targets.push(node.r().inclusive_ancestors()
|
||||||
.find(|node| node.r().is_element())
|
.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
|
// 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 {
|
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::HTMLButtonElement)) |
|
||||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) |
|
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) |
|
||||||
// NodeTypeId::Element(ElementTypeId::HTMLKeygenElement) |
|
// NodeTypeId::Element(ElementTypeId::HTMLKeygenElement) |
|
||||||
|
|
|
@ -47,7 +47,7 @@ use dom::htmltableelement::HTMLTableElement;
|
||||||
use dom::htmltextareaelement::RawLayoutHTMLTextAreaElementHelpers;
|
use dom::htmltextareaelement::RawLayoutHTMLTextAreaElementHelpers;
|
||||||
use dom::namednodemap::NamedNodeMap;
|
use dom::namednodemap::NamedNodeMap;
|
||||||
use dom::node::{CLICK_IN_PROGRESS, LayoutNodeHelpers, Node};
|
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::node::{document_from_node, window_from_node};
|
||||||
use dom::nodelist::NodeList;
|
use dom::nodelist::NodeList;
|
||||||
use dom::virtualmethods::{VirtualMethods, vtable_for};
|
use dom::virtualmethods::{VirtualMethods, vtable_for};
|
||||||
|
@ -62,7 +62,7 @@ use selectors::parser::{AttrSelector, NamespaceConstraint};
|
||||||
use smallvec::VecLike;
|
use smallvec::VecLike;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::{Cow, ToOwned};
|
use std::borrow::{Cow, ToOwned};
|
||||||
use std::cell::Ref;
|
use std::cell::{Cell, Ref};
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -76,6 +76,25 @@ use style::values::specified::{self, CSSColor, CSSRGBA};
|
||||||
use url::UrlParser;
|
use url::UrlParser;
|
||||||
use util::str::{DOMString, LengthOrPercentageOrAuto};
|
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]
|
#[dom_struct]
|
||||||
pub struct Element {
|
pub struct Element {
|
||||||
node: Node,
|
node: Node,
|
||||||
|
@ -87,6 +106,7 @@ pub struct Element {
|
||||||
style_attribute: DOMRefCell<Option<PropertyDeclarationBlock>>,
|
style_attribute: DOMRefCell<Option<PropertyDeclarationBlock>>,
|
||||||
attr_list: MutNullableHeap<JS<NamedNodeMap>>,
|
attr_list: MutNullableHeap<JS<NamedNodeMap>>,
|
||||||
class_list: MutNullableHeap<JS<DOMTokenList>>,
|
class_list: MutNullableHeap<JS<DOMTokenList>>,
|
||||||
|
event_state: Cell<EventState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Element {
|
impl PartialEq for Element {
|
||||||
|
@ -115,16 +135,16 @@ impl Element {
|
||||||
pub fn new_inherited(local_name: DOMString,
|
pub fn new_inherited(local_name: DOMString,
|
||||||
namespace: Namespace, prefix: Option<DOMString>,
|
namespace: Namespace, prefix: Option<DOMString>,
|
||||||
document: &Document) -> Element {
|
document: &Document) -> Element {
|
||||||
Element::new_inherited_with_flags(NodeFlags::new(), local_name,
|
Element::new_inherited_with_state(EventState::empty(), local_name,
|
||||||
namespace, prefix, document)
|
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<DOMString>,
|
namespace: Namespace, prefix: Option<DOMString>,
|
||||||
document: &Document)
|
document: &Document)
|
||||||
-> Element {
|
-> Element {
|
||||||
Element {
|
Element {
|
||||||
node: Node::new_inherited_with_flags(flags, document),
|
node: Node::new_inherited(document),
|
||||||
local_name: Atom::from_slice(&local_name),
|
local_name: Atom::from_slice(&local_name),
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
|
@ -133,6 +153,7 @@ impl Element {
|
||||||
class_list: Default::default(),
|
class_list: Default::default(),
|
||||||
id_attribute: DOMRefCell::new(None),
|
id_attribute: DOMRefCell::new(None),
|
||||||
style_attribute: DOMRefCell::new(None),
|
style_attribute: DOMRefCell::new(None),
|
||||||
|
event_state: Cell::new(state),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,6 +245,8 @@ pub trait LayoutElementHelpers {
|
||||||
fn namespace(&self) -> &Namespace;
|
fn namespace(&self) -> &Namespace;
|
||||||
fn get_checked_state_for_layout(&self) -> bool;
|
fn get_checked_state_for_layout(&self) -> bool;
|
||||||
fn get_indeterminate_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<Element> {
|
impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
|
@ -574,6 +597,14 @@ impl LayoutElementHelpers for LayoutJS<Element> {
|
||||||
None => false,
|
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)]
|
#[derive(PartialEq, Eq, Copy, Clone, HeapSizeOf)]
|
||||||
|
@ -827,7 +858,7 @@ impl Element {
|
||||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) |
|
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) |
|
||||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) |
|
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) |
|
||||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOptionElement)) => {
|
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOptionElement)) => {
|
||||||
node.get_disabled_state()
|
self.get_disabled_state()
|
||||||
}
|
}
|
||||||
// TODO:
|
// TODO:
|
||||||
// an optgroup element that has a disabled attribute
|
// an optgroup element that has a disabled attribute
|
||||||
|
@ -1624,31 +1655,30 @@ impl<'a> ::selectors::Element for Root<Element> {
|
||||||
fn get_namespace<'b>(&'b self) -> &'b Namespace {
|
fn get_namespace<'b>(&'b self) -> &'b Namespace {
|
||||||
self.namespace()
|
self.namespace()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_hover_state(&self) -> bool {
|
fn get_hover_state(&self) -> bool {
|
||||||
let node = NodeCast::from_ref(&**self);
|
Element::get_hover_state(self)
|
||||||
node.get_hover_state()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_active_state(&self) -> bool {
|
fn get_active_state(&self) -> bool {
|
||||||
let node = NodeCast::from_ref(&**self);
|
Element::get_active_state(self)
|
||||||
node.get_active_state()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_focus_state(&self) -> bool {
|
fn get_focus_state(&self) -> bool {
|
||||||
// TODO: Also check whether the top-level browsing context has the system focus,
|
// TODO: Also check whether the top-level browsing context has the system focus,
|
||||||
// and whether this element is a browsing context container.
|
// and whether this element is a browsing context container.
|
||||||
// https://html.spec.whatwg.org/multipage/#selector-focus
|
// https://html.spec.whatwg.org/multipage/#selector-focus
|
||||||
let node = NodeCast::from_ref(&**self);
|
Element::get_focus_state(self)
|
||||||
node.get_focus_state()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_id(&self) -> Option<Atom> {
|
fn get_id(&self) -> Option<Atom> {
|
||||||
self.id_attribute.borrow().clone()
|
self.id_attribute.borrow().clone()
|
||||||
}
|
}
|
||||||
fn get_disabled_state(&self) -> bool {
|
fn get_disabled_state(&self) -> bool {
|
||||||
let node = NodeCast::from_ref(&**self);
|
Element::get_disabled_state(self)
|
||||||
node.get_disabled_state()
|
|
||||||
}
|
}
|
||||||
fn get_enabled_state(&self) -> bool {
|
fn get_enabled_state(&self) -> bool {
|
||||||
let node = NodeCast::from_ref(&**self);
|
Element::get_enabled_state(self)
|
||||||
node.get_enabled_state()
|
|
||||||
}
|
}
|
||||||
fn get_checked_state(&self) -> bool {
|
fn get_checked_state(&self) -> bool {
|
||||||
let input_element: Option<&HTMLInputElement> = HTMLInputElementCast::to_ref(&**self);
|
let input_element: Option<&HTMLInputElement> = HTMLInputElementCast::to_ref(&**self);
|
||||||
|
@ -1816,6 +1846,58 @@ impl Element {
|
||||||
// Step 7
|
// Step 7
|
||||||
self.set_click_in_progress(false);
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
|
|
@ -10,14 +10,13 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLButtonElementCast, H
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLFieldSetElementDerived, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{HTMLFieldSetElementDerived, NodeCast};
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeMutation, Element};
|
use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE};
|
||||||
use dom::event::Event;
|
use dom::event::Event;
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::htmlformelement::{FormControl, FormSubmitter};
|
use dom::htmlformelement::{FormControl, FormSubmitter};
|
||||||
use dom::htmlformelement::{SubmittedFrom, HTMLFormElement};
|
use dom::htmlformelement::{SubmittedFrom, HTMLFormElement};
|
||||||
use dom::node::{IN_ENABLED_STATE, Node, NodeFlags};
|
use dom::node::{Node, document_from_node, window_from_node};
|
||||||
use dom::node::{document_from_node, window_from_node};
|
|
||||||
use dom::validitystate::ValidityState;
|
use dom::validitystate::ValidityState;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
|
@ -47,7 +46,7 @@ impl HTMLButtonElement {
|
||||||
document: &Document) -> HTMLButtonElement {
|
document: &Document) -> HTMLButtonElement {
|
||||||
HTMLButtonElement {
|
HTMLButtonElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
|
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
|
||||||
localName, prefix, document),
|
localName, prefix, document),
|
||||||
//TODO: implement button_type in attribute_mutated
|
//TODO: implement button_type in attribute_mutated
|
||||||
button_type: Cell::new(ButtonType::ButtonSubmit)
|
button_type: Cell::new(ButtonType::ButtonSubmit)
|
||||||
|
@ -144,17 +143,17 @@ impl VirtualMethods for HTMLButtonElement {
|
||||||
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!(disabled) => {
|
&atom!(disabled) => {
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
match mutation {
|
match mutation {
|
||||||
AttributeMutation::Set(Some(_)) => {}
|
AttributeMutation::Set(Some(_)) => {}
|
||||||
AttributeMutation::Set(None) => {
|
AttributeMutation::Set(None) => {
|
||||||
node.set_disabled_state(true);
|
el.set_disabled_state(true);
|
||||||
node.set_enabled_state(false);
|
el.set_enabled_state(false);
|
||||||
},
|
},
|
||||||
AttributeMutation::Removed => {
|
AttributeMutation::Removed => {
|
||||||
node.set_disabled_state(false);
|
el.set_disabled_state(false);
|
||||||
node.set_enabled_state(true);
|
el.set_enabled_state(true);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
el.check_ancestors_disabled_state_for_form_control();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -167,8 +166,8 @@ impl VirtualMethods for HTMLButtonElement {
|
||||||
s.bind_to_tree(tree_in_doc);
|
s.bind_to_tree(tree_in_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
el.check_ancestors_disabled_state_for_form_control();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unbind_from_tree(&self, tree_in_doc: bool) {
|
fn unbind_from_tree(&self, tree_in_doc: bool) {
|
||||||
|
@ -177,10 +176,11 @@ impl VirtualMethods for HTMLButtonElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
|
let el = ElementCast::from_ref(self);
|
||||||
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
|
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 {
|
} 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 {
|
fn is_instance_activatable(&self) -> bool {
|
||||||
//https://html.spec.whatwg.org/multipage/#the-button-element
|
//https://html.spec.whatwg.org/multipage/#the-button-element
|
||||||
let node = NodeCast::from_ref(*self);
|
let el = ElementCast::from_ref(*self);
|
||||||
!(node.get_disabled_state())
|
!(el.get_disabled_state())
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#run-pre-click-activation-steps
|
// https://html.spec.whatwg.org/multipage/#run-pre-click-activation-steps
|
||||||
|
|
|
@ -20,9 +20,9 @@ use dom::bindings::utils::Reflectable;
|
||||||
use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration};
|
use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::domstringmap::DOMStringMap;
|
use dom::domstringmap::DOMStringMap;
|
||||||
use dom::element::{AttributeMutation, Element};
|
use dom::element::{AttributeMutation, Element, EventState};
|
||||||
use dom::htmlinputelement::HTMLInputElement;
|
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::node::{document_from_node, window_from_node};
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use msg::constellation_msg::FocusType;
|
use msg::constellation_msg::FocusType;
|
||||||
|
@ -49,15 +49,15 @@ impl PartialEq for HTMLElement {
|
||||||
impl HTMLElement {
|
impl HTMLElement {
|
||||||
pub fn new_inherited(tag_name: DOMString, prefix: Option<DOMString>,
|
pub fn new_inherited(tag_name: DOMString, prefix: Option<DOMString>,
|
||||||
document: &Document) -> HTMLElement {
|
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<DOMString>, document: &Document)
|
prefix: Option<DOMString>, document: &Document)
|
||||||
-> HTMLElement {
|
-> HTMLElement {
|
||||||
HTMLElement {
|
HTMLElement {
|
||||||
element:
|
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(),
|
style_decl: Default::default(),
|
||||||
dataset: Default::default(),
|
dataset: Default::default(),
|
||||||
}
|
}
|
||||||
|
@ -194,8 +194,8 @@ impl HTMLElementMethods for HTMLElement {
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-blur
|
// https://html.spec.whatwg.org/multipage/#dom-blur
|
||||||
fn Blur(&self) {
|
fn Blur(&self) {
|
||||||
// TODO: Run the unfocusing steps.
|
// TODO: Run the unfocusing steps.
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
if !node.get_focus_state() {
|
if !el.get_focus_state() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// https://html.spec.whatwg.org/multipage/#unfocusing-steps
|
// https://html.spec.whatwg.org/multipage/#unfocusing-steps
|
||||||
|
|
|
@ -5,16 +5,16 @@
|
||||||
use dom::attr::Attr;
|
use dom::attr::Attr;
|
||||||
use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding::HTMLFieldSetElementMethods;
|
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::{HTMLElementTypeId, HTMLLegendElementDerived};
|
||||||
use dom::bindings::codegen::InheritTypes::{NodeCast, NodeTypeId};
|
use dom::bindings::codegen::InheritTypes::{NodeCast, NodeTypeId};
|
||||||
use dom::bindings::js::{Root, RootedReference};
|
use dom::bindings::js::{Root, RootedReference};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeMutation, Element};
|
use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE};
|
||||||
use dom::htmlcollection::{CollectionFilter, HTMLCollection};
|
use dom::htmlcollection::{CollectionFilter, HTMLCollection};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::htmlformelement::{FormControl, HTMLFormElement};
|
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::validitystate::ValidityState;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use util::str::{DOMString, StaticStringVec};
|
use util::str::{DOMString, StaticStringVec};
|
||||||
|
@ -30,7 +30,7 @@ impl HTMLFieldSetElement {
|
||||||
document: &Document) -> HTMLFieldSetElement {
|
document: &Document) -> HTMLFieldSetElement {
|
||||||
HTMLFieldSetElement {
|
HTMLFieldSetElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
|
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
|
||||||
localName, prefix, document)
|
localName, prefix, document)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,8 +99,9 @@ impl VirtualMethods for HTMLFieldSetElement {
|
||||||
AttributeMutation::Removed => false,
|
AttributeMutation::Removed => false,
|
||||||
};
|
};
|
||||||
let node = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.set_disabled_state(disabled_state);
|
let el = ElementCast::from_ref(self);
|
||||||
node.set_enabled_state(!disabled_state);
|
el.set_disabled_state(disabled_state);
|
||||||
|
el.set_enabled_state(!disabled_state);
|
||||||
let mut found_legend = false;
|
let mut found_legend = false;
|
||||||
let children = node.children().filter(|node| {
|
let children = node.children().filter(|node| {
|
||||||
if found_legend {
|
if found_legend {
|
||||||
|
@ -135,13 +136,15 @@ impl VirtualMethods for HTMLFieldSetElement {
|
||||||
});
|
});
|
||||||
if disabled_state {
|
if disabled_state {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
field.set_disabled_state(true);
|
let el = ElementCast::to_ref(field.r()).unwrap();
|
||||||
field.set_enabled_state(false);
|
el.set_disabled_state(true);
|
||||||
|
el.set_enabled_state(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
field.check_disabled_attribute();
|
let el = ElementCast::to_ref(field.r()).unwrap();
|
||||||
field.check_ancestors_disabled_state_for_form_control();
|
el.check_disabled_attribute();
|
||||||
|
el.check_ancestors_disabled_state_for_form_control();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -223,9 +223,11 @@ impl HTMLFormElement {
|
||||||
// TODO: This is an incorrect way of getting controls owned
|
// TODO: This is an incorrect way of getting controls owned
|
||||||
// by the form, but good enough until html5ever lands
|
// by the form, but good enough until html5ever lands
|
||||||
node.traverse_preorder().filter_map(|child| {
|
node.traverse_preorder().filter_map(|child| {
|
||||||
if child.r().get_disabled_state() {
|
match ElementCast::to_ref(child.r()) {
|
||||||
return None;
|
Some(el) if !el.get_disabled_state() => (),
|
||||||
|
_ => return None,
|
||||||
}
|
}
|
||||||
|
|
||||||
if child.r().ancestors()
|
if child.r().ancestors()
|
||||||
.any(|a| HTMLDataListElementCast::to_root(a).is_some()) {
|
.any(|a| HTMLDataListElementCast::to_root(a).is_some()) {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
@ -17,14 +17,14 @@ use dom::bindings::codegen::InheritTypes::{KeyboardEventCast, NodeCast};
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JS, LayoutJS, Root, RootedReference};
|
use dom::bindings::js::{JS, LayoutJS, Root, RootedReference};
|
||||||
use dom::document::Document;
|
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::event::{Event, EventBubbles, EventCancelable};
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::htmlformelement::{FormControl, FormDatum, FormSubmitter, HTMLFormElement};
|
use dom::htmlformelement::{FormControl, FormDatum, FormSubmitter, HTMLFormElement};
|
||||||
use dom::htmlformelement::{ResetFrom, SubmittedFrom};
|
use dom::htmlformelement::{ResetFrom, SubmittedFrom};
|
||||||
use dom::keyboardevent::KeyboardEvent;
|
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::node::{document_from_node, window_from_node};
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use msg::constellation_msg::ConstellationChan;
|
use msg::constellation_msg::ConstellationChan;
|
||||||
|
@ -109,7 +109,7 @@ impl HTMLInputElement {
|
||||||
let chan = document.window().r().constellation_chan();
|
let chan = document.window().r().constellation_chan();
|
||||||
HTMLInputElement {
|
HTMLInputElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
|
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
|
||||||
localName, prefix, document),
|
localName, prefix, document),
|
||||||
input_type: Cell::new(InputType::InputText),
|
input_type: Cell::new(InputType::InputText),
|
||||||
checked: Cell::new(false),
|
checked: Cell::new(false),
|
||||||
|
@ -472,8 +472,8 @@ impl HTMLInputElement {
|
||||||
fn mutable(&self) -> bool {
|
fn mutable(&self) -> bool {
|
||||||
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-fe-mutable
|
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-fe-mutable
|
||||||
// https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable
|
// https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
!(node.get_disabled_state() || self.ReadOnly())
|
!(el.get_disabled_state() || self.ReadOnly())
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-form-reset-control
|
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-form-reset-control
|
||||||
|
@ -511,10 +511,10 @@ impl VirtualMethods for HTMLInputElement {
|
||||||
},
|
},
|
||||||
AttributeMutation::Removed => false,
|
AttributeMutation::Removed => false,
|
||||||
};
|
};
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
node.set_disabled_state(disabled_state);
|
el.set_disabled_state(disabled_state);
|
||||||
node.set_enabled_state(!disabled_state);
|
el.set_enabled_state(!disabled_state);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
el.check_ancestors_disabled_state_for_form_control();
|
||||||
},
|
},
|
||||||
&atom!(checked) if !self.checked_changed.get() => {
|
&atom!(checked) if !self.checked_changed.get() => {
|
||||||
let checked_state = match mutation {
|
let checked_state = match mutation {
|
||||||
|
@ -596,8 +596,8 @@ impl VirtualMethods for HTMLInputElement {
|
||||||
s.bind_to_tree(tree_in_doc);
|
s.bind_to_tree(tree_in_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
el.check_ancestors_disabled_state_for_form_control();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unbind_from_tree(&self, tree_in_doc: bool) {
|
fn unbind_from_tree(&self, tree_in_doc: bool) {
|
||||||
|
@ -606,10 +606,11 @@ impl VirtualMethods for HTMLInputElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
|
let el = ElementCast::from_ref(self);
|
||||||
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
|
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 {
|
} else {
|
||||||
node.check_disabled_attribute();
|
el.check_disabled_attribute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,13 @@
|
||||||
use dom::attr::Attr;
|
use dom::attr::Attr;
|
||||||
use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLOptGroupElementBinding::HTMLOptGroupElementMethods;
|
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::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::AttributeMutation;
|
use dom::element::{AttributeMutation, IN_ENABLED_STATE};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{IN_ENABLED_STATE, Node, NodeFlags};
|
use dom::node::{Node};
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ impl HTMLOptGroupElement {
|
||||||
document: &Document) -> HTMLOptGroupElement {
|
document: &Document) -> HTMLOptGroupElement {
|
||||||
HTMLOptGroupElement {
|
HTMLOptGroupElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
|
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
|
||||||
localName, prefix, document)
|
localName, prefix, document)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,19 +67,22 @@ impl VirtualMethods for HTMLOptGroupElement {
|
||||||
AttributeMutation::Removed => false,
|
AttributeMutation::Removed => false,
|
||||||
};
|
};
|
||||||
let node = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
node.set_disabled_state(disabled_state);
|
let el = ElementCast::from_ref(self);
|
||||||
node.set_enabled_state(!disabled_state);
|
el.set_disabled_state(disabled_state);
|
||||||
|
el.set_enabled_state(!disabled_state);
|
||||||
let options = node.children().filter(|child| {
|
let options = node.children().filter(|child| {
|
||||||
child.is_htmloptionelement()
|
child.is_htmloptionelement()
|
||||||
});
|
}).map(|child| Root::from_ref(HTMLOptionElementCast::to_ref(child.r()).unwrap()));
|
||||||
if disabled_state {
|
if disabled_state {
|
||||||
for option in options {
|
for option in options {
|
||||||
option.set_disabled_state(true);
|
let el = ElementCast::from_ref(option.r());
|
||||||
option.set_enabled_state(false);
|
el.set_disabled_state(true);
|
||||||
|
el.set_enabled_state(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for option in options {
|
for option in options {
|
||||||
option.check_disabled_attribute();
|
let el = ElementCast::from_ref(option.r());
|
||||||
|
el.check_disabled_attribute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,9 +12,9 @@ use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLScriptElementDer
|
||||||
use dom::bindings::codegen::InheritTypes::{NodeCast, TextDerived};
|
use dom::bindings::codegen::InheritTypes::{NodeCast, TextDerived};
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeMutation, Element};
|
use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{IN_ENABLED_STATE, Node, NodeFlags};
|
use dom::node::{Node};
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use util::str::{DOMString, split_html_space_chars, str_join};
|
use util::str::{DOMString, split_html_space_chars, str_join};
|
||||||
|
@ -36,7 +36,7 @@ impl HTMLOptionElement {
|
||||||
document: &Document) -> HTMLOptionElement {
|
document: &Document) -> HTMLOptionElement {
|
||||||
HTMLOptionElement {
|
HTMLOptionElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
|
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
|
||||||
localName, prefix, document),
|
localName, prefix, document),
|
||||||
selectedness: Cell::new(false),
|
selectedness: Cell::new(false),
|
||||||
dirtiness: Cell::new(false),
|
dirtiness: Cell::new(false),
|
||||||
|
@ -151,16 +151,16 @@ impl VirtualMethods for HTMLOptionElement {
|
||||||
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!(disabled) => {
|
&atom!(disabled) => {
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
match mutation {
|
match mutation {
|
||||||
AttributeMutation::Set(_) => {
|
AttributeMutation::Set(_) => {
|
||||||
node.set_disabled_state(true);
|
el.set_disabled_state(true);
|
||||||
node.set_enabled_state(false);
|
el.set_enabled_state(false);
|
||||||
},
|
},
|
||||||
AttributeMutation::Removed => {
|
AttributeMutation::Removed => {
|
||||||
node.set_disabled_state(false);
|
el.set_disabled_state(false);
|
||||||
node.set_enabled_state(true);
|
el.set_enabled_state(true);
|
||||||
node.check_parent_disabled_state_for_option();
|
el.check_parent_disabled_state_for_option();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -189,8 +189,8 @@ impl VirtualMethods for HTMLOptionElement {
|
||||||
s.bind_to_tree(tree_in_doc);
|
s.bind_to_tree(tree_in_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
node.check_parent_disabled_state_for_option();
|
el.check_parent_disabled_state_for_option();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unbind_from_tree(&self, tree_in_doc: bool) {
|
fn unbind_from_tree(&self, tree_in_doc: bool) {
|
||||||
|
@ -199,10 +199,11 @@ impl VirtualMethods for HTMLOptionElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
|
let el = ElementCast::from_ref(self);
|
||||||
if node.GetParentNode().is_some() {
|
if node.GetParentNode().is_some() {
|
||||||
node.check_parent_disabled_state_for_option();
|
el.check_parent_disabled_state_for_option();
|
||||||
} else {
|
} else {
|
||||||
node.check_disabled_attribute();
|
el.check_disabled_attribute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,15 @@
|
||||||
use dom::attr::{Attr, AttrValue};
|
use dom::attr::{Attr, AttrValue};
|
||||||
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding::HTMLSelectElementMethods;
|
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::HTMLElementOrLong;
|
||||||
use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement;
|
use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::AttributeMutation;
|
use dom::element::{AttributeMutation, IN_ENABLED_STATE};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::htmlformelement::{FormControl, HTMLFormElement};
|
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::validitystate::ValidityState;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
@ -33,7 +33,7 @@ impl HTMLSelectElement {
|
||||||
document: &Document) -> HTMLSelectElement {
|
document: &Document) -> HTMLSelectElement {
|
||||||
HTMLSelectElement {
|
HTMLSelectElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
|
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
|
||||||
localName, prefix, document)
|
localName, prefix, document)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,16 +107,16 @@ impl VirtualMethods for HTMLSelectElement {
|
||||||
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) {
|
||||||
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
if attr.local_name() == &atom!(disabled) {
|
if attr.local_name() == &atom!(disabled) {
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
match mutation {
|
match mutation {
|
||||||
AttributeMutation::Set(_) => {
|
AttributeMutation::Set(_) => {
|
||||||
node.set_disabled_state(true);
|
el.set_disabled_state(true);
|
||||||
node.set_enabled_state(false);
|
el.set_enabled_state(false);
|
||||||
},
|
},
|
||||||
AttributeMutation::Removed => {
|
AttributeMutation::Removed => {
|
||||||
node.set_disabled_state(false);
|
el.set_disabled_state(false);
|
||||||
node.set_enabled_state(true);
|
el.set_enabled_state(true);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
el.check_ancestors_disabled_state_for_form_control();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,8 +127,8 @@ impl VirtualMethods for HTMLSelectElement {
|
||||||
s.bind_to_tree(tree_in_doc);
|
s.bind_to_tree(tree_in_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
el.check_ancestors_disabled_state_for_form_control();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unbind_from_tree(&self, tree_in_doc: bool) {
|
fn unbind_from_tree(&self, tree_in_doc: bool) {
|
||||||
|
@ -137,10 +137,11 @@ impl VirtualMethods for HTMLSelectElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = NodeCast::from_ref(self);
|
let node = NodeCast::from_ref(self);
|
||||||
|
let el = ElementCast::from_ref(self);
|
||||||
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
|
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 {
|
} else {
|
||||||
node.check_disabled_attribute();
|
el.check_disabled_attribute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,13 @@ use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{LayoutJS, Root};
|
use dom::bindings::js::{LayoutJS, Root};
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::AttributeMutation;
|
use dom::element::{AttributeMutation, IN_ENABLED_STATE};
|
||||||
use dom::event::{Event, EventBubbles, EventCancelable};
|
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::htmlformelement::{FormControl, HTMLFormElement};
|
use dom::htmlformelement::{FormControl, HTMLFormElement};
|
||||||
use dom::keyboardevent::KeyboardEvent;
|
use dom::keyboardevent::KeyboardEvent;
|
||||||
use dom::node::{ChildrenMutation, IN_ENABLED_STATE, Node, NodeDamage};
|
use dom::node::{ChildrenMutation, Node, NodeDamage};
|
||||||
use dom::node::{NodeFlags, document_from_node, window_from_node};
|
use dom::node::{document_from_node, window_from_node};
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use msg::constellation_msg::ConstellationChan;
|
use msg::constellation_msg::ConstellationChan;
|
||||||
use script_task::ScriptTaskEventCategory::InputEvent;
|
use script_task::ScriptTaskEventCategory::InputEvent;
|
||||||
|
@ -87,7 +87,7 @@ impl HTMLTextAreaElement {
|
||||||
let chan = document.window().r().constellation_chan();
|
let chan = document.window().r().constellation_chan();
|
||||||
HTMLTextAreaElement {
|
HTMLTextAreaElement {
|
||||||
htmlelement:
|
htmlelement:
|
||||||
HTMLElement::new_inherited_with_flags(NodeFlags::new() | IN_ENABLED_STATE,
|
HTMLElement::new_inherited_with_state(IN_ENABLED_STATE,
|
||||||
localName, prefix, document),
|
localName, prefix, document),
|
||||||
textinput: DOMRefCell::new(TextInput::new(Lines::Multiple, "".to_owned(), chan)),
|
textinput: DOMRefCell::new(TextInput::new(Lines::Multiple, "".to_owned(), chan)),
|
||||||
cols: Cell::new(DEFAULT_COLS),
|
cols: Cell::new(DEFAULT_COLS),
|
||||||
|
@ -245,16 +245,16 @@ impl VirtualMethods for HTMLTextAreaElement {
|
||||||
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
self.super_type().unwrap().attribute_mutated(attr, mutation);
|
||||||
match attr.local_name() {
|
match attr.local_name() {
|
||||||
&atom!(disabled) => {
|
&atom!(disabled) => {
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
match mutation {
|
match mutation {
|
||||||
AttributeMutation::Set(_) => {
|
AttributeMutation::Set(_) => {
|
||||||
node.set_disabled_state(true);
|
el.set_disabled_state(true);
|
||||||
node.set_enabled_state(false);
|
el.set_enabled_state(false);
|
||||||
},
|
},
|
||||||
AttributeMutation::Removed => {
|
AttributeMutation::Removed => {
|
||||||
node.set_disabled_state(false);
|
el.set_disabled_state(false);
|
||||||
node.set_enabled_state(true);
|
el.set_enabled_state(true);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
el.check_ancestors_disabled_state_for_form_control();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -279,8 +279,8 @@ impl VirtualMethods for HTMLTextAreaElement {
|
||||||
s.bind_to_tree(tree_in_doc);
|
s.bind_to_tree(tree_in_doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = NodeCast::from_ref(self);
|
let el = ElementCast::from_ref(self);
|
||||||
node.check_ancestors_disabled_state_for_form_control();
|
el.check_ancestors_disabled_state_for_form_control();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue {
|
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 node = NodeCast::from_ref(self);
|
||||||
|
let el = ElementCast::from_ref(self);
|
||||||
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
|
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 {
|
} else {
|
||||||
node.check_disabled_attribute();
|
el.check_disabled_attribute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,40 +125,28 @@ impl PartialEq for Node {
|
||||||
bitflags! {
|
bitflags! {
|
||||||
#[doc = "Flags for node items."]
|
#[doc = "Flags for node items."]
|
||||||
#[derive(JSTraceable, HeapSizeOf)]
|
#[derive(JSTraceable, HeapSizeOf)]
|
||||||
flags NodeFlags: u16 {
|
flags NodeFlags: u8 {
|
||||||
#[doc = "Specifies whether this node is in a document."]
|
#[doc = "Specifies whether this node is in a document."]
|
||||||
const IS_IN_DOC = 0x01,
|
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."]
|
#[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."]
|
#[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 \
|
#[doc = "Specifies whether this node has siblings (inclusive of itself) which \
|
||||||
changed since the last reflow."]
|
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 \
|
#[doc = "Specifies whether this node has descendants (inclusive of itself) which \
|
||||||
have changed since the last reflow."]
|
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)
|
// TODO: find a better place to keep this (#4105)
|
||||||
// https://critic.hoppipolla.co.uk/showcomment?chain=8873
|
// https://critic.hoppipolla.co.uk/showcomment?chain=8873
|
||||||
// Perhaps using a Set in Document?
|
// Perhaps using a Set in Document?
|
||||||
#[doc = "Specifies whether or not there is an authentic click in progress on \
|
#[doc = "Specifies whether or not there is an authentic click in progress on \
|
||||||
this element."]
|
this element."]
|
||||||
const CLICK_IN_PROGRESS = 0x100,
|
const CLICK_IN_PROGRESS = 0x20,
|
||||||
#[doc = "Specifies whether this node has the focus."]
|
|
||||||
const IN_FOCUS_STATE = 0x200,
|
|
||||||
#[doc = "Specifies whether this node is focusable and whether it is supposed \
|
#[doc = "Specifies whether this node is focusable and whether it is supposed \
|
||||||
to be reachable with using sequential focus navigation."]
|
to be reachable with using sequential focus navigation."]
|
||||||
const SEQUENTIALLY_FOCUSABLE = 0x400,
|
const SEQUENTIALLY_FOCUSABLE = 0x40,
|
||||||
#[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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,49 +462,6 @@ impl Node {
|
||||||
self.flags.set(flags);
|
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 {
|
pub fn get_has_changed(&self) -> bool {
|
||||||
self.get_flag(HAS_CHANGED)
|
self.get_flag(HAS_CHANGED)
|
||||||
}
|
}
|
||||||
|
@ -975,12 +920,6 @@ pub trait LayoutNodeHelpers {
|
||||||
unsafe fn layout_data(&self) -> Ref<Option<LayoutData>>;
|
unsafe fn layout_data(&self) -> Ref<Option<LayoutData>>;
|
||||||
unsafe fn layout_data_mut(&self) -> RefMut<Option<LayoutData>>;
|
unsafe fn layout_data_mut(&self) -> RefMut<Option<LayoutData>>;
|
||||||
unsafe fn layout_data_unchecked(&self) -> *const Option<LayoutData>;
|
unsafe fn layout_data_unchecked(&self) -> *const Option<LayoutData>;
|
||||||
|
|
||||||
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<Node> {
|
impl LayoutNodeHelpers for LayoutJS<Node> {
|
||||||
|
@ -1076,42 +1015,6 @@ impl LayoutNodeHelpers for LayoutJS<Node> {
|
||||||
unsafe fn layout_data_unchecked(&self) -> *const Option<LayoutData> {
|
unsafe fn layout_data_unchecked(&self) -> *const Option<LayoutData> {
|
||||||
(*self.unsafe_get()).layout_data.borrow_unchecked()
|
(*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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1345,11 +1248,7 @@ impl Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_inherited(doc: &Document) -> Node {
|
pub fn new_inherited(doc: &Document) -> Node {
|
||||||
Node::new_inherited_with_flags(NodeFlags::new(), doc)
|
Node::new_(NodeFlags::new(), Some(doc))
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_inherited_with_flags(flags: NodeFlags, doc: &Document) -> Node {
|
|
||||||
Node::new_(flags, Some(doc))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
|
@ -2463,15 +2362,16 @@ impl VirtualMethods for Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Node {
|
impl Element {
|
||||||
pub fn check_ancestors_disabled_state_for_form_control(&self) {
|
pub fn check_ancestors_disabled_state_for_form_control(&self) {
|
||||||
|
let node = NodeCast::from_ref(self);
|
||||||
if self.get_disabled_state() { return; }
|
if self.get_disabled_state() { return; }
|
||||||
for ancestor in self.ancestors() {
|
for ancestor in node.ancestors() {
|
||||||
let ancestor = ancestor;
|
let ancestor = ancestor;
|
||||||
let ancestor = ancestor.r();
|
let ancestor = ancestor.r();
|
||||||
if !ancestor.is_htmlfieldsetelement() { continue; }
|
if !ancestor.is_htmlfieldsetelement() { continue; }
|
||||||
if !ancestor.get_disabled_state() { continue; }
|
if !ElementCast::to_ref(ancestor).unwrap().get_disabled_state() { continue; }
|
||||||
if ancestor.is_parent_of(self) {
|
if ancestor.is_parent_of(node) {
|
||||||
self.set_disabled_state(true);
|
self.set_disabled_state(true);
|
||||||
self.set_enabled_state(false);
|
self.set_enabled_state(false);
|
||||||
return;
|
return;
|
||||||
|
@ -2481,7 +2381,7 @@ impl Node {
|
||||||
{
|
{
|
||||||
Some(ref legend) => {
|
Some(ref legend) => {
|
||||||
// XXXabinader: should we save previous ancestor to avoid this iteration?
|
// XXXabinader: should we save previous ancestor to avoid this iteration?
|
||||||
if self.ancestors().any(|ancestor| ancestor == *legend) { continue; }
|
if node.ancestors().any(|ancestor| ancestor == *legend) { continue; }
|
||||||
},
|
},
|
||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
|
@ -2493,8 +2393,9 @@ impl Node {
|
||||||
|
|
||||||
pub fn check_parent_disabled_state_for_option(&self) {
|
pub fn check_parent_disabled_state_for_option(&self) {
|
||||||
if self.get_disabled_state() { return; }
|
if self.get_disabled_state() { return; }
|
||||||
if let Some(ref parent) = self.GetParentNode() {
|
let node = NodeCast::from_ref(self);
|
||||||
if parent.r().is_htmloptgroupelement() && parent.r().get_disabled_state() {
|
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_disabled_state(true);
|
||||||
self.set_enabled_state(false);
|
self.set_enabled_state(false);
|
||||||
}
|
}
|
||||||
|
@ -2502,8 +2403,7 @@ impl Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_disabled_attribute(&self) {
|
pub fn check_disabled_attribute(&self) {
|
||||||
let elem = ElementCast::to_ref(self).unwrap();
|
let has_disabled_attrib = self.has_attribute(&atom!("disabled"));
|
||||||
let has_disabled_attrib = elem.has_attribute(&atom!("disabled"));
|
|
||||||
self.set_disabled_state(has_disabled_attrib);
|
self.set_disabled_state(has_disabled_attrib);
|
||||||
self.set_enabled_state(!has_disabled_attrib);
|
self.set_enabled_state(!has_disabled_attrib);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ use dom::document::{Document, DocumentProgressHandler, IsHTMLDocument};
|
||||||
use dom::document::{DocumentProgressTask, DocumentSource, MouseEventType};
|
use dom::document::{DocumentProgressTask, DocumentSource, MouseEventType};
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::event::{EventBubbles, EventCancelable};
|
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::servohtmlparser::{ParserContext, ServoHTMLParser};
|
||||||
use dom::uievent::UIEvent;
|
use dom::uievent::UIEvent;
|
||||||
use dom::window::{ReflowReason, ScriptHelpers, Window};
|
use dom::window::{ReflowReason, ScriptHelpers, Window};
|
||||||
|
@ -406,7 +406,7 @@ pub struct ScriptTask {
|
||||||
/// The JavaScript runtime.
|
/// The JavaScript runtime.
|
||||||
js_runtime: Rc<Runtime>,
|
js_runtime: Rc<Runtime>,
|
||||||
|
|
||||||
mouse_over_targets: DOMRefCell<Vec<JS<Node>>>,
|
mouse_over_targets: DOMRefCell<Vec<JS<Element>>>,
|
||||||
|
|
||||||
/// List of pipelines that have been owned and closed by this script task.
|
/// List of pipelines that have been owned and closed by this script task.
|
||||||
closed_pipelines: RefCell<HashSet<PipelineId>>,
|
closed_pipelines: RefCell<HashSet<PipelineId>>,
|
||||||
|
@ -1718,7 +1718,7 @@ impl ScriptTask {
|
||||||
let page = get_page(&self.root_page(), pipeline_id);
|
let page = get_page(&self.root_page(), pipeline_id);
|
||||||
let document = page.document();
|
let document = page.document();
|
||||||
|
|
||||||
let mut prev_mouse_over_targets: RootedVec<JS<Node>> = RootedVec::new();
|
let mut prev_mouse_over_targets: RootedVec<JS<Element>> = RootedVec::new();
|
||||||
for target in &*self.mouse_over_targets.borrow_mut() {
|
for target in &*self.mouse_over_targets.borrow_mut() {
|
||||||
prev_mouse_over_targets.push(target.clone());
|
prev_mouse_over_targets.push(target.clone());
|
||||||
}
|
}
|
||||||
|
@ -1732,7 +1732,7 @@ impl ScriptTask {
|
||||||
// Notify Constellation about anchors that are no longer mouse over targets.
|
// Notify Constellation about anchors that are no longer mouse over targets.
|
||||||
for target in &*prev_mouse_over_targets {
|
for target in &*prev_mouse_over_targets {
|
||||||
if !mouse_over_targets.contains(target) {
|
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 event = ConstellationMsg::NodeStatus(None);
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||||
chan.send(event).unwrap();
|
chan.send(event).unwrap();
|
||||||
|
@ -1744,9 +1744,8 @@ impl ScriptTask {
|
||||||
// Notify Constellation about the topmost anchor mouse over target.
|
// Notify Constellation about the topmost anchor mouse over target.
|
||||||
for target in &*mouse_over_targets {
|
for target in &*mouse_over_targets {
|
||||||
let target = target.root();
|
let target = target.root();
|
||||||
if target.r().is_anchor_element() {
|
if NodeCast::from_ref(target.r()).is_anchor_element() {
|
||||||
let element = ElementCast::to_ref(target.r()).unwrap();
|
let status = target.r().get_attribute(&ns!(""), &atom!("href"))
|
||||||
let status = element.get_attribute(&ns!(""), &atom!("href"))
|
|
||||||
.and_then(|href| {
|
.and_then(|href| {
|
||||||
let value = href.value();
|
let value = href.value();
|
||||||
let url = document.r().url();
|
let url = document.r().url();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue