mirror of
https://github.com/swc-project/swc.git
synced 2024-12-25 22:56:11 +03:00
feat(html/minifier): Improve minifier (#5227)
This commit is contained in:
parent
883a76a73a
commit
1da6016da7
@ -91,6 +91,7 @@ static EVENT_HANDLER_ATTRIBUTES: &[&str] = &[
|
||||
"ondrag",
|
||||
"ondragend",
|
||||
"ondragenter",
|
||||
"ondragexit",
|
||||
"ondragleave",
|
||||
"ondragover",
|
||||
"ondragstart",
|
||||
@ -167,6 +168,9 @@ static EVENT_HANDLER_ATTRIBUTES: &[&str] = &[
|
||||
"onvisibilitychange",
|
||||
"onshow",
|
||||
"onsort",
|
||||
"onbegin",
|
||||
"onend",
|
||||
"onrepeat",
|
||||
];
|
||||
|
||||
static ALLOW_TO_TRIM_GLOBAL_ATTRIBUTES: &[&str] = &["style", "tabindex", "itemid"];
|
||||
@ -226,7 +230,11 @@ static COMMA_SEPARATED_HTML_ATTRIBUTES: &[(&str, &str)] = &[
|
||||
("style", "media"),
|
||||
];
|
||||
|
||||
static COMMA_SEPARATED_SVG_ATTRIBUTES: &[(&str, &str)] = &[("style", "media")];
|
||||
static COMMA_SEPARATED_SVG_ATTRIBUTES: &[(&str, &str)] = &[
|
||||
("style", "media"),
|
||||
("polyline", "points"),
|
||||
("polygon", "points"),
|
||||
];
|
||||
|
||||
static SPACE_SEPARATED_GLOBAL_ATTRIBUTES: &[&str] = &[
|
||||
"class",
|
||||
@ -259,6 +267,64 @@ static SPACE_SEPARATED_HTML_ATTRIBUTES: &[(&str, &str)] = &[
|
||||
("form", "autocomplete"),
|
||||
];
|
||||
|
||||
static SPACE_SEPARATED_SVG_ATTRIBUTES: &[(&str, &str)] = &[
|
||||
("svg", "preserveAspectRatio"),
|
||||
("svg", "viewBox"),
|
||||
("symbol", "preserveAspectRatio"),
|
||||
("symbol", "viewBox"),
|
||||
("image", "preserveAspectRatio"),
|
||||
("feImage", "preserveAspectRatio"),
|
||||
("marker", "preserveAspectRatio"),
|
||||
("pattern", "preserveAspectRatio"),
|
||||
("pattern", "viewBox"),
|
||||
("pattern", "patternTransform"),
|
||||
("view", "preserveAspectRatio"),
|
||||
("view", "viewBox"),
|
||||
("path", "d"),
|
||||
// TODO improve me more
|
||||
("textPath", "path"),
|
||||
("animateMotion", "path"),
|
||||
("glyph", "d"),
|
||||
("missing-glyph", "d"),
|
||||
("feColorMatrix", "values"),
|
||||
("feConvolveMatrix", "kernelMatrix"),
|
||||
("text", "rotate"),
|
||||
("tspan", "rotate"),
|
||||
("feFuncA", "tableValues"),
|
||||
("feFuncB", "tableValues"),
|
||||
("feFuncG", "tableValues"),
|
||||
("feFuncR", "tableValues"),
|
||||
("linearGradient", "gradientTransform"),
|
||||
("radialGradient", "gradientTransform"),
|
||||
("font-face", "panose-1"),
|
||||
];
|
||||
|
||||
static SEMICOLON_SEPARATED_SVG_ATTRIBUTES: &[(&str, &str)] = &[
|
||||
("animate", "keyTimes"),
|
||||
("animate", "keySplines"),
|
||||
("animate", "values"),
|
||||
("animate", "begin"),
|
||||
("animate", "end"),
|
||||
("animateColor", "keyTimes"),
|
||||
("animateColor", "keySplines"),
|
||||
("animateColor", "values"),
|
||||
("animateColor", "begin"),
|
||||
("animateColor", "end"),
|
||||
("animateMotion", "keyTimes"),
|
||||
("animateMotion", "keySplines"),
|
||||
("animateMotion", "values"),
|
||||
("animateMotion", "values"),
|
||||
("animateMotion", "end"),
|
||||
("animateTransform", "keyTimes"),
|
||||
("animateTransform", "keySplines"),
|
||||
("animateTransform", "values"),
|
||||
("animateTransform", "begin"),
|
||||
("animateTransform", "end"),
|
||||
("discard", "begin"),
|
||||
("set", "begin"),
|
||||
("set", "end"),
|
||||
];
|
||||
|
||||
enum CssMinificationMode {
|
||||
Stylesheet,
|
||||
ListOfDeclarations,
|
||||
@ -410,6 +476,25 @@ impl Minifier<'_> {
|
||||
Namespace::HTML => {
|
||||
SPACE_SEPARATED_HTML_ATTRIBUTES.contains(&(&element.tag_name, attribute_name))
|
||||
}
|
||||
Namespace::SVG => {
|
||||
match attribute_name {
|
||||
"transform" | "stroke-dasharray" | "clip-path" | "requiredFeatures" => {
|
||||
return true
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
SPACE_SEPARATED_SVG_ATTRIBUTES.contains(&(&element.tag_name, attribute_name))
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_semicolon_separated_attribute(&self, element: &Element, attribute_name: &str) -> bool {
|
||||
match element.namespace {
|
||||
Namespace::SVG => {
|
||||
SEMICOLON_SEPARATED_SVG_ATTRIBUTES.contains(&(&element.tag_name, attribute_name))
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -446,6 +531,7 @@ impl Minifier<'_> {
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
Namespace::SVG => matches!(&*element.tag_name, "a" if attribute_name == "rel"),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -911,7 +997,6 @@ impl Minifier<'_> {
|
||||
| "textpath"
|
||||
| "tspan"
|
||||
| "use"
|
||||
| "symbol’"
|
||||
) =>
|
||||
{
|
||||
WhitespaceMinificationMode {
|
||||
@ -1954,30 +2039,32 @@ impl VisitMut for Minifier<'_> {
|
||||
if self.is_space_separated_attribute(current_element, &n.name) {
|
||||
value = value.split_whitespace().collect::<Vec<_>>().join(" ");
|
||||
} else if self.is_comma_separated_attribute(current_element, &n.name) {
|
||||
let is_sizes = matches!(&*n.name, "sizes" | "imagesizes");
|
||||
value = value
|
||||
.split(',')
|
||||
.map(|value| {
|
||||
if matches!(&*n.name, "sizes" | "imagesizes") {
|
||||
let trimmed = value.trim();
|
||||
|
||||
let mut new_values = vec![];
|
||||
|
||||
for value in value.trim().split(',') {
|
||||
if is_sizes {
|
||||
let trimmed = value.trim();
|
||||
|
||||
match self.minify_sizes(trimmed) {
|
||||
Some(minified) => {
|
||||
new_values.push(minified);
|
||||
match self.minify_sizes(trimmed) {
|
||||
Some(minified) => minified,
|
||||
_ => trimmed.to_string(),
|
||||
}
|
||||
_ => {
|
||||
new_values.push(trimmed.to_string());
|
||||
}
|
||||
};
|
||||
} else {
|
||||
new_values.push(value.trim().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
value = new_values.join(",");
|
||||
} else if matches!(&*n.name, "points") {
|
||||
self.collapse_whitespace(value.trim())
|
||||
} else {
|
||||
value.trim().to_string()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
} else if self.is_trimable_separated_attribute(current_element, &n.name) {
|
||||
value = value.trim().to_string();
|
||||
} else if self.is_semicolon_separated_attribute(current_element, &n.name) {
|
||||
value = value
|
||||
.split(';')
|
||||
.map(|value| self.collapse_whitespace(value.trim()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(";");
|
||||
} else if current_element.namespace == Namespace::HTML
|
||||
&& &n.name == "contenteditable"
|
||||
&& value == "true"
|
||||
|
@ -370,5 +370,404 @@ big
|
||||
<text y="40" xml:space="preserve" alignment-baseline="auto">Preserved spacing</text>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 220 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Simple rectangle -->
|
||||
<rect width="100" height="100" onclick="alert('test' + 'test');" />
|
||||
<rect width="100" height="100" onclick="javascript:alert('test' + 'test');" />
|
||||
|
||||
<!-- Rounded corner rectangle -->
|
||||
<rect x="120" width="100" height="100" rx="15" />
|
||||
</svg>
|
||||
|
||||
<svg>
|
||||
<a href=" test.html " ondragexit="alert( 'test' + 'test' )" rel="
|
||||
nofollow
|
||||
noindex
|
||||
">Test</a>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 100 100" width="160" height="60"
|
||||
preserveAspectRatio=" xMidYMid meet " x="0" y="30">
|
||||
<use href="#smiley" />
|
||||
</svg>
|
||||
|
||||
<svg viewBox="-10 -10 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- polygon is an closed shape -->
|
||||
<polygon stroke="black" fill="none"
|
||||
points="
|
||||
|
||||
50
|
||||
|
||||
,
|
||||
|
||||
0
|
||||
|
||||
21
|
||||
|
||||
,
|
||||
|
||||
90
|
||||
|
||||
98
|
||||
|
||||
,
|
||||
|
||||
35
|
||||
|
||||
2,
|
||||
|
||||
35
|
||||
|
||||
79,
|
||||
|
||||
90" />
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="60" cy="10" r="10">
|
||||
<animate attributeName=cx dur=4s repeatCount=indefinite values="
|
||||
60;
|
||||
110;
|
||||
60;
|
||||
10;
|
||||
60
|
||||
" keyTimes="
|
||||
0
|
||||
;
|
||||
0.25 ;
|
||||
0.5 ;
|
||||
0.75 ;
|
||||
1"/>
|
||||
<animate attributeName="cy" dur="4s" repeatCount="indefinite"
|
||||
values=" 10; 60; 110; 60; 10 " keyTimes="0; 0.25; 0.5; 0.75; 1"/>
|
||||
</circle>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="60" cy="10" r="10">
|
||||
<animate attributeName="cx" dur="4s" calcMode="spline" repeatCount="indefinite"
|
||||
values="60; 110; 60; 10; 60" keyTimes="0; 0.25; 0.5; 0.75; 1"
|
||||
keySplines="0.5 0 0.5 1; 0.5 0 0.5 1; 0.5 0 0.5 1; 0.5 0 0.5 1"/>
|
||||
<animate attributeName="cy" dur="4s" calcMode="spline" repeatCount="indefinite"
|
||||
values="10; 60; 110; 60; 10" keyTimes="0; 0.25; 0.5; 0.75; 1"
|
||||
keySplines="
|
||||
|
||||
0.5 0
|
||||
|
||||
0.5
|
||||
|
||||
1
|
||||
|
||||
; 0.5 0 0.5 1; 0.5 0 0.5 1; 0.5 0 0.5 1"
|
||||
/>
|
||||
</circle>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="
|
||||
-5
|
||||
-5
|
||||
10
|
||||
10
|
||||
" xmlns="http://www.w3.org/2000/svg">
|
||||
<!--
|
||||
The point of coordinate 0,0 is now in the center of the viewport,
|
||||
and 100% is still resolve to a width or height of 10 user units so
|
||||
the rectangle looks shifted to the bottom/right corner of the viewport
|
||||
-->
|
||||
<rect x="0" y="0" width="100%" height="100%"/>
|
||||
|
||||
<!--
|
||||
With the point of coordinate 0,0 in the center of the viewport the
|
||||
value 50% is resolve to 5 which means the center of the circle is
|
||||
in the bottom/right corner of the viewport.
|
||||
-->
|
||||
<circle cx="50%" cy="50%" r="4" fill="white"/>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Dashes and gaps of various sizes with an even number of values -->
|
||||
<line x1="0" y1="9" x2="30" y2="9" stroke="black"
|
||||
stroke-dasharray="
|
||||
|
||||
4
|
||||
|
||||
1
|
||||
|
||||
2
|
||||
|
||||
3
|
||||
|
||||
" />
|
||||
<rect x="11" y="1" width="8" height="8" stroke="green"
|
||||
clip-path="
|
||||
|
||||
circle()
|
||||
|
||||
|
||||
fill-box
|
||||
|
||||
" />
|
||||
</svg>
|
||||
|
||||
<svg id="svg_css_ex1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="none" stroke="red"
|
||||
d="M 10,30
|
||||
A 20,20 0,0,1 50,30
|
||||
A 20,20 0,0,1 90,30
|
||||
Q 90,60 50,90
|
||||
Q 10,60 10,30 z
|
||||
" />
|
||||
</svg>
|
||||
|
||||
<svg width="120" height="120" viewBox="0 0 120 120"
|
||||
xmlns="http://www.w3.org/2000/svg" version="1.1"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
<!-- animated rectangles -->
|
||||
<rect x="10" y="35" height="15" width="0">
|
||||
<animate attributeType="XML" attributeName="width" to="50"
|
||||
id="first"
|
||||
begin="
|
||||
0s;
|
||||
|
||||
third.end
|
||||
|
||||
"
|
||||
end="
|
||||
0s;
|
||||
|
||||
third.end
|
||||
|
||||
"
|
||||
dur="4s" />
|
||||
</rect>
|
||||
|
||||
<rect x="60" y="60" height="15" width="0">
|
||||
<animate attributeType="XML" attributeName="width" to="25"
|
||||
id="second" begin="first.end" dur="2s" />
|
||||
</rect>
|
||||
|
||||
<rect x="85" y="85" height="15" width="0">
|
||||
<animate attributeType="XML" attributeName="width" to="25"
|
||||
id="third" begin="second.end" dur="2s" />
|
||||
</rect>
|
||||
|
||||
<!-- grid -->
|
||||
<text x="10" y="20" text-anchor="middle">0s</text>
|
||||
<line x1="10" y1="25" x2="10" y2="105" stroke="grey" stroke-width=".5" />
|
||||
<text x="35" y="20" text-anchor="middle">2s</text>
|
||||
<line x1="35" y1="25" x2="35" y2="105" stroke="grey" stroke-width=".5" />
|
||||
<text x="60" y="20" text-anchor="middle">4s</text>
|
||||
<line x1="60" y1="25" x2="60" y2="105" stroke="grey" stroke-width=".5" />
|
||||
<text x="85" y="20" text-anchor="middle">6s</text>
|
||||
<line x1="85" y1="25" x2="85" y2="105" stroke="grey" stroke-width=".5" />
|
||||
<text x="110" y="20" text-anchor="middle">8s</text>
|
||||
<line x1="110" y1="25" x2="110" y2="105" stroke="grey" stroke-width=".5" />
|
||||
|
||||
<line x1="10" y1="30" x2="110" y2="30" stroke="grey" stroke-width=".5" />
|
||||
<line x1="10" y1="105" x2="110" y2="105" stroke="grey" stroke-width=".5" />
|
||||
</svg>
|
||||
|
||||
<svg>
|
||||
<filter id="colorMeTheSame">
|
||||
<feColorMatrix in="SourceGraphic"
|
||||
type="matrix"
|
||||
values="1 0 0 0 0
|
||||
0
|
||||
1 0 0 0
|
||||
|
||||
|
||||
0 0
|
||||
|
||||
1 0 0
|
||||
0 0 0
|
||||
1 0" />
|
||||
</filter>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 420 200" xmlns="http://www.w3.org/2000/svg">
|
||||
<filter id="convolveMatrix1" x="0" y="0" width="100%" height="100%">
|
||||
<feConvolveMatrix kernelMatrix="
|
||||
|
||||
1
|
||||
|
||||
1
|
||||
0 0 0
|
||||
|
||||
0 0 0
|
||||
|
||||
-1"/>
|
||||
</filter>
|
||||
<filter id="convolveMatrix2" x="0" y="0" width="100%" height="100%">
|
||||
<feConvolveMatrix kernelMatrix="-1 0 0 0 0 0 0 0 1"/>
|
||||
</filter>
|
||||
|
||||
<image xlink:href="//developer.mozilla.org/files/6457/mdn_logo_only_color.png" width="200" height="200"
|
||||
style="filter:url(#convolveMatrix1);"/>
|
||||
<image xlink:href="//developer.mozilla.org/files/6457/mdn_logo_only_color.png" width="200" height="200"
|
||||
style="filter:url(#convolveMatrix2); transform:translateX(220px);"/>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Apply a transform on the tile -->
|
||||
<pattern id="p1" width=".25" height=".25"
|
||||
patternTransform="rotate(20)
|
||||
skewX(30)
|
||||
scale(1 0.5)">
|
||||
<circle cx="10" cy="10" r="10" />
|
||||
</pattern>
|
||||
|
||||
<!-- Apply the transformed pattern tile -->
|
||||
<rect x="10" y="10" width="80" height="80"
|
||||
fill="url(#p1)" />
|
||||
</svg>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:lang="en"
|
||||
viewBox="0 0 200 500">
|
||||
<title>Scream—Comic Book text</title>
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: 'SequentialistBB';
|
||||
src: url('fonts/SequentialistBB.woff2') format('woff2'),
|
||||
url('fonts/SequentialistBB.woff') format('woff');
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
}
|
||||
text {
|
||||
font-family: SequentialistBB,
|
||||
Papyrus-condensed, Impact,
|
||||
sans-serif-condensed, sans-serif;
|
||||
font-stretch: condensed;
|
||||
writing-mode: tb; /* SVG 1 syntax */
|
||||
glyph-orientation-vertical: 0;
|
||||
writing-mode: vertical-rl; /* CSS3 syntax */
|
||||
text-orientation: upright;
|
||||
font-size: 28px;
|
||||
}
|
||||
tspan { font-size: 75%; }
|
||||
path {
|
||||
fill: #fff;
|
||||
stroke: #000;
|
||||
stroke-width: 2;
|
||||
}
|
||||
</style>
|
||||
<path d="M175,495 L140,465 C30,500 40,400 30,200
|
||||
S70,10 100,10 S170,0 170,200 S170,400 150,450 Z" />
|
||||
<text x="100" y="12"
|
||||
rotate="0 15 30 45 60 75 90 105 120 135 150 165 180
|
||||
195 210 225 240 255 270 285 300 315 330 345 360"
|
||||
textLength="450">
|
||||
AAAaaaa<tspan>aaaa<tspan>aaaa<tspan>aahhh!</tspan
|
||||
>!</tspan>!</tspan>!</text>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="MyPath" fill="none" stroke="silver"
|
||||
|
||||
d="
|
||||
M10,90 Q90,90 90,45
|
||||
|
||||
Q90,10 50,10 Q10,10 10,40 Q10,70
|
||||
|
||||
45,70
|
||||
|
||||
Q70,70
|
||||
75,50" />
|
||||
|
||||
<text>
|
||||
<textPath path="M10,90
|
||||
|
||||
Q90,90 90,45
|
||||
|
||||
Q90,10 50,10
|
||||
Q10,10 10,40 Q10,70 45,70 Q70,70
|
||||
|
||||
75,50">
|
||||
Quick brown fox jumps over the lazy dog.
|
||||
</textPath>
|
||||
</text>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 420 200" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="gradient" gradientUnits="userSpaceOnUse"
|
||||
x1="0" y1="0" x2="200" y2="0">
|
||||
<stop offset="0" stop-color="#ff0000" />
|
||||
<stop offset="0.5" stop-color="#00ff00" />
|
||||
<stop offset="1" stop-color="#0000ff" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<filter id="componentTransfer1" x="0" y="0" width="100%" height="100%">
|
||||
<feComponentTransfer>
|
||||
<feFuncR type="table" tableValues="
|
||||
|
||||
0
|
||||
|
||||
1
|
||||
|
||||
"/>
|
||||
<feFuncG type="table" tableValues=" 0 1 "/>
|
||||
<feFuncB type="table" tableValues="0 1"/>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
<filter id="componentTransfer2" x="0" y="0" width="100%" height="100%">
|
||||
<feComponentTransfer>
|
||||
<feFuncR type="table" tableValues="1 0"/>
|
||||
<feFuncG type="table" tableValues="1 0"/>
|
||||
<feFuncB type="table" tableValues="1 0"/>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
|
||||
<rect x="0" y="0" width="200" height="200" fill="url(#gradient)"
|
||||
style="filter: url(#componentTransfer1);" />
|
||||
<rect x="0" y="0" width="200" height="200" fill="url(#gradient)"
|
||||
style="filter: url(#componentTransfer2); transform: translateX(220px);" />
|
||||
</svg>
|
||||
|
||||
<svg width="450" height="1170" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<!-- Testing : http://www.w3.org/TR/SVG11/feature#SVG -->
|
||||
<rect class="ko" x="10" y="10" height="25" width="430" />
|
||||
<rect class="ok" x="10" y="10" height="25" width="430"
|
||||
requiredFeatures="
|
||||
http://www.w3.org/TR/SVG11/feature#SVG http://www.w3.org/TR/SVG11/feature#SVG
|
||||
" />
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 420 200" xmlns="http://www.w3.org/2000/svg">
|
||||
<radialGradient id="gradient1" gradientUnits="userSpaceOnUse"
|
||||
cx="100" cy="100" r="100" fx="100" fy="100">
|
||||
<stop offset="0%" stop-color="darkblue" />
|
||||
<stop offset="50%" stop-color="skyblue" />
|
||||
<stop offset="100%" stop-color="darkblue" />
|
||||
</radialGradient>
|
||||
<radialGradient id="gradient2" gradientUnits="userSpaceOnUse"
|
||||
cx="100" cy="100" r="100" fx="100" fy="100"
|
||||
gradientTransform="
|
||||
skewX(20)
|
||||
translate(-35, 0)
|
||||
">
|
||||
<stop offset="0%" stop-color="darkblue" />
|
||||
<stop offset="50%" stop-color="skyblue" />
|
||||
<stop offset="100%" stop-color="darkblue" />
|
||||
</radialGradient>
|
||||
|
||||
<rect x="0" y="0" width="200" height="200" fill="url(#gradient1)" />
|
||||
<rect x="0" y="0" width="200" height="200" fill="url(#gradient2)" style="transform: translateX(220px);" />
|
||||
</svg>
|
||||
|
||||
<svg viewBox="-40 0 150 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g fill="grey"
|
||||
transform="rotate(-10 50 100)
|
||||
translate(-36 45.5)
|
||||
skewX(40)
|
||||
scale(1 0.5)">
|
||||
<path id="heart" d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z" />
|
||||
</g>
|
||||
|
||||
<use xlink:href="#heart" fill="none" stroke="red"/>
|
||||
</svg>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -274,4 +274,194 @@
|
||||
<svg viewBox="0 0 140 50">
|
||||
<text y=20>Default spacing</text>
|
||||
<text y=40 xml:space=preserve>Preserved spacing</text>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 220 100">
|
||||
|
||||
<rect width=100 height=100 onclick='alert("testtest")'/>
|
||||
<rect width=100 height=100 onclick='alert("testtest")'/>
|
||||
|
||||
|
||||
<rect x=120 width=100 height=100 rx=15 />
|
||||
</svg>
|
||||
|
||||
<svg>
|
||||
<a href=" test.html " ondragexit='alert("testtest")' rel="nofollow noindex">Test</a>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 100 100" width=160 height=60 y=30>
|
||||
<use href=#smiley />
|
||||
</svg>
|
||||
|
||||
<svg viewBox="-10 -10 120 120">
|
||||
|
||||
<polygon stroke=black fill=none points="50,0 21,90 98,35 2,35 79,90"/>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 120 120">
|
||||
<circle cx=60 cy=10 r=10>
|
||||
<animate attributeName=cx dur=4s repeatCount=indefinite values=60;110;60;10;60 keyTimes=0;0.25;0.5;0.75;1 />
|
||||
<animate attributeName=cy dur=4s repeatCount=indefinite values=10;60;110;60;10 keyTimes=0;0.25;0.5;0.75;1 />
|
||||
</circle>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 120 120">
|
||||
<circle cx=60 cy=10 r=10>
|
||||
<animate attributeName=cx dur=4s calcMode=spline repeatCount=indefinite values=60;110;60;10;60 keyTimes=0;0.25;0.5;0.75;1 keySplines="0.5 0 0.5 1;0.5 0 0.5 1;0.5 0 0.5 1;0.5 0 0.5 1"/>
|
||||
<animate attributeName=cy dur=4s calcMode=spline repeatCount=indefinite values=10;60;110;60;10 keyTimes=0;0.25;0.5;0.75;1 keySplines="0.5 0 0.5 1;0.5 0 0.5 1;0.5 0 0.5 1;0.5 0 0.5 1"/>
|
||||
</circle>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="-5 -5 10 10">
|
||||
|
||||
<rect width=100% height=100% />
|
||||
|
||||
|
||||
<circle cx=50% cy=50% r=4 fill=white />
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 30 10">
|
||||
|
||||
<line y1=9 x2=30 y2=9 stroke=black stroke-dasharray="4 1 2 3"/>
|
||||
<rect x=11 y=1 width=8 height=8 stroke=green clip-path="circle() fill-box"/>
|
||||
</svg>
|
||||
|
||||
<svg id=svg_css_ex1 viewBox="0 0 100 100">
|
||||
<path fill=none stroke=red d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z"/>
|
||||
</svg>
|
||||
|
||||
<svg width=120 height=120 viewBox="0 0 120 120" version=1.1>
|
||||
|
||||
|
||||
<rect x=10 y=35 height=15 width=0>
|
||||
<animate attributeType=XML attributeName=width to=50 id=first begin=0s;third.end end=0s;third.end dur=4s />
|
||||
</rect>
|
||||
|
||||
<rect x=60 y=60 height=15 width=0>
|
||||
<animate attributeType=XML attributeName=width to=25 id=second begin=first.end dur=2s />
|
||||
</rect>
|
||||
|
||||
<rect x=85 y=85 height=15 width=0>
|
||||
<animate attributeType=XML attributeName=width to=25 id=third begin=second.end dur=2s />
|
||||
</rect>
|
||||
|
||||
|
||||
<text x=10 y=20 text-anchor=middle>0s</text>
|
||||
<line x1=10 y1=25 x2=10 y2=105 stroke=grey stroke-width=.5 />
|
||||
<text x=35 y=20 text-anchor=middle>2s</text>
|
||||
<line x1=35 y1=25 x2=35 y2=105 stroke=grey stroke-width=.5 />
|
||||
<text x=60 y=20 text-anchor=middle>4s</text>
|
||||
<line x1=60 y1=25 x2=60 y2=105 stroke=grey stroke-width=.5 />
|
||||
<text x=85 y=20 text-anchor=middle>6s</text>
|
||||
<line x1=85 y1=25 x2=85 y2=105 stroke=grey stroke-width=.5 />
|
||||
<text x=110 y=20 text-anchor=middle>8s</text>
|
||||
<line x1=110 y1=25 x2=110 y2=105 stroke=grey stroke-width=.5 />
|
||||
|
||||
<line x1=10 y1=30 x2=110 y2=30 stroke=grey stroke-width=.5 />
|
||||
<line x1=10 y1=105 x2=110 y2=105 stroke=grey stroke-width=.5 />
|
||||
</svg>
|
||||
|
||||
<svg>
|
||||
<filter id=colorMeTheSame>
|
||||
<feColorMatrix in=SourceGraphic values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
|
||||
</filter>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 420 200">
|
||||
<filter id=convolveMatrix1 x=0 y=0 width=100% height=100%>
|
||||
<feConvolveMatrix kernelMatrix="1 1 0 0 0 0 0 0 -1"/>
|
||||
</filter>
|
||||
<filter id=convolveMatrix2 x=0 y=0 width=100% height=100%>
|
||||
<feConvolveMatrix kernelMatrix="-1 0 0 0 0 0 0 0 1"/>
|
||||
</filter>
|
||||
|
||||
<image xlink:href=//developer.mozilla.org/files/6457/mdn_logo_only_color.png width=200 height=200 style=filter:url(#convolveMatrix1) />
|
||||
<image xlink:href=//developer.mozilla.org/files/6457/mdn_logo_only_color.png width=200 height=200 style=filter:url(#convolveMatrix2);transform:translateX(220px) />
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 100 100">
|
||||
|
||||
<pattern id=p1 width=.25 height=.25 patternTransform="rotate(20) skewX(30) scale(1 0.5)">
|
||||
<circle cx=10 cy=10 r=10 />
|
||||
</pattern>
|
||||
|
||||
|
||||
<rect x=10 y=10 width=80 height=80 fill=url(#p1) />
|
||||
</svg>
|
||||
|
||||
<svg xml:lang=en viewBox="0 0 200 500">
|
||||
<title>Scream—Comic Book text</title>
|
||||
<style>@font-face{font-family:"SequentialistBB";src:url(fonts/SequentialistBB.woff2)format("woff2"),url(fonts/SequentialistBB.woff)format("woff");font-style:normal;font-weight:400}text{font-family:SequentialistBB,Papyrus-condensed,Impact,sans-serif-condensed,sans-serif;font-stretch:condensed;writing-mode:tb;glyph-orientation-vertical:0;writing-mode:vertical-rl;text-orientation:upright;font-size:28px}tspan{font-size:75%}path{fill:#fff;stroke:#000;stroke-width:2}</style>
|
||||
<path d="M175,495 L140,465 C30,500 40,400 30,200 S70,10 100,10 S170,0 170,200 S170,400 150,450 Z"/>
|
||||
<text x=100 y=12 rotate="0 15 30 45 60 75 90 105 120 135 150 165 180 195 210 225 240 255 270 285 300 315 330 345 360" textLength=450>
|
||||
AAAaaaa<tspan>aaaa<tspan>aaaa<tspan>aahhh!</tspan>!</tspan>!</tspan>!</text>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 100 100">
|
||||
<path id=MyPath fill=none stroke=silver d="M10,90 Q90,90 90,45 Q90,10 50,10 Q10,10 10,40 Q10,70 45,70 Q70,70 75,50"/>
|
||||
|
||||
<text>
|
||||
<textPath path="M10,90 Q90,90 90,45 Q90,10 50,10 Q10,10 10,40 Q10,70 45,70 Q70,70 75,50">
|
||||
Quick brown fox jumps over the lazy dog.
|
||||
</textPath>
|
||||
</text>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 420 200">
|
||||
<defs>
|
||||
<linearGradient id=gradient gradientUnits=userSpaceOnUse x1=0 y1=0 x2=200 y2=0>
|
||||
<stop stop-color=#ff0000 />
|
||||
<stop offset=0.5 stop-color=#00ff00 />
|
||||
<stop offset=1 stop-color=#0000ff />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<filter id=componentTransfer1 x=0 y=0 width=100% height=100%>
|
||||
<feComponentTransfer>
|
||||
<feFuncR type=table tableValues="0 1"/>
|
||||
<feFuncG type=table tableValues="0 1"/>
|
||||
<feFuncB type=table tableValues="0 1"/>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
<filter id=componentTransfer2 x=0 y=0 width=100% height=100%>
|
||||
<feComponentTransfer>
|
||||
<feFuncR type=table tableValues="1 0"/>
|
||||
<feFuncG type=table tableValues="1 0"/>
|
||||
<feFuncB type=table tableValues="1 0"/>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
|
||||
<rect width=200 height=200 fill=url(#gradient) style=filter:url(#componentTransfer1) />
|
||||
<rect width=200 height=200 fill=url(#gradient) style=filter:url(#componentTransfer2);transform:translateX(220px) />
|
||||
</svg>
|
||||
|
||||
<svg width=450 height=1170>
|
||||
|
||||
|
||||
<rect class=ko x=10 y=10 height=25 width=430 />
|
||||
<rect class=ok x=10 y=10 height=25 width=430 requiredFeatures="http://www.w3.org/TR/SVG11/feature#SVG http://www.w3.org/TR/SVG11/feature#SVG"/>
|
||||
</svg>
|
||||
|
||||
<svg viewBox="0 0 420 200">
|
||||
<radialGradient id=gradient1 gradientUnits=userSpaceOnUse cx=100 cy=100 r=100 fx=100 fy=100>
|
||||
<stop offset=0% stop-color=darkblue />
|
||||
<stop offset=50% stop-color=skyblue />
|
||||
<stop offset=100% stop-color=darkblue />
|
||||
</radialGradient>
|
||||
<radialGradient id=gradient2 gradientUnits=userSpaceOnUse cx=100 cy=100 r=100 fx=100 fy=100 gradientTransform="skewX(20) translate(-35, 0)">
|
||||
<stop offset=0% stop-color=darkblue />
|
||||
<stop offset=50% stop-color=skyblue />
|
||||
<stop offset=100% stop-color=darkblue />
|
||||
</radialGradient>
|
||||
|
||||
<rect width=200 height=200 fill=url(#gradient1) />
|
||||
<rect width=200 height=200 fill=url(#gradient2) style=transform:translateX(220px) />
|
||||
</svg>
|
||||
|
||||
<svg viewBox="-40 0 150 100">
|
||||
<g fill=grey transform="rotate(-10 50 100) translate(-36 45.5) skewX(40) scale(1 0.5)">
|
||||
<path id=heart d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z"/>
|
||||
</g>
|
||||
|
||||
<use xlink:href=#heart fill=none stroke=red />
|
||||
</svg>
|
Loading…
Reference in New Issue
Block a user