1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::InheritTypes::ElementCast;
use dom::bindings::codegen::InheritTypes::HTMLAnchorElementCast;
use dom::bindings::codegen::InheritTypes::HTMLBodyElementCast;
use dom::bindings::codegen::InheritTypes::HTMLElementCast;
use dom::bindings::codegen::InheritTypes::HTMLIFrameElementCast;
use dom::bindings::codegen::InheritTypes::HTMLImageElementCast;
use dom::bindings::codegen::InheritTypes::HTMLObjectElementCast;
use dom::bindings::codegen::InheritTypes::HTMLStyleElementCast;
use dom::bindings::js::JSRef;
use dom::element::Element;
use dom::element::{ElementTypeId, HTMLAnchorElementTypeId, HTMLBodyElementTypeId, HTMLImageElementTypeId};
use dom::element::{HTMLIFrameElementTypeId, HTMLObjectElementTypeId, HTMLStyleElementTypeId};
use dom::event::Event;
use dom::htmlanchorelement::HTMLAnchorElement;
use dom::htmlbodyelement::HTMLBodyElement;
use dom::htmlelement::HTMLElement;
use dom::htmliframeelement::HTMLIFrameElement;
use dom::htmlimageelement::HTMLImageElement;
use dom::htmlobjectelement::HTMLObjectElement;
use dom::htmlstyleelement::HTMLStyleElement;
use dom::node::{Node, NodeHelpers, ElementNodeTypeId};
use servo_util::str::DOMString;
/// Trait to allow DOM nodes to opt-in to overriding (or adding to) common
/// behaviours. Replicates the effect of C++ virtual methods.
pub trait VirtualMethods {
/// Returns self as the superclass of the implementation for this trait,
/// if any.
fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:>;
/// Called when changing or adding attributes, after the attribute's value
/// has been updated.
fn after_set_attr(&mut self, name: DOMString, value: DOMString) {
match self.super_type() {
Some(ref mut s) => s.after_set_attr(name, value),
_ => (),
}
}
/// Called when changing or removing attributes, before any modification
/// has taken place.
fn before_remove_attr(&mut self, name: DOMString, value: DOMString) {
match self.super_type() {
Some(ref mut s) => s.before_remove_attr(name, value),
_ => (),
}
}
/// Called when a Node is appended to a tree that is part of a Document.
fn bind_to_tree(&mut self) {
match self.super_type() {
Some(ref mut s) => s.bind_to_tree(),
_ => (),
}
}
/// Called when a Node is removed from a tree that is part of a Document.
fn unbind_from_tree(&mut self) {
match self.super_type() {
Some(ref mut s) => s.unbind_from_tree(),
_ => (),
}
}
/// Called on the parent when a node is added to its child list.
fn child_inserted(&mut self, child: &JSRef<Node>) {
match self.super_type() {
Some(ref mut s) => s.child_inserted(child),
_ => (),
}
}
/// Called during event dispatch after the bubbling phase completes.
fn handle_event(&mut self, event: &JSRef<Event>) {
match self.super_type() {
Some(s) => {
s.handle_event(event);
}
_ => (),
}
}
}
/// Obtain a VirtualMethods instance for a given Node-derived object. Any
/// method call on the trait object will invoke the corresponding method on the
/// concrete type, propagating up the parent hierarchy unless otherwise
/// interrupted.
pub fn vtable_for<'a>(node: &'a mut JSRef<Node>) -> &'a mut VirtualMethods: {
match node.type_id() {
ElementNodeTypeId(HTMLAnchorElementTypeId) => {
let element: &mut JSRef<HTMLAnchorElement> = HTMLAnchorElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(HTMLBodyElementTypeId) => {
let element: &mut JSRef<HTMLBodyElement> = HTMLBodyElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(HTMLImageElementTypeId) => {
let element: &mut JSRef<HTMLImageElement> = HTMLImageElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(HTMLIFrameElementTypeId) => {
let element: &mut JSRef<HTMLIFrameElement> = HTMLIFrameElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(HTMLObjectElementTypeId) => {
let element: &mut JSRef<HTMLObjectElement> = HTMLObjectElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(HTMLStyleElementTypeId) => {
let element: &mut JSRef<HTMLStyleElement> = HTMLStyleElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(ElementTypeId) => {
let element: &mut JSRef<Element> = ElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
ElementNodeTypeId(_) => {
let element: &mut JSRef<HTMLElement> = HTMLElementCast::to_mut_ref(node).unwrap();
element as &mut VirtualMethods:
}
_ => {
node as &mut VirtualMethods:
}
}
}
|