diff options
author | Josh Matthews <josh@joshmatthews.net> | 2014-04-09 20:02:40 +0200 |
---|---|---|
committer | Ms2ger <ms2ger@gmail.com> | 2014-04-10 10:27:28 +0200 |
commit | ca6cfb5bca2ffbb41dd7735557f11fb5726be6e4 (patch) | |
tree | d2f94f87e1e1c5ca84c02ea45d7bf5cf9d3c1080 /src/components/script/dom/virtualmethods.rs | |
parent | ea2560ef20ec1116b0897e84fb58eb14a8ea4696 (diff) | |
download | servo-ca6cfb5bca2ffbb41dd7735557f11fb5726be6e4.tar.gz servo-ca6cfb5bca2ffbb41dd7735557f11fb5726be6e4.zip |
Add support for trait-based virtual methods on Nodes, and use it for before_remove_attr and after_set_attr.
Diffstat (limited to 'src/components/script/dom/virtualmethods.rs')
-rw-r--r-- | src/components/script/dom/virtualmethods.rs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/components/script/dom/virtualmethods.rs b/src/components/script/dom/virtualmethods.rs new file mode 100644 index 00000000000..f189f0443e8 --- /dev/null +++ b/src/components/script/dom/virtualmethods.rs @@ -0,0 +1,77 @@ +/* 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::HTMLElementCast; +use dom::bindings::codegen::InheritTypes::HTMLIFrameElementCast; +use dom::bindings::codegen::InheritTypes::HTMLImageElementCast; +use dom::bindings::codegen::InheritTypes::HTMLObjectElementCast; +use dom::bindings::js::JS; +use dom::element::Element; +use dom::element::{ElementTypeId, HTMLImageElementTypeId}; +use dom::element::{HTMLIFrameElementTypeId, HTMLObjectElementTypeId}; +use dom::htmlelement::HTMLElement; +use dom::htmliframeelement::HTMLIFrameElement; +use dom::htmlimageelement::HTMLImageElement; +use dom::htmlobjectelement::HTMLObjectElement; +use dom::node::{Node, 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(&self) -> Option<~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), + _ => (), + } + } +} + +/// 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: &JS<Node>) -> ~VirtualMethods: { + match node.get().type_id { + ElementNodeTypeId(HTMLImageElementTypeId) => { + let element: JS<HTMLImageElement> = HTMLImageElementCast::to(node).unwrap(); + ~element as ~VirtualMethods: + } + ElementNodeTypeId(HTMLIFrameElementTypeId) => { + let element: JS<HTMLIFrameElement> = HTMLIFrameElementCast::to(node).unwrap(); + ~element as ~VirtualMethods: + } + ElementNodeTypeId(HTMLObjectElementTypeId) => { + let element: JS<HTMLObjectElement> = HTMLObjectElementCast::to(node).unwrap(); + ~element as ~VirtualMethods: + } + ElementNodeTypeId(ElementTypeId) => { + let element: JS<Element> = ElementCast::to(node).unwrap(); + ~element as ~VirtualMethods: + } + ElementNodeTypeId(_) => { + let element: JS<HTMLElement> = HTMLElementCast::to(node).unwrap(); + ~element as ~VirtualMethods: + } + _ => { + ~node.clone() as ~VirtualMethods: + } + } +} |