mirror of
https://github.com/servo/servo.git
synced 2025-06-15 03:44: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::documenttype::DocumentType;
|
||||||
use dom::domimplementation::DOMImplementation;
|
use dom::domimplementation::DOMImplementation;
|
||||||
use dom::element::{Element, ElementCreator, AttributeHandlers};
|
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::event::{Event, EventBubbles, EventCancelable, EventHelpers};
|
||||||
use dom::eventtarget::{EventTarget, EventTargetTypeId, EventTargetHelpers};
|
use dom::eventtarget::{EventTarget, EventTargetTypeId, EventTargetHelpers};
|
||||||
use dom::htmlanchorelement::HTMLAnchorElement;
|
use dom::htmlanchorelement::HTMLAnchorElement;
|
||||||
|
@ -448,8 +448,10 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
|
||||||
|
|
||||||
/// Request that the given element receive focus once the current transaction is complete.
|
/// Request that the given element receive focus once the current transaction is complete.
|
||||||
fn request_focus(self, elem: JSRef<Element>) {
|
fn request_focus(self, elem: JSRef<Element>) {
|
||||||
|
if elem.is_focusable_area() {
|
||||||
self.possibly_focused.assign(Some(elem))
|
self.possibly_focused.assign(Some(elem))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Reassign the focus context to the element that last requested focus during this
|
/// Reassign the focus context to the element that last requested focus during this
|
||||||
/// transaction, or none if no elements requested it.
|
/// transaction, or none if no elements requested it.
|
||||||
|
|
|
@ -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 {
|
pub trait AttributeHandlers {
|
||||||
/// Returns the attribute with given namespace and case-sensitive local
|
/// Returns the attribute with given namespace and case-sensitive local
|
||||||
/// name, if any.
|
/// name, if any.
|
||||||
|
|
|
@ -1,23 +1,5 @@
|
||||||
[disabledElement.html]
|
[disabledElement.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
[A disabled <button> should not be focusable]
|
[A disabled <span> should be focusable]
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[A disabled <input> should not be focusable]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[A disabled <select> should not be focusable]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[A disabled <optgroup> should not be focusable]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[A disabled <option> should not be focusable]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[A disabled <textarea> should not be focusable]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[A disabled <input[type=radio\]> should not be focusable]
|
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,10 @@
|
||||||
type: testharness
|
type: testharness
|
||||||
[input3 has the attribute autofocus]
|
[input3 has the attribute autofocus]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
[tabindex attribute makes the element focusable]
|
||||||
|
expected: FAIL
|
||||||
|
[editable elements are focusable]
|
||||||
|
expected: FAIL
|
||||||
|
[':focus' matches focussed body with tabindex]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue