mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Add Comparable trait to js.rs; fixups
This commit is contained in:
parent
e7b3caa386
commit
5511e02a78
6 changed files with 53 additions and 39 deletions
|
@ -575,3 +575,24 @@ impl<'a, T: Reflectable> Reflectable for JSRef<'a, T> {
|
|||
self.deref().reflector()
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for comparing smart pointers ignoring the lifetimes
|
||||
pub trait Comparable<T> {
|
||||
fn equals(&self, other: T) -> bool;
|
||||
}
|
||||
|
||||
impl<'a, 'b, T> Comparable<JSRef<'a, T>> for JSRef<'b, T> {
|
||||
fn equals(&self, other: JSRef<'a, T>) -> bool {
|
||||
self.ptr == other.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, T> Comparable<Option<JSRef<'a, T>>> for Option<JSRef<'b, T>> {
|
||||
fn equals(&self, other: Option<JSRef<'a, T>>) -> bool {
|
||||
match (*self, other) {
|
||||
(Some(x), Some(y)) => x.ptr == y.ptr,
|
||||
(None, None) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1253,7 +1253,7 @@ impl<'a> ActivationElementHelpers<'a> for JSRef<'a, Element> {
|
|||
// Step 4
|
||||
let e = self.nearest_activable_element().root();
|
||||
match e {
|
||||
Some (el) => match el.as_maybe_activatable() {
|
||||
Some(el) => match el.as_maybe_activatable() {
|
||||
Some(elem) => {
|
||||
// Step 5-6
|
||||
elem.pre_click_activation();
|
||||
|
|
|
@ -16,7 +16,8 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLFor
|
|||
use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLFieldSetElementDerived, EventTargetCast};
|
||||
use dom::bindings::codegen::InheritTypes::KeyboardEventCast;
|
||||
use dom::bindings::global::Window;
|
||||
use dom::bindings::js::{JS, JSRef, Root, Temporary, OptionalRootable, ResultRootable, MutNullableJS};
|
||||
use dom::bindings::js::{Comparable, JS, JSRef, Root, Temporary, OptionalRootable};
|
||||
use dom::bindings::js::{ResultRootable, RootedReference, MutNullableJS};
|
||||
use dom::bindings::utils::{Reflectable, Reflector};
|
||||
use dom::document::{Document, DocumentHelpers};
|
||||
use dom::element::{AttributeHandlers, Element, HTMLInputElementTypeId};
|
||||
|
@ -260,16 +261,13 @@ pub trait HTMLInputElementHelpers {
|
|||
fn force_relayout(self);
|
||||
fn radio_group_updated(self, group: Option<&str>);
|
||||
fn get_radio_group_name(self) -> Option<String>;
|
||||
fn in_same_group<'a,'b>(self, other: JSRef<'a, HTMLInputElement>,
|
||||
owner: Option<JSRef<'b, HTMLFormElement>>,
|
||||
group: Option<&str>) -> bool;
|
||||
fn update_checked_state(self, checked: bool);
|
||||
fn get_size(&self) -> u32;
|
||||
}
|
||||
|
||||
fn broadcast_radio_checked(broadcaster: JSRef<HTMLInputElement>, group: Option<&str>) {
|
||||
//TODO: if not in document, use root ancestor instead of document
|
||||
let owner = broadcaster.form_owner().root().map(|r| *r);
|
||||
let owner = broadcaster.form_owner().root();
|
||||
let doc = document_from_node(broadcaster).root();
|
||||
let doc_node: JSRef<Node> = NodeCast::from_ref(*doc);
|
||||
|
||||
|
@ -277,7 +275,7 @@ fn broadcast_radio_checked(broadcaster: JSRef<HTMLInputElement>, group: Option<&
|
|||
let mut iter = unsafe {
|
||||
doc_node.query_selector_iter("input[type=radio]".to_string()).unwrap()
|
||||
.filter_map(|t| HTMLInputElementCast::to_ref(t))
|
||||
.filter(|&r| broadcaster.in_same_group(r, owner, group) && broadcaster != r)
|
||||
.filter(|&r| in_same_group(r, owner.root_ref(), group) && broadcaster != r)
|
||||
};
|
||||
for r in iter {
|
||||
if r.Checked() {
|
||||
|
@ -286,6 +284,22 @@ fn broadcast_radio_checked(broadcaster: JSRef<HTMLInputElement>, group: Option<&
|
|||
}
|
||||
}
|
||||
|
||||
fn in_same_group<'a,'b>(other: JSRef<'a, HTMLInputElement>,
|
||||
owner: Option<JSRef<'b, HTMLFormElement>>,
|
||||
group: Option<&str>) -> bool {
|
||||
let other_owner = other.form_owner().root();
|
||||
let other_owner = other_owner.root_ref();
|
||||
other.input_type.get() == InputRadio &&
|
||||
// TODO Both a and b are in the same home subtree.
|
||||
other_owner.equals(owner) &&
|
||||
// TODO should be a unicode compatibility caseless match
|
||||
match (other.get_radio_group_name(), group) {
|
||||
(Some(ref s1), Some(s2)) => s1.as_slice() == s2,
|
||||
(None, None) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> {
|
||||
fn force_relayout(self) {
|
||||
let doc = document_from_node(self).root();
|
||||
|
@ -307,21 +321,6 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> {
|
|||
.map(|name| name.Value())
|
||||
}
|
||||
|
||||
fn in_same_group<'a,'b>(self, other: JSRef<'a, HTMLInputElement>,
|
||||
owner: Option<JSRef<'b, HTMLFormElement>>,
|
||||
group: Option<&str>) -> bool {
|
||||
let other_owner: Option<JSRef<_>> = other.form_owner().root().map(|r| *r);
|
||||
other.input_type.get() == InputRadio &&
|
||||
// TODO Both a and b are in the same home subtree.
|
||||
other_owner == owner &&
|
||||
// TODO should be a unicode compatibility caseless match
|
||||
match (other.get_radio_group_name(), group) {
|
||||
(Some(ref s1), Some(s2)) => s1.as_slice() == s2,
|
||||
(None, None) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn update_checked_state(self, checked: bool) {
|
||||
self.checked.set(checked);
|
||||
if self.input_type.get() == InputRadio && checked {
|
||||
|
@ -582,7 +581,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
|||
// https://html.spec.whatwg.org/multipage/forms.html#radio-button-state-(type=radio):pre-click-activation-steps
|
||||
InputRadio => {
|
||||
//TODO: if not in document, use root ancestor instead of document
|
||||
let owner = self.form_owner().root().map(|r| *r);
|
||||
let owner = self.form_owner().root();
|
||||
let doc = document_from_node(*self).root();
|
||||
let doc_node: JSRef<Node> = NodeCast::from_ref(*doc);
|
||||
let group = self.get_radio_group_name();;
|
||||
|
@ -591,8 +590,8 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
|||
let checked_member = unsafe {
|
||||
doc_node.query_selector_iter("input[type=radio]".to_string()).unwrap()
|
||||
.filter_map(|t| HTMLInputElementCast::to_ref(t))
|
||||
.filter(|&r| self.in_same_group(r, owner,
|
||||
group.as_ref().map(|gr| gr.as_slice())))
|
||||
.filter(|&r| in_same_group(r, owner.root_ref(),
|
||||
group.as_ref().map(|gr| gr.as_slice())))
|
||||
.find(|r| r.Checked())
|
||||
};
|
||||
cache.checked_radio.assign(checked_member);
|
||||
|
@ -673,16 +672,16 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
|||
// https://html.spec.whatwg.org/multipage/forms.html#radio-button-state-(type=radio):activation-behavior
|
||||
if self.mutable() {
|
||||
let win = window_from_node(*self).root();
|
||||
let event = Event::new(&Window(*win),
|
||||
"input".to_string(),
|
||||
Bubbles, NotCancelable).root();
|
||||
let event = Event::new(Window(*win),
|
||||
"input".to_string(),
|
||||
Bubbles, NotCancelable).root();
|
||||
event.set_trusted(true);
|
||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(*self);
|
||||
target.DispatchEvent(*event).ok();
|
||||
|
||||
let event = Event::new(&Window(*win),
|
||||
"change".to_string(),
|
||||
Bubbles, NotCancelable).root();
|
||||
let event = Event::new(Window(*win),
|
||||
"change".to_string(),
|
||||
Bubbles, NotCancelable).root();
|
||||
event.set_trusted(true);
|
||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(*self);
|
||||
target.DispatchEvent(*event).ok();
|
||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, Documen
|
|||
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
||||
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
||||
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{EventTargetCast, NodeCast, EventCast};
|
||||
use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, NodeCast, EventCast};
|
||||
use dom::bindings::conversions::{FromJSValConvertible, Empty};
|
||||
use dom::bindings::global;
|
||||
use dom::bindings::js::{JS, JSRef, RootCollection, Temporary, OptionalRootable};
|
||||
|
|
|
@ -9591,9 +9591,6 @@
|
|||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "oncanplaythrough" with the proper type (99)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onchange" with the proper type (100)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onclose" with the proper type (102)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -9645,9 +9642,6 @@
|
|||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onfocus" with the proper type (118)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "oninput" with the proper type (119)]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "oninvalid" with the proper type (120)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue