diff options
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/create.rs | 53 | ||||
-rw-r--r-- | components/script/dom/mod.rs | 3 | ||||
-rw-r--r-- | components/script/dom/node.rs | 16 | ||||
-rw-r--r-- | components/script/dom/svgelement.rs | 48 | ||||
-rw-r--r-- | components/script/dom/svggraphicselement.rs | 48 | ||||
-rw-r--r-- | components/script/dom/svgsvgelement.rs | 83 | ||||
-rw-r--r-- | components/script/dom/virtualmethods.rs | 8 | ||||
-rw-r--r-- | components/script/dom/webidls/SVGElement.webidl | 22 | ||||
-rw-r--r-- | components/script/dom/webidls/SVGGraphicsElement.webidl | 22 | ||||
-rw-r--r-- | components/script/dom/webidls/SVGSVGElement.webidl | 45 |
10 files changed, 338 insertions, 10 deletions
diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs index 6cdaf2b0e78..98a2e5ad4ed 100644 --- a/components/script/dom/create.rs +++ b/components/script/dom/create.rs @@ -76,21 +76,44 @@ use dom::htmltrackelement::HTMLTrackElement; use dom::htmlulistelement::HTMLUListElement; use dom::htmlunknownelement::HTMLUnknownElement; use dom::htmlvideoelement::HTMLVideoElement; +use dom::svgsvgelement::SVGSVGElement; use string_cache::{Atom, QualName}; +use util::prefs::PREFS; -pub fn create_element(name: QualName, - prefix: Option<Atom>, - document: &Document, - creator: ElementCreator) +fn create_svg_element(name: QualName, + prefix: Option<DOMString>, + document: &Document) -> Root<Element> { - // FIXME(ajeffrey): Convert directly from Atom to DOMString. + assert!(name.ns == ns!(svg)); - let prefix = prefix.map(|p| DOMString::from(&*p)); + macro_rules! make( + ($ctor:ident) => ({ + let obj = $ctor::new(name.local, prefix, document); + Root::upcast(obj) + }); + ($ctor:ident, $($arg:expr),+) => ({ + let obj = $ctor::new(name.local, prefix, document, $($arg),+); + Root::upcast(obj) + }) + ); - if name.ns != ns!(html) { + if !PREFS.get("dom.svg.enabled").as_boolean().unwrap_or(false) { return Element::new(name.local, name.ns, prefix, document); } + match name.local { + atom!("svg") => make!(SVGSVGElement), + _ => Element::new(name.local, name.ns, prefix, document), + } +} + +fn create_html_element(name: QualName, + prefix: Option<DOMString>, + document: &Document, + creator: ElementCreator) + -> Root<Element> { + assert!(name.ns == ns!(html)); + macro_rules! make( ($ctor:ident) => ({ let obj = $ctor::new(name.local, prefix, document); @@ -249,3 +272,19 @@ pub fn create_element(name: QualName, _ => make!(HTMLUnknownElement), } } + +pub fn create_element(name: QualName, + prefix: Option<Atom>, + document: &Document, + creator: ElementCreator) + -> Root<Element> { + // FIXME(ajeffrey): Convert directly from Atom to DOMString. + + let prefix = prefix.map(|p| DOMString::from(&*p)); + + match name.ns { + ns!(html) => create_html_element(name, prefix, document, creator), + ns!(svg) => create_svg_element(name, prefix, document), + _ => Element::new(name.local, name.ns, prefix, document) + } +} diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 2335f8a0a25..ace4f979be6 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -392,6 +392,9 @@ pub mod storage; pub mod storageevent; pub mod stylesheet; pub mod stylesheetlist; +pub mod svgelement; +pub mod svggraphicselement; +pub mod svgsvgelement; pub mod testbinding; pub mod testbindingiterable; pub mod testbindingpairiterable; diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index c18613ac6a2..b52a8aec965 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -22,6 +22,7 @@ use dom::bindings::conversions::{self, DerivedFrom}; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::inheritance::{Castable, CharacterDataTypeId, ElementTypeId}; use dom::bindings::inheritance::{EventTargetTypeId, HTMLElementTypeId, NodeTypeId}; +use dom::bindings::inheritance::{SVGElementTypeId, SVGGraphicsElementTypeId}; use dom::bindings::js::{JS, LayoutJS, MutNullableHeap}; use dom::bindings::js::Root; use dom::bindings::js::RootedReference; @@ -36,7 +37,7 @@ use dom::element::{Element, ElementCreator}; use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::htmlbodyelement::HTMLBodyElement; -use dom::htmlcanvaselement::LayoutHTMLCanvasElementHelpers; +use dom::htmlcanvaselement::{HTMLCanvasElement, LayoutHTMLCanvasElementHelpers}; use dom::htmlcollection::HTMLCollection; use dom::htmlelement::HTMLElement; use dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementLayoutMethods}; @@ -46,6 +47,7 @@ use dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHel use dom::nodelist::NodeList; use dom::processinginstruction::ProcessingInstruction; use dom::range::WeakRangeVec; +use dom::svgsvgelement::{SVGSVGElement, LayoutSVGSVGElementHelpers}; use dom::text::Text; use dom::virtualmethods::{VirtualMethods, vtable_for}; use dom::window::Window; @@ -59,7 +61,7 @@ use libc::{self, c_void, uintptr_t}; use msg::constellation_msg::PipelineId; use parse::html::parse_html_fragment; use ref_slice::ref_slice; -use script_layout_interface::{HTMLCanvasData, OpaqueStyleAndLayoutData}; +use script_layout_interface::{HTMLCanvasData, OpaqueStyleAndLayoutData, SVGSVGData}; use script_layout_interface::{LayoutElementType, LayoutNodeType, TrustedNodeAddress}; use script_layout_interface::message::Msg; use script_traits::UntrustedNodeAddress; @@ -955,6 +957,7 @@ pub trait LayoutNodeHelpers { fn selection(&self) -> Option<Range<usize>>; fn image_url(&self) -> Option<Url>; fn canvas_data(&self) -> Option<HTMLCanvasData>; + fn svg_data(&self) -> Option<SVGSVGData>; fn iframe_pipeline_id(&self) -> PipelineId; fn opaque(&self) -> OpaqueNode; } @@ -1088,10 +1091,15 @@ impl LayoutNodeHelpers for LayoutJS<Node> { } fn canvas_data(&self) -> Option<HTMLCanvasData> { - self.downcast() + self.downcast::<HTMLCanvasElement>() .map(|canvas| canvas.data()) } + fn svg_data(&self) -> Option<SVGSVGData> { + self.downcast::<SVGSVGElement>() + .map(|svg| svg.data()) + } + fn iframe_pipeline_id(&self) -> PipelineId { let iframe_element = self.downcast::<HTMLIFrameElement>() .expect("not an iframe element!"); @@ -2689,6 +2697,8 @@ impl Into<LayoutElementType> for ElementTypeId { LayoutElementType::HTMLTableSectionElement, ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement) => LayoutElementType::HTMLTextAreaElement, + ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(SVGGraphicsElementTypeId::SVGSVGElement)) => + LayoutElementType::SVGSVGElement, _ => LayoutElementType::Element, } } diff --git a/components/script/dom/svgelement.rs b/components/script/dom/svgelement.rs new file mode 100644 index 00000000000..95fd42c40b6 --- /dev/null +++ b/components/script/dom/svgelement.rs @@ -0,0 +1,48 @@ +/* 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::Bindings::SVGElementBinding; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::Root; +use dom::bindings::str::DOMString; +use dom::document::Document; +use dom::element::Element; +use dom::node::Node; +use dom::virtualmethods::VirtualMethods; +use string_cache::Atom; +use style::element_state::ElementState; + +#[dom_struct] +pub struct SVGElement { + element: Element, +} + +impl SVGElement { + pub fn new_inherited(tag_name: Atom, prefix: Option<DOMString>, + document: &Document) -> SVGElement { + SVGElement::new_inherited_with_state(ElementState::empty(), tag_name, prefix, document) + } + + pub fn new_inherited_with_state(state: ElementState, tag_name: Atom, + prefix: Option<DOMString>, document: &Document) + -> SVGElement { + SVGElement { + element: + Element::new_inherited_with_state(state, tag_name, ns!(svg), prefix, document), + } + } + + #[allow(unrooted_must_root)] + pub fn new(local_name: Atom, prefix: Option<DOMString>, document: &Document) -> Root<SVGElement> { + Node::reflect_node(box SVGElement::new_inherited(local_name, prefix, document), + document, + SVGElementBinding::Wrap) + } +} + +impl VirtualMethods for SVGElement { + fn super_type(&self) -> Option<&VirtualMethods> { + Some(self.upcast::<Element>() as &VirtualMethods) + } +} diff --git a/components/script/dom/svggraphicselement.rs b/components/script/dom/svggraphicselement.rs new file mode 100644 index 00000000000..bd7c8d581f7 --- /dev/null +++ b/components/script/dom/svggraphicselement.rs @@ -0,0 +1,48 @@ +/* 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::Bindings::SVGGraphicsElementBinding; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::Root; +use dom::bindings::str::DOMString; +use dom::document::Document; +use dom::node::Node; +use dom::svgelement::SVGElement; +use dom::virtualmethods::VirtualMethods; +use string_cache::Atom; +use style::element_state::ElementState; + +#[dom_struct] +pub struct SVGGraphicsElement { + svgelement: SVGElement, +} + +impl SVGGraphicsElement { + pub fn new_inherited(tag_name: Atom, prefix: Option<DOMString>, + document: &Document) -> SVGGraphicsElement { + SVGGraphicsElement::new_inherited_with_state(ElementState::empty(), tag_name, prefix, document) + } + + pub fn new_inherited_with_state(state: ElementState, tag_name: Atom, + prefix: Option<DOMString>, document: &Document) + -> SVGGraphicsElement { + SVGGraphicsElement { + svgelement: + SVGElement::new_inherited_with_state(state, tag_name, prefix, document), + } + } + + #[allow(unrooted_must_root)] + pub fn new(local_name: Atom, prefix: Option<DOMString>, document: &Document) -> Root<SVGGraphicsElement> { + Node::reflect_node(box SVGGraphicsElement::new_inherited(local_name, prefix, document), + document, + SVGGraphicsElementBinding::Wrap) + } +} + +impl VirtualMethods for SVGGraphicsElement { + fn super_type(&self) -> Option<&VirtualMethods> { + Some(self.upcast::<SVGElement>() as &VirtualMethods) + } +} diff --git a/components/script/dom/svgsvgelement.rs b/components/script/dom/svgsvgelement.rs new file mode 100644 index 00000000000..11c1e35b9e9 --- /dev/null +++ b/components/script/dom/svgsvgelement.rs @@ -0,0 +1,83 @@ +/* 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::attr::Attr; +use dom::bindings::codegen::Bindings::SVGSVGElementBinding; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::{LayoutJS, Root}; +use dom::bindings::str::DOMString; +use dom::document::Document; +use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers}; +use dom::node::Node; +use dom::svggraphicselement::SVGGraphicsElement; +use dom::virtualmethods::VirtualMethods; +use script_layout_interface::SVGSVGData; +use string_cache::Atom; +use style::attr::AttrValue; + +const DEFAULT_WIDTH: u32 = 300; +const DEFAULT_HEIGHT: u32 = 150; + +#[dom_struct] +pub struct SVGSVGElement { + svggraphicselement: SVGGraphicsElement +} + +impl SVGSVGElement { + fn new_inherited(local_name: Atom, + prefix: Option<DOMString>, + document: &Document) -> SVGSVGElement { + SVGSVGElement { + svggraphicselement: + SVGGraphicsElement::new_inherited(local_name, prefix, document) + } + } + + #[allow(unrooted_must_root)] + pub fn new(local_name: Atom, + prefix: Option<DOMString>, + document: &Document) -> Root<SVGSVGElement> { + Node::reflect_node(box SVGSVGElement::new_inherited(local_name, prefix, document), + document, + SVGSVGElementBinding::Wrap) + } +} + +pub trait LayoutSVGSVGElementHelpers { + fn data(&self) -> SVGSVGData; +} + +impl LayoutSVGSVGElementHelpers for LayoutJS<SVGSVGElement> { + #[allow(unsafe_code)] + fn data(&self) -> SVGSVGData { + unsafe { + let SVG = &*self.unsafe_get(); + + let width_attr = SVG.upcast::<Element>().get_attr_for_layout(&ns!(), &atom!("width")); + let height_attr = SVG.upcast::<Element>().get_attr_for_layout(&ns!(), &atom!("height")); + SVGSVGData { + width: width_attr.map_or(DEFAULT_WIDTH, |val| val.as_uint()), + height: height_attr.map_or(DEFAULT_HEIGHT, |val| val.as_uint()), + } + } + } +} + +impl VirtualMethods for SVGSVGElement { + fn super_type(&self) -> Option<&VirtualMethods> { + Some(self.upcast::<SVGGraphicsElement>() as &VirtualMethods) + } + + fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { + self.super_type().unwrap().attribute_mutated(attr, mutation); + } + + fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue { + match name { + &atom!("width") => AttrValue::from_u32(value.into(), DEFAULT_WIDTH), + &atom!("height") => AttrValue::from_u32(value.into(), DEFAULT_HEIGHT), + _ => self.super_type().unwrap().parse_plain_attribute(name, value), + } + } +} diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs index d4cf1609568..c8a8a7436a4 100644 --- a/components/script/dom/virtualmethods.rs +++ b/components/script/dom/virtualmethods.rs @@ -7,6 +7,8 @@ use dom::bindings::inheritance::Castable; use dom::bindings::inheritance::ElementTypeId; use dom::bindings::inheritance::HTMLElementTypeId; use dom::bindings::inheritance::NodeTypeId; +use dom::bindings::inheritance::SVGElementTypeId; +use dom::bindings::inheritance::SVGGraphicsElementTypeId; use dom::bindings::str::DOMString; use dom::document::Document; use dom::element::{AttributeMutation, Element}; @@ -47,6 +49,7 @@ use dom::htmltemplateelement::HTMLTemplateElement; use dom::htmltextareaelement::HTMLTextAreaElement; use dom::htmltitleelement::HTMLTitleElement; use dom::node::{ChildrenMutation, CloneChildrenFlag, Node, UnbindContext}; +use dom::svgsvgelement::SVGSVGElement; use string_cache::Atom; use style::attr::AttrValue; @@ -231,6 +234,11 @@ pub fn vtable_for(node: &Node) -> &VirtualMethods { NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTitleElement)) => { node.downcast::<HTMLTitleElement>().unwrap() as &VirtualMethods } + NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement( + SVGGraphicsElementTypeId::SVGSVGElement + ))) => { + node.downcast::<SVGSVGElement>().unwrap() as &VirtualMethods + } NodeTypeId::Element(ElementTypeId::Element) => { node.downcast::<Element>().unwrap() as &VirtualMethods } diff --git a/components/script/dom/webidls/SVGElement.webidl b/components/script/dom/webidls/SVGElement.webidl new file mode 100644 index 00000000000..02f673a420e --- /dev/null +++ b/components/script/dom/webidls/SVGElement.webidl @@ -0,0 +1,22 @@ +/* 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/. */ + +// https://svgwg.org/svg2-draft/types.html#InterfaceSVGElement +[Pref="dom.svg.enabled"] +interface SVGElement : Element { + + //[SameObject] readonly attribute SVGAnimatedString className; + + //[SameObject] readonly attribute DOMStringMap dataset; + + //readonly attribute SVGSVGElement? ownerSVGElement; + //readonly attribute SVGElement? viewportElement; + + //attribute long tabIndex; + //void focus(); + //void blur(); +}; + +//SVGElement implements GlobalEventHandlers; +//SVGElement implements SVGElementInstance; diff --git a/components/script/dom/webidls/SVGGraphicsElement.webidl b/components/script/dom/webidls/SVGGraphicsElement.webidl new file mode 100644 index 00000000000..d8f90e639ea --- /dev/null +++ b/components/script/dom/webidls/SVGGraphicsElement.webidl @@ -0,0 +1,22 @@ +/* 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/. */ + +// https://svgwg.org/svg2-draft/types.html#InterfaceSVGGraphicsElement +[Pref="dom.svg.enabled"] +//dictionary SVGBoundingBoxOptions { +// boolean fill = true; +// boolean stroke = false; +// boolean markers = false; +// boolean clipped = false; +//}; + +interface SVGGraphicsElement : SVGElement { + //[SameObject] readonly attribute SVGAnimatedTransformList transform; + + //DOMRect getBBox(optional SVGBoundingBoxOptions options); + //DOMMatrix? getCTM(); + //DOMMatrix? getScreenCTM(); +}; + +//SVGGraphicsElement implements SVGTests; diff --git a/components/script/dom/webidls/SVGSVGElement.webidl b/components/script/dom/webidls/SVGSVGElement.webidl new file mode 100644 index 00000000000..bed2c03a74b --- /dev/null +++ b/components/script/dom/webidls/SVGSVGElement.webidl @@ -0,0 +1,45 @@ +/* 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/. */ + +// https://svgwg.org/svg2-draft/struct.html#InterfaceSVGSVGElement +[Pref="dom.svg.enabled"] +interface SVGSVGElement : SVGGraphicsElement { + + //[SameObject] readonly attribute SVGAnimatedLength x; + //[SameObject] readonly attribute SVGAnimatedLength y; + //[SameObject] readonly attribute SVGAnimatedLength width; + //[SameObject] readonly attribute SVGAnimatedLength height; + + //attribute float currentScale; + //[SameObject] readonly attribute DOMPointReadOnly currentTranslate; + + //NodeList getIntersectionList(DOMRectReadOnly rect, SVGElement? referenceElement); + //NodeList getEnclosureList(DOMRectReadOnly rect, SVGElement? referenceElement); + //boolean checkIntersection(SVGElement element, DOMRectReadOnly rect); + //boolean checkEnclosure(SVGElement element, DOMRectReadOnly rect); + + //void deselectAll(); + + //SVGNumber createSVGNumber(); + //SVGLength createSVGLength(); + //SVGAngle createSVGAngle(); + //DOMPoint createSVGPoint(); + //DOMMatrix createSVGMatrix(); + //DOMRect createSVGRect(); + //SVGTransform createSVGTransform(); + //SVGTransform createSVGTransformFromMatrix(DOMMatrixReadOnly matrix); + + //Element getElementById(DOMString elementId); + + // Deprecated methods that have no effect when called, + // but which are kept for compatibility reasons. + //unsigned long suspendRedraw(unsigned long maxWaitMilliseconds); + //void unsuspendRedraw(unsigned long suspendHandleID); + //void unsuspendRedrawAll(); + //void forceRedraw(); +}; + +//SVGSVGElement implements SVGFitToViewBox; +//SVGSVGElement implements SVGZoomAndPan; +//SVGSVGElement implements WindowEventHandlers; |