mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Introduce trait Castable
This trait is used to hold onto the downcast and upcast functions of all castable IDL interfaces. A castable IDL interface is one which either derives from or is derived by other interfaces. The deriving relation is represented by implementations of marker trait DerivedFrom<T: Castable> generated in InheritTypes. /^[ ]*use dom::bindings::codegen::InheritTypes::.*(Base|Cast|Derived)/ { /::[a-zA-Z]+(Base|Cast|Derived);/d s/([{ ])[a-zA-Z]+(Base|Cast|Derived), /\1/g s/([{ ])[a-zA-Z]+(Base|Cast|Derived), /\1/g s/, [a-zA-Z]+(Base|Cast|Derived)([},])/\2/g s/, [a-zA-Z]+(Base|Cast|Derived)([},])/\2/g /\{([a-zA-Z]+(Base|Cast|Derived))?\};$/d s/\{([a-zA-Z_]+)\};$/\1;/ } s/([a-zA-Z]+)Cast::from_ref\(\&?\**([a-zA-Z_]+)(\.r\(\))?\)/\2.upcast::<\1>()/g s/([a-zA-Z]+)Cast::from_ref\(\&?\**([a-zA-Z_]+)(\.[a-zA-Z_]+\(\))?\)/\2\3.upcast::<\1>()/g s/\(([a-zA-Z]+)Cast::from_ref\)/\(Castable::upcast::<\1>\)/g s/([a-zA-Z]+)Cast::from_root/Root::upcast::<\1>/g s/([a-zA-Z]+)Cast::from_layout_js\(\&([a-zA-Z_.]+)\)/\2.upcast::<\1>()/g s/([a-zA-Z]+)Cast::to_ref\(\&?\**([a-zA-Z_]+)(\.r\(\))?\)/\2.downcast::<\1>()/g s/([a-zA-Z]+)Cast::to_ref\(\&?\**([a-zA-Z_]+)(\.[a-zA-Z_]+\(\))?\)/\2\3.downcast::<\1>()/g s/\(([a-zA-Z]+)Cast::to_ref\)/\(Castable::downcast::<\1>\)/g s/([a-zA-Z]+)Cast::to_root/Root::downcast::<\1>/g s/([a-zA-Z]+)Cast::to_layout_js\(&?([a-zA-Z_.]+(\(\))?)\)/\2.downcast::<\1>()/g s/\.is_document\(\)/.is::<Document>()/g s/\.is_htmlanchorelement\(\)/.is::<HTMLAnchorElement>()/g s/\.is_htmlappletelement\(\)/.is::<HTMLAppletElement>()/g s/\.is_htmlareaelement\(\)/.is::<HTMLAreaElement>()/g s/\.is_htmlbodyelement\(\)/.is::<HTMLBodyElement>()/g s/\.is_htmlembedelement\(\)/.is::<HTMLEmbedElement>()/g s/\.is_htmlfieldsetelement\(\)/.is::<HTMLFieldSetElement>()/g s/\.is_htmlformelement\(\)/.is::<HTMLFormElement>()/g s/\.is_htmlframesetelement\(\)/.is::<HTMLFrameSetElement>()/g s/\.is_htmlhtmlelement\(\)/.is::<HTMLHtmlElement>()/g s/\.is_htmlimageelement\(\)/.is::<HTMLImageElement>()/g s/\.is_htmllegendelement\(\)/.is::<HTMLLegendElement>()/g s/\.is_htmloptgroupelement\(\)/.is::<HTMLOptGroupElement>()/g s/\.is_htmloptionelement\(\)/.is::<HTMLOptionElement>()/g s/\.is_htmlscriptelement\(\)/.is::<HTMLScriptElement>()/g s/\.is_htmltabledatacellelement\(\)/.is::<HTMLTableDataCellElement>()/g s/\.is_htmltableheadercellelement\(\)/.is::<HTMLTableHeaderCellElement>()/g s/\.is_htmltablerowelement\(\)/.is::<HTMLTableRowElement>()/g s/\.is_htmltablesectionelement\(\)/.is::<HTMLTableSectionElement>()/g s/\.is_htmltitleelement\(\)/.is::<HTMLTitleElement>()/g
This commit is contained in:
parent
bd363b009d
commit
13ea3ac413
82 changed files with 1124 additions and 1148 deletions
|
@ -11,9 +11,7 @@ use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
|||
use dom::bindings::codegen::Bindings::HTMLInputElementBinding;
|
||||
use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods;
|
||||
use dom::bindings::codegen::Bindings::KeyboardEventBinding::KeyboardEventMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, HTMLElementCast};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLFieldSetElementDerived, HTMLInputElementCast};
|
||||
use dom::bindings::codegen::InheritTypes::{KeyboardEventCast, NodeCast};
|
||||
use dom::bindings::conversions::Castable;
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{JS, LayoutJS, Root, RootedReference};
|
||||
use dom::document::Document;
|
||||
|
@ -21,6 +19,7 @@ use dom::element::{AttributeMutation, Element, IN_ENABLED_STATE, RawLayoutElemen
|
|||
use dom::event::{Event, EventBubbles, EventCancelable};
|
||||
use dom::eventtarget::EventTarget;
|
||||
use dom::htmlelement::HTMLElement;
|
||||
use dom::htmlfieldsetelement::HTMLFieldSetElement;
|
||||
use dom::htmlformelement::{FormControl, FormDatum, FormSubmitter, HTMLFormElement};
|
||||
use dom::htmlformelement::{ResetFrom, SubmittedFrom};
|
||||
use dom::keyboardevent::KeyboardEvent;
|
||||
|
@ -165,7 +164,7 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> {
|
|||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn get_raw_attr_value(input: LayoutJS<HTMLInputElement>) -> Option<String> {
|
||||
let elem = ElementCast::from_layout_js(&input);
|
||||
let elem = input.upcast::<Element>();
|
||||
(*elem.unsafe_get()).get_attr_val_for_layout(&ns!(""), &atom!("value"))
|
||||
.map(|s| s.to_owned())
|
||||
}
|
||||
|
@ -354,13 +353,13 @@ fn broadcast_radio_checked(broadcaster: &HTMLInputElement, group: Option<&Atom>)
|
|||
//TODO: if not in document, use root ancestor instead of document
|
||||
let owner = broadcaster.form_owner();
|
||||
let doc = document_from_node(broadcaster);
|
||||
let doc_node = NodeCast::from_ref(doc.r());
|
||||
let doc_node = doc.upcast::<Node>();
|
||||
|
||||
// This function is a workaround for lifetime constraint difficulties.
|
||||
fn do_broadcast(doc_node: &Node, broadcaster: &HTMLInputElement,
|
||||
owner: Option<&HTMLFormElement>, group: Option<&Atom>) {
|
||||
let iter = doc_node.query_selector_iter("input[type=radio]".to_owned())
|
||||
.unwrap().filter_map(HTMLInputElementCast::to_root)
|
||||
let iter = doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap()
|
||||
.filter_map(Root::downcast::<HTMLInputElement>)
|
||||
.filter(|r| in_same_group(r.r(), owner, group) && broadcaster != r.r());
|
||||
for ref r in iter {
|
||||
if r.r().Checked() {
|
||||
|
@ -389,7 +388,7 @@ fn in_same_group(other: &HTMLInputElement, owner: Option<&HTMLFormElement>,
|
|||
impl HTMLInputElement {
|
||||
fn force_relayout(&self) {
|
||||
let doc = document_from_node(self);
|
||||
let node = NodeCast::from_ref(self);
|
||||
let node = self.upcast::<Node>();
|
||||
doc.r().content_changed(node, NodeDamage::OtherNodeDamage)
|
||||
}
|
||||
|
||||
|
@ -440,7 +439,7 @@ impl HTMLInputElement {
|
|||
// https://html.spec.whatwg.org/multipage/#radio-button-group
|
||||
fn get_radio_group_name(&self) -> Option<Atom> {
|
||||
//TODO: determine form owner
|
||||
let elem = ElementCast::from_ref(self);
|
||||
let elem = self.upcast::<Element>();
|
||||
elem.get_attribute(&ns!(""), &atom!("name"))
|
||||
.map(|name| name.value().as_atom().clone())
|
||||
}
|
||||
|
@ -469,7 +468,7 @@ impl HTMLInputElement {
|
|||
fn mutable(&self) -> bool {
|
||||
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-fe-mutable
|
||||
// https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable
|
||||
let el = ElementCast::from_ref(self);
|
||||
let el = self.upcast::<Element>();
|
||||
!(el.get_disabled_state() || self.ReadOnly())
|
||||
}
|
||||
|
||||
|
@ -492,7 +491,7 @@ impl HTMLInputElement {
|
|||
|
||||
impl VirtualMethods for HTMLInputElement {
|
||||
fn super_type(&self) -> Option<&VirtualMethods> {
|
||||
let htmlelement: &HTMLElement = HTMLElementCast::from_ref(self);
|
||||
let htmlelement: &HTMLElement = self.upcast::<HTMLElement>();
|
||||
Some(htmlelement as &VirtualMethods)
|
||||
}
|
||||
|
||||
|
@ -508,7 +507,7 @@ impl VirtualMethods for HTMLInputElement {
|
|||
},
|
||||
AttributeMutation::Removed => false,
|
||||
};
|
||||
let el = ElementCast::from_ref(self);
|
||||
let el = self.upcast::<Element>();
|
||||
el.set_disabled_state(disabled_state);
|
||||
el.set_enabled_state(!disabled_state);
|
||||
el.check_ancestors_disabled_state_for_form_control();
|
||||
|
@ -593,7 +592,7 @@ impl VirtualMethods for HTMLInputElement {
|
|||
s.bind_to_tree(tree_in_doc);
|
||||
}
|
||||
|
||||
let el = ElementCast::from_ref(self);
|
||||
let el = self.upcast::<Element>();
|
||||
el.check_ancestors_disabled_state_for_form_control();
|
||||
}
|
||||
|
||||
|
@ -602,9 +601,9 @@ impl VirtualMethods for HTMLInputElement {
|
|||
s.unbind_from_tree(tree_in_doc);
|
||||
}
|
||||
|
||||
let node = NodeCast::from_ref(self);
|
||||
let el = ElementCast::from_ref(self);
|
||||
if node.ancestors().any(|ancestor| ancestor.r().is_htmlfieldsetelement()) {
|
||||
let node = self.upcast::<Node>();
|
||||
let el = self.upcast::<Element>();
|
||||
if node.ancestors().any(|ancestor| ancestor.is::<HTMLFieldSetElement>()) {
|
||||
el.check_ancestors_disabled_state_for_form_control();
|
||||
} else {
|
||||
el.check_disabled_attribute();
|
||||
|
@ -628,11 +627,11 @@ impl VirtualMethods for HTMLInputElement {
|
|||
//TODO: set the editing position for text inputs
|
||||
|
||||
let doc = document_from_node(self);
|
||||
doc.r().request_focus(ElementCast::from_ref(self));
|
||||
doc.r().request_focus(self.upcast::<Element>());
|
||||
} else if &*event.Type() == "keydown" && !event.DefaultPrevented() &&
|
||||
(self.input_type.get() == InputType::InputText ||
|
||||
self.input_type.get() == InputType::InputPassword) {
|
||||
let keyevent: Option<&KeyboardEvent> = KeyboardEventCast::to_ref(event);
|
||||
let keyevent: Option<&KeyboardEvent> = event.downcast::<KeyboardEvent>();
|
||||
keyevent.map(|keyevent| {
|
||||
// This can't be inlined, as holding on to textinput.borrow_mut()
|
||||
// during self.implicit_submission will cause a panic.
|
||||
|
@ -663,7 +662,7 @@ impl FormControl for HTMLInputElement {}
|
|||
|
||||
impl Activatable for HTMLInputElement {
|
||||
fn as_element(&self) -> &Element {
|
||||
ElementCast::from_ref(self)
|
||||
self.upcast::<Element>()
|
||||
}
|
||||
|
||||
fn is_instance_activatable(&self) -> bool {
|
||||
|
@ -708,11 +707,12 @@ impl Activatable for HTMLInputElement {
|
|||
//TODO: if not in document, use root ancestor instead of document
|
||||
let owner = self.form_owner();
|
||||
let doc = document_from_node(self);
|
||||
let doc_node = NodeCast::from_ref(doc.r());
|
||||
let doc_node = doc.upcast::<Node>();
|
||||
let group = self.get_radio_group_name();;
|
||||
|
||||
// Safe since we only manipulate the DOM tree after finding an element
|
||||
let checked_member = doc_node.query_selector_iter("input[type=radio]".to_owned()).unwrap()
|
||||
.filter_map(HTMLInputElementCast::to_root)
|
||||
.filter_map(Root::downcast::<HTMLInputElement>)
|
||||
.find(|r| {
|
||||
in_same_group(r.r(), owner.r(), group.as_ref()) &&
|
||||
r.r().Checked()
|
||||
|
@ -813,14 +813,14 @@ impl Activatable for HTMLInputElement {
|
|||
"input".to_owned(),
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::NotCancelable);
|
||||
let target = EventTargetCast::from_ref(self);
|
||||
let target = self.upcast::<EventTarget>();
|
||||
event.r().fire(target);
|
||||
|
||||
let event = Event::new(GlobalRef::Window(win.r()),
|
||||
"change".to_owned(),
|
||||
EventBubbles::Bubbles,
|
||||
EventCancelable::NotCancelable);
|
||||
let target = EventTargetCast::from_ref(self);
|
||||
let target = self.upcast::<EventTarget>();
|
||||
event.r().fire(target);
|
||||
}
|
||||
},
|
||||
|
@ -832,20 +832,20 @@ impl Activatable for HTMLInputElement {
|
|||
#[allow(unsafe_code)]
|
||||
fn implicit_submission(&self, ctrlKey: bool, shiftKey: bool, altKey: bool, metaKey: bool) {
|
||||
let doc = document_from_node(self);
|
||||
let node = NodeCast::from_ref(doc.r());
|
||||
let node = doc.upcast::<Node>();
|
||||
let owner = self.form_owner();
|
||||
let form = match owner {
|
||||
None => return,
|
||||
Some(ref f) => f
|
||||
};
|
||||
|
||||
let elem = ElementCast::from_ref(self);
|
||||
let elem = self.upcast::<Element>();
|
||||
if elem.click_in_progress() {
|
||||
return;
|
||||
}
|
||||
let submit_button;
|
||||
submit_button = node.query_selector_iter("input[type=submit]".to_owned()).unwrap()
|
||||
.filter_map(HTMLInputElementCast::to_root)
|
||||
.filter_map(Root::downcast::<HTMLInputElement>)
|
||||
.find(|r| r.r().form_owner() == owner);
|
||||
match submit_button {
|
||||
Some(ref button) => {
|
||||
|
@ -855,7 +855,7 @@ impl Activatable for HTMLInputElement {
|
|||
}
|
||||
None => {
|
||||
let inputs = node.query_selector_iter("input".to_owned()).unwrap()
|
||||
.filter_map(HTMLInputElementCast::to_root)
|
||||
.filter_map(Root::downcast::<HTMLInputElement>)
|
||||
.filter(|input| {
|
||||
input.r().form_owner() == owner && match &*input.r().Type() {
|
||||
"text" | "search" | "url" | "tel" |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue