mirror of
https://github.com/servo/servo.git
synced 2025-06-13 19:04:30 +00:00
Don't allow disabled fields to be focused
This commit is contained in:
parent
35fb516662
commit
4e63a5063e
4 changed files with 58 additions and 21 deletions
|
@ -36,7 +36,7 @@ use dom::documentfragment::DocumentFragment;
|
|||
use dom::documenttype::DocumentType;
|
||||
use dom::domimplementation::DOMImplementation;
|
||||
use dom::element::{Element, ElementCreator, AttributeHandlers};
|
||||
use dom::element::{ElementTypeId, ActivationElementHelpers};
|
||||
use dom::element::{ElementTypeId, ActivationElementHelpers, FocusElementHelpers};
|
||||
use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers};
|
||||
use dom::eventtarget::{EventTarget, EventTargetTypeId, EventTargetHelpers};
|
||||
use dom::htmlanchorelement::HTMLAnchorElement;
|
||||
|
@ -448,7 +448,9 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
|
|||
|
||||
/// Request that the given element receive focus once the current transaction is complete.
|
||||
fn request_focus(self, elem: JSRef<Element>) {
|
||||
self.possibly_focused.assign(Some(elem))
|
||||
if elem.is_focusable_area() {
|
||||
self.possibly_focused.assign(Some(elem))
|
||||
}
|
||||
}
|
||||
|
||||
/// Reassign the focus context to the element that last requested focus during this
|
||||
|
|
|
@ -601,6 +601,53 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait FocusElementHelpers {
|
||||
/// https://html.spec.whatwg.org/multipage/interaction.html#focusable-area
|
||||
fn is_focusable_area(self) -> bool;
|
||||
|
||||
/// https://html.spec.whatwg.org/multipage/scripting.html#concept-element-disabled
|
||||
fn is_actually_disabled(self) -> bool;
|
||||
}
|
||||
|
||||
impl<'a> FocusElementHelpers for JSRef<'a, Element> {
|
||||
fn is_focusable_area(self) -> bool {
|
||||
if self.is_actually_disabled() {
|
||||
return false;
|
||||
}
|
||||
// TODO: Check whether the element is being rendered (i.e. not hidden).
|
||||
// TODO: Check the tabindex focus flag.
|
||||
// https://html.spec.whatwg.org/multipage/interaction.html#specially-focusable
|
||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
||||
match node.type_id() {
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) => {
|
||||
true
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn is_actually_disabled(self) -> bool {
|
||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
||||
match node.type_id() {
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) |
|
||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOptionElement)) => {
|
||||
node.get_disabled_state()
|
||||
}
|
||||
// TODO:
|
||||
// an optgroup element that has a disabled attribute
|
||||
// a menuitem element that has a disabled attribute
|
||||
// a fieldset element that is a disabled fieldset
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AttributeHandlers {
|
||||
/// Returns the attribute with given namespace and case-sensitive local
|
||||
/// name, if any.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue