mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +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()
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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::{HTMLInputElementDerived, HTMLFieldSetElementDerived, EventTargetCast};
|
||||||
use dom::bindings::codegen::InheritTypes::KeyboardEventCast;
|
use dom::bindings::codegen::InheritTypes::KeyboardEventCast;
|
||||||
use dom::bindings::global::Window;
|
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::bindings::utils::{Reflectable, Reflector};
|
||||||
use dom::document::{Document, DocumentHelpers};
|
use dom::document::{Document, DocumentHelpers};
|
||||||
use dom::element::{AttributeHandlers, Element, HTMLInputElementTypeId};
|
use dom::element::{AttributeHandlers, Element, HTMLInputElementTypeId};
|
||||||
|
@ -260,16 +261,13 @@ pub trait HTMLInputElementHelpers {
|
||||||
fn force_relayout(self);
|
fn force_relayout(self);
|
||||||
fn radio_group_updated(self, group: Option<&str>);
|
fn radio_group_updated(self, group: Option<&str>);
|
||||||
fn get_radio_group_name(self) -> Option<String>;
|
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 update_checked_state(self, checked: bool);
|
||||||
fn get_size(&self) -> u32;
|
fn get_size(&self) -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn broadcast_radio_checked(broadcaster: JSRef<HTMLInputElement>, group: Option<&str>) {
|
fn broadcast_radio_checked(broadcaster: JSRef<HTMLInputElement>, group: Option<&str>) {
|
||||||
//TODO: if not in document, use root ancestor instead of document
|
//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 = document_from_node(broadcaster).root();
|
||||||
let doc_node: JSRef<Node> = NodeCast::from_ref(*doc);
|
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 {
|
let mut iter = unsafe {
|
||||||
doc_node.query_selector_iter("input[type=radio]".to_string()).unwrap()
|
doc_node.query_selector_iter("input[type=radio]".to_string()).unwrap()
|
||||||
.filter_map(|t| HTMLInputElementCast::to_ref(t))
|
.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 {
|
for r in iter {
|
||||||
if r.Checked() {
|
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> {
|
impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> {
|
||||||
fn force_relayout(self) {
|
fn force_relayout(self) {
|
||||||
let doc = document_from_node(self).root();
|
let doc = document_from_node(self).root();
|
||||||
|
@ -307,21 +321,6 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> {
|
||||||
.map(|name| name.Value())
|
.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) {
|
fn update_checked_state(self, checked: bool) {
|
||||||
self.checked.set(checked);
|
self.checked.set(checked);
|
||||||
if self.input_type.get() == InputRadio && 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
|
// https://html.spec.whatwg.org/multipage/forms.html#radio-button-state-(type=radio):pre-click-activation-steps
|
||||||
InputRadio => {
|
InputRadio => {
|
||||||
//TODO: if not in document, use root ancestor instead of document
|
//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 = document_from_node(*self).root();
|
||||||
let doc_node: JSRef<Node> = NodeCast::from_ref(*doc);
|
let doc_node: JSRef<Node> = NodeCast::from_ref(*doc);
|
||||||
let group = self.get_radio_group_name();;
|
let group = self.get_radio_group_name();;
|
||||||
|
@ -591,7 +590,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
||||||
let checked_member = unsafe {
|
let checked_member = unsafe {
|
||||||
doc_node.query_selector_iter("input[type=radio]".to_string()).unwrap()
|
doc_node.query_selector_iter("input[type=radio]".to_string()).unwrap()
|
||||||
.filter_map(|t| HTMLInputElementCast::to_ref(t))
|
.filter_map(|t| HTMLInputElementCast::to_ref(t))
|
||||||
.filter(|&r| self.in_same_group(r, owner,
|
.filter(|&r| in_same_group(r, owner.root_ref(),
|
||||||
group.as_ref().map(|gr| gr.as_slice())))
|
group.as_ref().map(|gr| gr.as_slice())))
|
||||||
.find(|r| r.Checked())
|
.find(|r| r.Checked())
|
||||||
};
|
};
|
||||||
|
@ -673,14 +672,14 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
||||||
// https://html.spec.whatwg.org/multipage/forms.html#radio-button-state-(type=radio):activation-behavior
|
// https://html.spec.whatwg.org/multipage/forms.html#radio-button-state-(type=radio):activation-behavior
|
||||||
if self.mutable() {
|
if self.mutable() {
|
||||||
let win = window_from_node(*self).root();
|
let win = window_from_node(*self).root();
|
||||||
let event = Event::new(&Window(*win),
|
let event = Event::new(Window(*win),
|
||||||
"input".to_string(),
|
"input".to_string(),
|
||||||
Bubbles, NotCancelable).root();
|
Bubbles, NotCancelable).root();
|
||||||
event.set_trusted(true);
|
event.set_trusted(true);
|
||||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(*self);
|
let target: JSRef<EventTarget> = EventTargetCast::from_ref(*self);
|
||||||
target.DispatchEvent(*event).ok();
|
target.DispatchEvent(*event).ok();
|
||||||
|
|
||||||
let event = Event::new(&Window(*win),
|
let event = Event::new(Window(*win),
|
||||||
"change".to_string(),
|
"change".to_string(),
|
||||||
Bubbles, NotCancelable).root();
|
Bubbles, NotCancelable).root();
|
||||||
event.set_trusted(true);
|
event.set_trusted(true);
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::DocumentBinding::{DocumentMethods, Documen
|
||||||
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
||||||
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
||||||
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
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::conversions::{FromJSValConvertible, Empty};
|
||||||
use dom::bindings::global;
|
use dom::bindings::global;
|
||||||
use dom::bindings::js::{JS, JSRef, RootCollection, Temporary, OptionalRootable};
|
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)]
|
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "oncanplaythrough" with the proper type (99)]
|
||||||
expected: FAIL
|
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)]
|
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onclose" with the proper type (102)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -9645,9 +9642,6 @@
|
||||||
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onfocus" with the proper type (118)]
|
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "onfocus" with the proper type (118)]
|
||||||
expected: FAIL
|
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)]
|
[Document interface: document.implementation.createDocument(null, "", null) must inherit property "oninvalid" with the proper type (120)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue