mirror of
https://github.com/servo/servo.git
synced 2025-06-08 08:33:26 +00:00
Auto merge of #13589 - splav:SVGElement#12974, r=pcwalton,Ms2ger
Support SVG element <!-- Please describe your changes on the following line: --> minimal SVG element implementation --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #12974 (github issue number if applicable). <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13589) <!-- Reviewable:end -->
This commit is contained in:
commit
dad3b4785a
22 changed files with 533 additions and 19 deletions
|
@ -678,6 +678,7 @@ impl BlockFlow {
|
||||||
fn is_replaced_content(&self) -> bool {
|
fn is_replaced_content(&self) -> bool {
|
||||||
match self.fragment.specific {
|
match self.fragment.specific {
|
||||||
SpecificFragmentInfo::ScannedText(_) |
|
SpecificFragmentInfo::ScannedText(_) |
|
||||||
|
SpecificFragmentInfo::Svg(_) |
|
||||||
SpecificFragmentInfo::Image(_) |
|
SpecificFragmentInfo::Image(_) |
|
||||||
SpecificFragmentInfo::Canvas(_) |
|
SpecificFragmentInfo::Canvas(_) |
|
||||||
SpecificFragmentInfo::InlineBlock(_) => true,
|
SpecificFragmentInfo::InlineBlock(_) => true,
|
||||||
|
|
|
@ -22,7 +22,7 @@ use floats::FloatKind;
|
||||||
use flow::{self, AbsoluteDescendants, IS_ABSOLUTELY_POSITIONED, ImmutableFlowUtils};
|
use flow::{self, AbsoluteDescendants, IS_ABSOLUTELY_POSITIONED, ImmutableFlowUtils};
|
||||||
use flow::{CAN_BE_FRAGMENTED, MutableFlowUtils, MutableOwnedFlowUtils};
|
use flow::{CAN_BE_FRAGMENTED, MutableFlowUtils, MutableOwnedFlowUtils};
|
||||||
use flow_ref::{self, FlowRef};
|
use flow_ref::{self, FlowRef};
|
||||||
use fragment::{CanvasFragmentInfo, ImageFragmentInfo, InlineAbsoluteFragmentInfo};
|
use fragment::{CanvasFragmentInfo, ImageFragmentInfo, InlineAbsoluteFragmentInfo, SvgFragmentInfo};
|
||||||
use fragment::{Fragment, GeneratedContentInfo, IframeFragmentInfo};
|
use fragment::{Fragment, GeneratedContentInfo, IframeFragmentInfo};
|
||||||
use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo};
|
use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo};
|
||||||
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
|
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
|
||||||
|
@ -335,6 +335,10 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
|
||||||
let data = node.canvas_data().unwrap();
|
let data = node.canvas_data().unwrap();
|
||||||
SpecificFragmentInfo::Canvas(box CanvasFragmentInfo::new(node, data, self.style_context()))
|
SpecificFragmentInfo::Canvas(box CanvasFragmentInfo::new(node, data, self.style_context()))
|
||||||
}
|
}
|
||||||
|
Some(LayoutNodeType::Element(LayoutElementType::SVGSVGElement)) => {
|
||||||
|
let data = node.svg_data().unwrap();
|
||||||
|
SpecificFragmentInfo::Svg(box SvgFragmentInfo::new(node, data, self.style_context()))
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// This includes pseudo-elements.
|
// This includes pseudo-elements.
|
||||||
SpecificFragmentInfo::Generic
|
SpecificFragmentInfo::Generic
|
||||||
|
@ -1701,7 +1705,8 @@ impl<ConcreteThreadSafeLayoutNode> NodeUtils for ConcreteThreadSafeLayoutNode
|
||||||
Some(LayoutNodeType::Document) |
|
Some(LayoutNodeType::Document) |
|
||||||
Some(LayoutNodeType::Element(LayoutElementType::HTMLImageElement)) |
|
Some(LayoutNodeType::Element(LayoutElementType::HTMLImageElement)) |
|
||||||
Some(LayoutNodeType::Element(LayoutElementType::HTMLIFrameElement)) |
|
Some(LayoutNodeType::Element(LayoutElementType::HTMLIFrameElement)) |
|
||||||
Some(LayoutNodeType::Element(LayoutElementType::HTMLCanvasElement)) => true,
|
Some(LayoutNodeType::Element(LayoutElementType::HTMLCanvasElement)) |
|
||||||
|
Some(LayoutNodeType::Element(LayoutElementType::SVGSVGElement)) => true,
|
||||||
Some(LayoutNodeType::Element(LayoutElementType::HTMLObjectElement)) => self.has_object_data(),
|
Some(LayoutNodeType::Element(LayoutElementType::HTMLObjectElement)) => self.has_object_data(),
|
||||||
Some(LayoutNodeType::Element(_)) => false,
|
Some(LayoutNodeType::Element(_)) => false,
|
||||||
None => self.get_pseudo_element_type().is_replaced_content(),
|
None => self.get_pseudo_element_type().is_replaced_content(),
|
||||||
|
|
|
@ -1239,7 +1239,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
SpecificFragmentInfo::MulticolColumn |
|
SpecificFragmentInfo::MulticolColumn |
|
||||||
SpecificFragmentInfo::InlineBlock(_) |
|
SpecificFragmentInfo::InlineBlock(_) |
|
||||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
||||||
SpecificFragmentInfo::InlineAbsolute(_) => {
|
SpecificFragmentInfo::InlineAbsolute(_) |
|
||||||
|
SpecificFragmentInfo::Svg(_) => {
|
||||||
if opts::get().show_debug_fragment_borders {
|
if opts::get().show_debug_fragment_borders {
|
||||||
self.build_debug_borders_around_fragment(state,
|
self.build_debug_borders_around_fragment(state,
|
||||||
stacking_relative_border_box,
|
stacking_relative_border_box,
|
||||||
|
|
|
@ -30,6 +30,7 @@ use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder};
|
||||||
use range::*;
|
use range::*;
|
||||||
use rustc_serialize::{Encodable, Encoder};
|
use rustc_serialize::{Encodable, Encoder};
|
||||||
use script_layout_interface::HTMLCanvasData;
|
use script_layout_interface::HTMLCanvasData;
|
||||||
|
use script_layout_interface::SVGSVGData;
|
||||||
use script_layout_interface::restyle_damage::{RECONSTRUCT_FLOW, RestyleDamage};
|
use script_layout_interface::restyle_damage::{RECONSTRUCT_FLOW, RestyleDamage};
|
||||||
use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode};
|
use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode};
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
@ -155,6 +156,7 @@ pub enum SpecificFragmentInfo {
|
||||||
Iframe(IframeFragmentInfo),
|
Iframe(IframeFragmentInfo),
|
||||||
Image(Box<ImageFragmentInfo>),
|
Image(Box<ImageFragmentInfo>),
|
||||||
Canvas(Box<CanvasFragmentInfo>),
|
Canvas(Box<CanvasFragmentInfo>),
|
||||||
|
Svg(Box<SvgFragmentInfo>),
|
||||||
|
|
||||||
/// A hypothetical box (see CSS 2.1 § 10.3.7) for an absolutely-positioned block that was
|
/// A hypothetical box (see CSS 2.1 § 10.3.7) for an absolutely-positioned block that was
|
||||||
/// declared with `display: inline;`.
|
/// declared with `display: inline;`.
|
||||||
|
@ -186,6 +188,7 @@ impl SpecificFragmentInfo {
|
||||||
SpecificFragmentInfo::Iframe(_) |
|
SpecificFragmentInfo::Iframe(_) |
|
||||||
SpecificFragmentInfo::Image(_) |
|
SpecificFragmentInfo::Image(_) |
|
||||||
SpecificFragmentInfo::ScannedText(_) |
|
SpecificFragmentInfo::ScannedText(_) |
|
||||||
|
SpecificFragmentInfo::Svg(_) |
|
||||||
SpecificFragmentInfo::Table |
|
SpecificFragmentInfo::Table |
|
||||||
SpecificFragmentInfo::TableCell |
|
SpecificFragmentInfo::TableCell |
|
||||||
SpecificFragmentInfo::TableColumn(_) |
|
SpecificFragmentInfo::TableColumn(_) |
|
||||||
|
@ -216,6 +219,7 @@ impl SpecificFragmentInfo {
|
||||||
}
|
}
|
||||||
SpecificFragmentInfo::InlineBlock(_) => "SpecificFragmentInfo::InlineBlock",
|
SpecificFragmentInfo::InlineBlock(_) => "SpecificFragmentInfo::InlineBlock",
|
||||||
SpecificFragmentInfo::ScannedText(_) => "SpecificFragmentInfo::ScannedText",
|
SpecificFragmentInfo::ScannedText(_) => "SpecificFragmentInfo::ScannedText",
|
||||||
|
SpecificFragmentInfo::Svg(_) => "SpecificFragmentInfo::Svg",
|
||||||
SpecificFragmentInfo::Table => "SpecificFragmentInfo::Table",
|
SpecificFragmentInfo::Table => "SpecificFragmentInfo::Table",
|
||||||
SpecificFragmentInfo::TableCell => "SpecificFragmentInfo::TableCell",
|
SpecificFragmentInfo::TableCell => "SpecificFragmentInfo::TableCell",
|
||||||
SpecificFragmentInfo::TableColumn(_) => "SpecificFragmentInfo::TableColumn",
|
SpecificFragmentInfo::TableColumn(_) => "SpecificFragmentInfo::TableColumn",
|
||||||
|
@ -356,6 +360,44 @@ impl CanvasFragmentInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct SvgFragmentInfo {
|
||||||
|
pub replaced_image_fragment_info: ReplacedImageFragmentInfo,
|
||||||
|
pub dom_width: Au,
|
||||||
|
pub dom_height: Au,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SvgFragmentInfo {
|
||||||
|
pub fn new<N: ThreadSafeLayoutNode>(node: &N,
|
||||||
|
data: SVGSVGData,
|
||||||
|
ctx: &SharedStyleContext)
|
||||||
|
-> SvgFragmentInfo {
|
||||||
|
SvgFragmentInfo {
|
||||||
|
replaced_image_fragment_info: ReplacedImageFragmentInfo::new(node, ctx),
|
||||||
|
dom_width: Au::from_px(data.width as i32),
|
||||||
|
dom_height: Au::from_px(data.height as i32),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the original inline-size of the SVG element.
|
||||||
|
pub fn svg_inline_size(&self) -> Au {
|
||||||
|
if self.replaced_image_fragment_info.writing_mode_is_vertical {
|
||||||
|
self.dom_height
|
||||||
|
} else {
|
||||||
|
self.dom_width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the original block-size of the SVG element.
|
||||||
|
pub fn svg_block_size(&self) -> Au {
|
||||||
|
if self.replaced_image_fragment_info.writing_mode_is_vertical {
|
||||||
|
self.dom_width
|
||||||
|
} else {
|
||||||
|
self.dom_height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// A fragment that represents a replaced content image and its accompanying borders, shadows, etc.
|
/// A fragment that represents a replaced content image and its accompanying borders, shadows, etc.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -1007,7 +1049,8 @@ impl Fragment {
|
||||||
SpecificFragmentInfo::Iframe(_) |
|
SpecificFragmentInfo::Iframe(_) |
|
||||||
SpecificFragmentInfo::Image(_) |
|
SpecificFragmentInfo::Image(_) |
|
||||||
SpecificFragmentInfo::InlineAbsolute(_) |
|
SpecificFragmentInfo::InlineAbsolute(_) |
|
||||||
SpecificFragmentInfo::Multicol => {
|
SpecificFragmentInfo::Multicol |
|
||||||
|
SpecificFragmentInfo::Svg(_) => {
|
||||||
QuantitiesIncludedInIntrinsicInlineSizes::all()
|
QuantitiesIncludedInIntrinsicInlineSizes::all()
|
||||||
}
|
}
|
||||||
SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell => {
|
SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell => {
|
||||||
|
@ -1509,6 +1552,26 @@ impl Fragment {
|
||||||
preferred_inline_size: canvas_inline_size,
|
preferred_inline_size: canvas_inline_size,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
SpecificFragmentInfo::Svg(ref mut svg_fragment_info) => {
|
||||||
|
let mut svg_inline_size = match self.style.content_inline_size() {
|
||||||
|
LengthOrPercentageOrAuto::Auto |
|
||||||
|
LengthOrPercentageOrAuto::Percentage(_) => {
|
||||||
|
svg_fragment_info.svg_inline_size()
|
||||||
|
}
|
||||||
|
LengthOrPercentageOrAuto::Length(length) => length,
|
||||||
|
LengthOrPercentageOrAuto::Calc(calc) => calc.length(),
|
||||||
|
};
|
||||||
|
|
||||||
|
svg_inline_size = max(model::specified(self.style.min_inline_size(), Au(0)), svg_inline_size);
|
||||||
|
if let Some(max) = model::specified_or_none(self.style.max_inline_size(), Au(0)) {
|
||||||
|
svg_inline_size = min(svg_inline_size, max)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.union_block(&IntrinsicISizes {
|
||||||
|
minimum_inline_size: svg_inline_size,
|
||||||
|
preferred_inline_size: svg_inline_size,
|
||||||
|
});
|
||||||
|
}
|
||||||
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
|
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
|
||||||
let range = &text_fragment_info.range;
|
let range = &text_fragment_info.range;
|
||||||
|
|
||||||
|
@ -1596,6 +1659,9 @@ impl Fragment {
|
||||||
SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => {
|
SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => {
|
||||||
canvas_fragment_info.replaced_image_fragment_info.computed_inline_size()
|
canvas_fragment_info.replaced_image_fragment_info.computed_inline_size()
|
||||||
}
|
}
|
||||||
|
SpecificFragmentInfo::Svg(ref svg_fragment_info) => {
|
||||||
|
svg_fragment_info.replaced_image_fragment_info.computed_inline_size()
|
||||||
|
}
|
||||||
SpecificFragmentInfo::Image(ref image_fragment_info) => {
|
SpecificFragmentInfo::Image(ref image_fragment_info) => {
|
||||||
image_fragment_info.replaced_image_fragment_info.computed_inline_size()
|
image_fragment_info.replaced_image_fragment_info.computed_inline_size()
|
||||||
}
|
}
|
||||||
|
@ -1885,7 +1951,8 @@ impl Fragment {
|
||||||
SpecificFragmentInfo::InlineBlock(_) |
|
SpecificFragmentInfo::InlineBlock(_) |
|
||||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
||||||
SpecificFragmentInfo::InlineAbsolute(_) |
|
SpecificFragmentInfo::InlineAbsolute(_) |
|
||||||
SpecificFragmentInfo::ScannedText(_) => {}
|
SpecificFragmentInfo::ScannedText(_) |
|
||||||
|
SpecificFragmentInfo::Svg(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
let style = &*self.style;
|
let style = &*self.style;
|
||||||
|
@ -1945,6 +2012,18 @@ impl Fragment {
|
||||||
fragment_inline_size,
|
fragment_inline_size,
|
||||||
fragment_block_size);
|
fragment_block_size);
|
||||||
}
|
}
|
||||||
|
SpecificFragmentInfo::Svg(ref mut svg_fragment_info) => {
|
||||||
|
let fragment_inline_size = svg_fragment_info.svg_inline_size();
|
||||||
|
let fragment_block_size = svg_fragment_info.svg_block_size();
|
||||||
|
self.border_box.size.inline =
|
||||||
|
svg_fragment_info.replaced_image_fragment_info
|
||||||
|
.calculate_replaced_inline_size(style,
|
||||||
|
noncontent_inline_size,
|
||||||
|
container_inline_size,
|
||||||
|
container_block_size,
|
||||||
|
fragment_inline_size,
|
||||||
|
fragment_block_size);
|
||||||
|
}
|
||||||
SpecificFragmentInfo::Iframe(ref iframe_fragment_info) => {
|
SpecificFragmentInfo::Iframe(ref iframe_fragment_info) => {
|
||||||
self.border_box.size.inline =
|
self.border_box.size.inline =
|
||||||
iframe_fragment_info.calculate_replaced_inline_size(style,
|
iframe_fragment_info.calculate_replaced_inline_size(style,
|
||||||
|
@ -1981,7 +2060,8 @@ impl Fragment {
|
||||||
SpecificFragmentInfo::InlineBlock(_) |
|
SpecificFragmentInfo::InlineBlock(_) |
|
||||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
||||||
SpecificFragmentInfo::InlineAbsolute(_) |
|
SpecificFragmentInfo::InlineAbsolute(_) |
|
||||||
SpecificFragmentInfo::ScannedText(_) => {}
|
SpecificFragmentInfo::ScannedText(_) |
|
||||||
|
SpecificFragmentInfo::Svg(_) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let style = &*self.style;
|
let style = &*self.style;
|
||||||
|
@ -2010,6 +2090,17 @@ impl Fragment {
|
||||||
fragment_inline_size,
|
fragment_inline_size,
|
||||||
fragment_block_size);
|
fragment_block_size);
|
||||||
}
|
}
|
||||||
|
SpecificFragmentInfo::Svg(ref mut svg_fragment_info) => {
|
||||||
|
let fragment_inline_size = svg_fragment_info.svg_inline_size();
|
||||||
|
let fragment_block_size = svg_fragment_info.svg_block_size();
|
||||||
|
self.border_box.size.block =
|
||||||
|
svg_fragment_info.replaced_image_fragment_info
|
||||||
|
.calculate_replaced_block_size(style,
|
||||||
|
noncontent_block_size,
|
||||||
|
containing_block_block_size,
|
||||||
|
fragment_inline_size,
|
||||||
|
fragment_block_size);
|
||||||
|
}
|
||||||
SpecificFragmentInfo::ScannedText(ref info) => {
|
SpecificFragmentInfo::ScannedText(ref info) => {
|
||||||
// Scanned text fragments' content block-sizes are calculated by the text run
|
// Scanned text fragments' content block-sizes are calculated by the text run
|
||||||
// scanner during flow construction.
|
// scanner during flow construction.
|
||||||
|
@ -2065,6 +2156,16 @@ impl Fragment {
|
||||||
ascent: computed_block_size + self.border_padding.block_start,
|
ascent: computed_block_size + self.border_padding.block_start,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SpecificFragmentInfo::Svg(ref svg_fragment_info) => {
|
||||||
|
let computed_block_size = svg_fragment_info.replaced_image_fragment_info
|
||||||
|
.computed_block_size();
|
||||||
|
InlineMetrics {
|
||||||
|
block_size_above_baseline: computed_block_size +
|
||||||
|
self.border_padding.block_start,
|
||||||
|
depth_below_baseline: self.border_padding.block_end,
|
||||||
|
ascent: computed_block_size + self.border_padding.block_start,
|
||||||
|
}
|
||||||
|
}
|
||||||
SpecificFragmentInfo::ScannedText(ref info) => {
|
SpecificFragmentInfo::ScannedText(ref info) => {
|
||||||
// Fragments with no glyphs don't contribute any inline metrics.
|
// Fragments with no glyphs don't contribute any inline metrics.
|
||||||
// TODO: Filter out these fragments during flow construction?
|
// TODO: Filter out these fragments during flow construction?
|
||||||
|
@ -2213,6 +2314,7 @@ impl Fragment {
|
||||||
SpecificFragmentInfo::Iframe(_) |
|
SpecificFragmentInfo::Iframe(_) |
|
||||||
SpecificFragmentInfo::Image(_) |
|
SpecificFragmentInfo::Image(_) |
|
||||||
SpecificFragmentInfo::ScannedText(_) |
|
SpecificFragmentInfo::ScannedText(_) |
|
||||||
|
SpecificFragmentInfo::Svg(_) |
|
||||||
SpecificFragmentInfo::Table |
|
SpecificFragmentInfo::Table |
|
||||||
SpecificFragmentInfo::TableCell |
|
SpecificFragmentInfo::TableCell |
|
||||||
SpecificFragmentInfo::TableColumn(_) |
|
SpecificFragmentInfo::TableColumn(_) |
|
||||||
|
@ -2699,6 +2801,7 @@ impl Fragment {
|
||||||
SpecificFragmentInfo::Iframe(_) |
|
SpecificFragmentInfo::Iframe(_) |
|
||||||
SpecificFragmentInfo::Image(_) |
|
SpecificFragmentInfo::Image(_) |
|
||||||
SpecificFragmentInfo::ScannedText(_) |
|
SpecificFragmentInfo::ScannedText(_) |
|
||||||
|
SpecificFragmentInfo::Svg(_) |
|
||||||
SpecificFragmentInfo::UnscannedText(_) => true
|
SpecificFragmentInfo::UnscannedText(_) => true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,20 +76,43 @@ use dom::htmltrackelement::HTMLTrackElement;
|
||||||
use dom::htmlulistelement::HTMLUListElement;
|
use dom::htmlulistelement::HTMLUListElement;
|
||||||
use dom::htmlunknownelement::HTMLUnknownElement;
|
use dom::htmlunknownelement::HTMLUnknownElement;
|
||||||
use dom::htmlvideoelement::HTMLVideoElement;
|
use dom::htmlvideoelement::HTMLVideoElement;
|
||||||
|
use dom::svgsvgelement::SVGSVGElement;
|
||||||
use string_cache::{Atom, QualName};
|
use string_cache::{Atom, QualName};
|
||||||
|
use util::prefs::PREFS;
|
||||||
|
|
||||||
pub fn create_element(name: QualName,
|
fn create_svg_element(name: QualName,
|
||||||
prefix: Option<Atom>,
|
prefix: Option<DOMString>,
|
||||||
|
document: &Document)
|
||||||
|
-> Root<Element> {
|
||||||
|
assert!(name.ns == ns!(svg));
|
||||||
|
|
||||||
|
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 !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,
|
document: &Document,
|
||||||
creator: ElementCreator)
|
creator: ElementCreator)
|
||||||
-> Root<Element> {
|
-> Root<Element> {
|
||||||
// FIXME(ajeffrey): Convert directly from Atom to DOMString.
|
assert!(name.ns == ns!(html));
|
||||||
|
|
||||||
let prefix = prefix.map(|p| DOMString::from(&*p));
|
|
||||||
|
|
||||||
if name.ns != ns!(html) {
|
|
||||||
return Element::new(name.local, name.ns, prefix, document);
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! make(
|
macro_rules! make(
|
||||||
($ctor:ident) => ({
|
($ctor:ident) => ({
|
||||||
|
@ -249,3 +272,19 @@ pub fn create_element(name: QualName,
|
||||||
_ => make!(HTMLUnknownElement),
|
_ => 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -392,6 +392,9 @@ pub mod storage;
|
||||||
pub mod storageevent;
|
pub mod storageevent;
|
||||||
pub mod stylesheet;
|
pub mod stylesheet;
|
||||||
pub mod stylesheetlist;
|
pub mod stylesheetlist;
|
||||||
|
pub mod svgelement;
|
||||||
|
pub mod svggraphicselement;
|
||||||
|
pub mod svgsvgelement;
|
||||||
pub mod testbinding;
|
pub mod testbinding;
|
||||||
pub mod testbindingiterable;
|
pub mod testbindingiterable;
|
||||||
pub mod testbindingpairiterable;
|
pub mod testbindingpairiterable;
|
||||||
|
|
|
@ -22,6 +22,7 @@ use dom::bindings::conversions::{self, DerivedFrom};
|
||||||
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
use dom::bindings::error::{Error, ErrorResult, Fallible};
|
||||||
use dom::bindings::inheritance::{Castable, CharacterDataTypeId, ElementTypeId};
|
use dom::bindings::inheritance::{Castable, CharacterDataTypeId, ElementTypeId};
|
||||||
use dom::bindings::inheritance::{EventTargetTypeId, HTMLElementTypeId, NodeTypeId};
|
use dom::bindings::inheritance::{EventTargetTypeId, HTMLElementTypeId, NodeTypeId};
|
||||||
|
use dom::bindings::inheritance::{SVGElementTypeId, SVGGraphicsElementTypeId};
|
||||||
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
|
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap};
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::js::RootedReference;
|
use dom::bindings::js::RootedReference;
|
||||||
|
@ -36,7 +37,7 @@ use dom::element::{Element, ElementCreator};
|
||||||
use dom::eventtarget::EventTarget;
|
use dom::eventtarget::EventTarget;
|
||||||
use dom::globalscope::GlobalScope;
|
use dom::globalscope::GlobalScope;
|
||||||
use dom::htmlbodyelement::HTMLBodyElement;
|
use dom::htmlbodyelement::HTMLBodyElement;
|
||||||
use dom::htmlcanvaselement::LayoutHTMLCanvasElementHelpers;
|
use dom::htmlcanvaselement::{HTMLCanvasElement, LayoutHTMLCanvasElementHelpers};
|
||||||
use dom::htmlcollection::HTMLCollection;
|
use dom::htmlcollection::HTMLCollection;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementLayoutMethods};
|
use dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementLayoutMethods};
|
||||||
|
@ -46,6 +47,7 @@ use dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHel
|
||||||
use dom::nodelist::NodeList;
|
use dom::nodelist::NodeList;
|
||||||
use dom::processinginstruction::ProcessingInstruction;
|
use dom::processinginstruction::ProcessingInstruction;
|
||||||
use dom::range::WeakRangeVec;
|
use dom::range::WeakRangeVec;
|
||||||
|
use dom::svgsvgelement::{SVGSVGElement, LayoutSVGSVGElementHelpers};
|
||||||
use dom::text::Text;
|
use dom::text::Text;
|
||||||
use dom::virtualmethods::{VirtualMethods, vtable_for};
|
use dom::virtualmethods::{VirtualMethods, vtable_for};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
|
@ -59,7 +61,7 @@ use libc::{self, c_void, uintptr_t};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use parse::html::parse_html_fragment;
|
use parse::html::parse_html_fragment;
|
||||||
use ref_slice::ref_slice;
|
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::{LayoutElementType, LayoutNodeType, TrustedNodeAddress};
|
||||||
use script_layout_interface::message::Msg;
|
use script_layout_interface::message::Msg;
|
||||||
use script_traits::UntrustedNodeAddress;
|
use script_traits::UntrustedNodeAddress;
|
||||||
|
@ -955,6 +957,7 @@ pub trait LayoutNodeHelpers {
|
||||||
fn selection(&self) -> Option<Range<usize>>;
|
fn selection(&self) -> Option<Range<usize>>;
|
||||||
fn image_url(&self) -> Option<Url>;
|
fn image_url(&self) -> Option<Url>;
|
||||||
fn canvas_data(&self) -> Option<HTMLCanvasData>;
|
fn canvas_data(&self) -> Option<HTMLCanvasData>;
|
||||||
|
fn svg_data(&self) -> Option<SVGSVGData>;
|
||||||
fn iframe_pipeline_id(&self) -> PipelineId;
|
fn iframe_pipeline_id(&self) -> PipelineId;
|
||||||
fn opaque(&self) -> OpaqueNode;
|
fn opaque(&self) -> OpaqueNode;
|
||||||
}
|
}
|
||||||
|
@ -1088,10 +1091,15 @@ impl LayoutNodeHelpers for LayoutJS<Node> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn canvas_data(&self) -> Option<HTMLCanvasData> {
|
fn canvas_data(&self) -> Option<HTMLCanvasData> {
|
||||||
self.downcast()
|
self.downcast::<HTMLCanvasElement>()
|
||||||
.map(|canvas| canvas.data())
|
.map(|canvas| canvas.data())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn svg_data(&self) -> Option<SVGSVGData> {
|
||||||
|
self.downcast::<SVGSVGElement>()
|
||||||
|
.map(|svg| svg.data())
|
||||||
|
}
|
||||||
|
|
||||||
fn iframe_pipeline_id(&self) -> PipelineId {
|
fn iframe_pipeline_id(&self) -> PipelineId {
|
||||||
let iframe_element = self.downcast::<HTMLIFrameElement>()
|
let iframe_element = self.downcast::<HTMLIFrameElement>()
|
||||||
.expect("not an iframe element!");
|
.expect("not an iframe element!");
|
||||||
|
@ -2689,6 +2697,8 @@ impl Into<LayoutElementType> for ElementTypeId {
|
||||||
LayoutElementType::HTMLTableSectionElement,
|
LayoutElementType::HTMLTableSectionElement,
|
||||||
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement) =>
|
ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement) =>
|
||||||
LayoutElementType::HTMLTextAreaElement,
|
LayoutElementType::HTMLTextAreaElement,
|
||||||
|
ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(SVGGraphicsElementTypeId::SVGSVGElement)) =>
|
||||||
|
LayoutElementType::SVGSVGElement,
|
||||||
_ => LayoutElementType::Element,
|
_ => LayoutElementType::Element,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
48
components/script/dom/svgelement.rs
Normal file
48
components/script/dom/svgelement.rs
Normal file
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
48
components/script/dom/svggraphicselement.rs
Normal file
48
components/script/dom/svggraphicselement.rs
Normal file
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
83
components/script/dom/svgsvgelement.rs
Normal file
83
components/script/dom/svgsvgelement.rs
Normal file
|
@ -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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::inheritance::ElementTypeId;
|
use dom::bindings::inheritance::ElementTypeId;
|
||||||
use dom::bindings::inheritance::HTMLElementTypeId;
|
use dom::bindings::inheritance::HTMLElementTypeId;
|
||||||
use dom::bindings::inheritance::NodeTypeId;
|
use dom::bindings::inheritance::NodeTypeId;
|
||||||
|
use dom::bindings::inheritance::SVGElementTypeId;
|
||||||
|
use dom::bindings::inheritance::SVGGraphicsElementTypeId;
|
||||||
use dom::bindings::str::DOMString;
|
use dom::bindings::str::DOMString;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeMutation, Element};
|
use dom::element::{AttributeMutation, Element};
|
||||||
|
@ -47,6 +49,7 @@ use dom::htmltemplateelement::HTMLTemplateElement;
|
||||||
use dom::htmltextareaelement::HTMLTextAreaElement;
|
use dom::htmltextareaelement::HTMLTextAreaElement;
|
||||||
use dom::htmltitleelement::HTMLTitleElement;
|
use dom::htmltitleelement::HTMLTitleElement;
|
||||||
use dom::node::{ChildrenMutation, CloneChildrenFlag, Node, UnbindContext};
|
use dom::node::{ChildrenMutation, CloneChildrenFlag, Node, UnbindContext};
|
||||||
|
use dom::svgsvgelement::SVGSVGElement;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use style::attr::AttrValue;
|
use style::attr::AttrValue;
|
||||||
|
|
||||||
|
@ -231,6 +234,11 @@ pub fn vtable_for(node: &Node) -> &VirtualMethods {
|
||||||
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTitleElement)) => {
|
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTitleElement)) => {
|
||||||
node.downcast::<HTMLTitleElement>().unwrap() as &VirtualMethods
|
node.downcast::<HTMLTitleElement>().unwrap() as &VirtualMethods
|
||||||
}
|
}
|
||||||
|
NodeTypeId::Element(ElementTypeId::SVGElement(SVGElementTypeId::SVGGraphicsElement(
|
||||||
|
SVGGraphicsElementTypeId::SVGSVGElement
|
||||||
|
))) => {
|
||||||
|
node.downcast::<SVGSVGElement>().unwrap() as &VirtualMethods
|
||||||
|
}
|
||||||
NodeTypeId::Element(ElementTypeId::Element) => {
|
NodeTypeId::Element(ElementTypeId::Element) => {
|
||||||
node.downcast::<Element>().unwrap() as &VirtualMethods
|
node.downcast::<Element>().unwrap() as &VirtualMethods
|
||||||
}
|
}
|
||||||
|
|
22
components/script/dom/webidls/SVGElement.webidl
Normal file
22
components/script/dom/webidls/SVGElement.webidl
Normal file
|
@ -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;
|
22
components/script/dom/webidls/SVGGraphicsElement.webidl
Normal file
22
components/script/dom/webidls/SVGGraphicsElement.webidl
Normal file
|
@ -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;
|
45
components/script/dom/webidls/SVGSVGElement.webidl
Normal file
45
components/script/dom/webidls/SVGSVGElement.webidl
Normal file
|
@ -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;
|
|
@ -43,7 +43,7 @@ use gfx_traits::ByteIndex;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use range::Range;
|
use range::Range;
|
||||||
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, TrustedNodeAddress};
|
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, TrustedNodeAddress};
|
||||||
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
|
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
|
||||||
use script_layout_interface::restyle_damage::RestyleDamage;
|
use script_layout_interface::restyle_damage::RestyleDamage;
|
||||||
use script_layout_interface::wrapper_traits::{DangerousThreadSafeLayoutNode, LayoutNode, PseudoElementType};
|
use script_layout_interface::wrapper_traits::{DangerousThreadSafeLayoutNode, LayoutNode, PseudoElementType};
|
||||||
|
@ -861,6 +861,11 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
|
||||||
this.canvas_data()
|
this.canvas_data()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn svg_data(&self) -> Option<SVGSVGData> {
|
||||||
|
let this = unsafe { self.get_jsmanaged() };
|
||||||
|
this.svg_data()
|
||||||
|
}
|
||||||
|
|
||||||
fn iframe_pipeline_id(&self) -> PipelineId {
|
fn iframe_pipeline_id(&self) -> PipelineId {
|
||||||
let this = unsafe { self.get_jsmanaged() };
|
let this = unsafe { self.get_jsmanaged() };
|
||||||
this.iframe_pipeline_id()
|
this.iframe_pipeline_id()
|
||||||
|
|
|
@ -95,6 +95,7 @@ pub enum LayoutElementType {
|
||||||
HTMLTableRowElement,
|
HTMLTableRowElement,
|
||||||
HTMLTableSectionElement,
|
HTMLTableSectionElement,
|
||||||
HTMLTextAreaElement,
|
HTMLTextAreaElement,
|
||||||
|
SVGSVGElement,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct HTMLCanvasData {
|
pub struct HTMLCanvasData {
|
||||||
|
@ -103,6 +104,11 @@ pub struct HTMLCanvasData {
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct SVGSVGData {
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
/// The address of a node known to be valid. These are sent from script to layout.
|
/// The address of a node known to be valid. These are sent from script to layout.
|
||||||
#[derive(Clone, PartialEq, Eq, Copy)]
|
#[derive(Clone, PartialEq, Eq, Copy)]
|
||||||
pub struct TrustedNodeAddress(pub *const c_void);
|
pub struct TrustedNodeAddress(pub *const c_void);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
use HTMLCanvasData;
|
use HTMLCanvasData;
|
||||||
use LayoutNodeType;
|
use LayoutNodeType;
|
||||||
use OpaqueStyleAndLayoutData;
|
use OpaqueStyleAndLayoutData;
|
||||||
|
use SVGSVGData;
|
||||||
use gfx_traits::{ByteIndex, LayerId, LayerType};
|
use gfx_traits::{ByteIndex, LayerId, LayerType};
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use range::Range;
|
use range::Range;
|
||||||
|
@ -362,6 +363,8 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + NodeInfo + PartialEq + Sized {
|
||||||
|
|
||||||
fn canvas_data(&self) -> Option<HTMLCanvasData>;
|
fn canvas_data(&self) -> Option<HTMLCanvasData>;
|
||||||
|
|
||||||
|
fn svg_data(&self) -> Option<SVGSVGData>;
|
||||||
|
|
||||||
/// If this node is an iframe element, returns its pipeline ID. If this node is
|
/// If this node is an iframe element, returns its pipeline ID. If this node is
|
||||||
/// not an iframe element, fails.
|
/// not an iframe element, fails.
|
||||||
fn iframe_pipeline_id(&self) -> PipelineId;
|
fn iframe_pipeline_id(&self) -> PipelineId;
|
||||||
|
|
|
@ -70,6 +70,7 @@ WEBIDL_STANDARDS = [
|
||||||
"//w3c.github.io",
|
"//w3c.github.io",
|
||||||
"//heycam.github.io/webidl",
|
"//heycam.github.io/webidl",
|
||||||
"//webbluetoothcg.github.io/web-bluetooth/",
|
"//webbluetoothcg.github.io/web-bluetooth/",
|
||||||
|
"//svgwg.org/svg2-draft",
|
||||||
# Not a URL
|
# Not a URL
|
||||||
"// This interface is entirely internal to Servo, and should not be" +
|
"// This interface is entirely internal to Servo, and should not be" +
|
||||||
" accessible to\n// web pages."
|
" accessible to\n// web pages."
|
||||||
|
|
|
@ -6294,6 +6294,18 @@
|
||||||
"url": "/_mozilla/mozilla/sslfail.html"
|
"url": "/_mozilla/mozilla/sslfail.html"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"mozilla/svg/svg.html": [
|
||||||
|
{
|
||||||
|
"path": "mozilla/svg/svg.html",
|
||||||
|
"references": [
|
||||||
|
[
|
||||||
|
"/_mozilla/mozilla/svg/svg_ref.html",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"url": "/_mozilla/mozilla/svg/svg.html"
|
||||||
|
}
|
||||||
|
],
|
||||||
"mozilla/table_valign_bottom.html": [
|
"mozilla/table_valign_bottom.html": [
|
||||||
{
|
{
|
||||||
"path": "mozilla/table_valign_bottom.html",
|
"path": "mozilla/table_valign_bottom.html",
|
||||||
|
@ -20040,6 +20052,18 @@
|
||||||
"url": "/_mozilla/mozilla/sslfail.html"
|
"url": "/_mozilla/mozilla/sslfail.html"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"mozilla/svg/svg.html": [
|
||||||
|
{
|
||||||
|
"path": "mozilla/svg/svg.html",
|
||||||
|
"references": [
|
||||||
|
[
|
||||||
|
"/_mozilla/mozilla/svg/svg_ref.html",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"url": "/_mozilla/mozilla/svg/svg.html"
|
||||||
|
}
|
||||||
|
],
|
||||||
"mozilla/table_valign_bottom.html": [
|
"mozilla/table_valign_bottom.html": [
|
||||||
{
|
{
|
||||||
"path": "mozilla/table_valign_bottom.html",
|
"path": "mozilla/table_valign_bottom.html",
|
||||||
|
|
3
tests/wpt/mozilla/meta/mozilla/svg/svg.html.ini
Normal file
3
tests/wpt/mozilla/meta/mozilla/svg/svg.html.ini
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[svg.html]
|
||||||
|
type: reftest
|
||||||
|
prefs: [dom.svg.enabled:true]
|
15
tests/wpt/mozilla/tests/mozilla/svg/svg.html
Normal file
15
tests/wpt/mozilla/tests/mozilla/svg/svg.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>SVG embedded inline</title>
|
||||||
|
<link rel="match" href="svg_ref.html">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
top<br>
|
||||||
|
a
|
||||||
|
<svg width="100px" height="100px">
|
||||||
|
</svg>
|
||||||
|
b<br>
|
||||||
|
bottom
|
||||||
|
</body>
|
||||||
|
</html>
|
19
tests/wpt/mozilla/tests/mozilla/svg/svg_ref.html
Normal file
19
tests/wpt/mozilla/tests/mozilla/svg/svg_ref.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>SVG embedded inline</title>
|
||||||
|
<style>
|
||||||
|
img {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
top<br>
|
||||||
|
a
|
||||||
|
<img>
|
||||||
|
b<br>
|
||||||
|
bottom
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue