fix(html/minifier): Fix bugs of the smart mode (#5093)

This commit is contained in:
Alexander Akait 2022-07-05 09:04:12 +03:00 committed by GitHub
parent 09d7f7aa27
commit 5932a0a2ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 616 additions and 211 deletions

View File

@ -1,7 +1,5 @@
#![deny(clippy::all)]
use std::mem::take;
use once_cell::sync::Lazy;
use serde_json::Value;
use swc_atoms::{js_word, JsWord};
@ -656,6 +654,15 @@ impl Minifier {
!matches!(self.collapse_whitespaces, CollapseWhitespaces::None)
}
fn is_custom_element(&self, tag_name: &str) -> bool {
// https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
match tag_name {
"annotation-xml" | "color-profile" | "font-face" | "font-face-src"
| "font-face-uri" | "font-face-format" | "font-face-name" | "missing-glyph" => false,
_ => matches!(tag_name.chars().next(), Some('a'..='z')) && tag_name.contains('-'),
}
}
fn get_display(&self, namespace: Namespace, tag_name: &str) -> Display {
match namespace {
Namespace::HTML => {
@ -715,90 +722,87 @@ impl Minifier {
_ => Display::Inline,
}
}
Namespace::SVG => match tag_name {
"text" | "foreignObject" => Display::Block,
_ => Display::Inline,
},
_ => Display::Inline,
}
}
fn is_element_displayed(&self, namespace: Namespace, tag_name: &str) -> bool {
match namespace {
// https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#metadata_content
//
// Excluded:
// `noscript` - can be displayed if JavaScript disabled
// `script` - can insert markup using `document.write`
Namespace::HTML => !matches!(
tag_name,
"base" | "command" | "link" | "meta" | "style" | "title"
),
Namespace::HTML => {
// https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#metadata_content
//
// Excluded:
// `noscript` - can be displayed if JavaScript disabled
// `script` - can insert markup using `document.write`
!matches!(
tag_name,
"base" | "command" | "link" | "meta" | "style" | "title" | "template"
)
}
Namespace::SVG => !matches!(tag_name, "style"),
_ => true,
}
}
fn remove_leading_and_trailing_whitespaces(&self, children: &mut Vec<Child>) {
if let Some(last) = children.first_mut() {
match last {
Child::Text(text) => {
text.data = text.data.trim_start_matches(is_whitespace).into();
fn remove_leading_and_trailing_whitespaces(
&self,
children: &mut Vec<Child>,
only_first: bool,
only_last: bool,
) {
if only_first {
if let Some(last) = children.first_mut() {
match last {
Child::Text(text) => {
text.data = text.data.trim_start_matches(is_whitespace).into();
if text.data.is_empty() {
children.remove(0);
if text.data.is_empty() {
children.remove(0);
}
}
Child::Element(Element {
namespace,
tag_name,
children,
..
}) if get_white_space(*namespace, tag_name) == WhiteSpace::Normal => {
self.remove_leading_and_trailing_whitespaces(children, true, false);
}
_ => {}
}
Child::Element(Element {
namespace,
tag_name,
children,
..
}) if get_white_space(*namespace, tag_name) == WhiteSpace::Normal => {
self.remove_leading_and_trailing_whitespaces(children);
}
_ => {}
}
}
if let Some(last) = children.last_mut() {
match last {
Child::Text(text) => {
text.data = text.data.trim_end_matches(is_whitespace).into();
if only_last {
if let Some(last) = children.last_mut() {
match last {
Child::Text(text) => {
text.data = text.data.trim_end_matches(is_whitespace).into();
if text.data.is_empty() {
children.pop();
if text.data.is_empty() {
children.pop();
}
}
Child::Element(Element {
namespace,
tag_name,
children,
..
}) if get_white_space(*namespace, tag_name) == WhiteSpace::Normal => {
self.remove_leading_and_trailing_whitespaces(children, false, true);
}
_ => {}
}
Child::Element(Element {
namespace,
tag_name,
children,
..
}) if get_white_space(*namespace, tag_name) == WhiteSpace::Normal => {
self.remove_leading_and_trailing_whitespaces(children);
}
_ => {}
}
}
}
fn get_deep_last_text_element<'a>(&self, node: &'a Child) -> Option<&'a Text> {
match node {
Child::Text(text) => Some(text),
Child::Element(Element {
namespace,
tag_name,
children,
..
}) if get_white_space(*namespace, tag_name) == WhiteSpace::Normal => {
if let Some(last) = children.last() {
self.get_deep_last_text_element(last)
} else {
None
}
}
_ => None,
}
}
fn get_prev_non_comment_node<'a>(
fn get_prev_displayed_node<'a>(
&self,
children: &'a Vec<Child>,
index: usize,
@ -806,15 +810,96 @@ impl Minifier {
let prev = children.get(index);
match prev {
Some(Child::Comment(_)) if index >= 1 => {
self.get_prev_non_comment_node(children, index - 1)
Some(Child::Comment(_)) => {
if index >= 1 {
self.get_prev_displayed_node(children, index - 1)
} else {
None
}
}
Some(Child::Element(element)) => {
if !self.is_element_displayed(element.namespace, &element.tag_name) && index >= 1 {
self.get_prev_displayed_node(children, index - 1)
} else if !element.children.is_empty() {
self.get_prev_displayed_node(&element.children, element.children.len() - 1)
} else {
prev
}
}
Some(_) => prev,
_ => None,
}
}
fn get_next_non_comment_node<'a>(
fn get_last_displayed_text_node<'a>(
&self,
children: &'a Vec<Child>,
index: usize,
) -> Option<&'a Text> {
let prev = children.get(index);
match prev {
Some(Child::Comment(_)) => {
if index >= 1 {
self.get_last_displayed_text_node(children, index - 1)
} else {
None
}
}
Some(Child::Element(element)) => {
if !self.is_element_displayed(element.namespace, &element.tag_name) && index >= 1 {
self.get_last_displayed_text_node(children, index - 1)
} else if !element.children.is_empty() {
for index in (0..=element.children.len() - 1).rev() {
if let Some(text) =
self.get_last_displayed_text_node(&element.children, index)
{
return Some(text);
}
}
None
} else {
None
}
}
Some(Child::Text(text)) => Some(text),
_ => None,
}
}
fn get_first_displayed_text_node<'a>(
&self,
children: &'a Vec<Child>,
index: usize,
) -> Option<&'a Text> {
let next = children.get(index);
match next {
Some(Child::Comment(_)) => self.get_first_displayed_text_node(children, index + 1),
Some(Child::Element(element)) => {
if !self.is_element_displayed(element.namespace, &element.tag_name) && index >= 1 {
self.get_first_displayed_text_node(children, index - 1)
} else if !element.children.is_empty() {
for index in 0..=element.children.len() - 1 {
if let Some(text) =
self.get_first_displayed_text_node(&element.children, index)
{
return Some(text);
}
}
None
} else {
None
}
}
Some(Child::Text(text)) => Some(text),
_ => None,
}
}
fn get_next_displayed_node<'a>(
&self,
children: &'a Vec<Child>,
index: usize,
@ -822,23 +907,17 @@ impl Minifier {
let next = children.get(index);
match next {
Some(Child::Comment(_)) => self.get_next_non_comment_node(children, index + 1),
Some(Child::Comment(_)) => self.get_next_displayed_node(children, index + 1),
Some(Child::Element(element))
if !self.is_element_displayed(element.namespace, &element.tag_name) =>
{
self.get_next_displayed_node(children, index + 1)
}
Some(_) => next,
_ => None,
}
}
fn get_next_text_node<'a>(&self, children: &'a Vec<Child>, index: usize) -> Option<&'a Child> {
let next = children.get(index);
match next {
Some(Child::Text(_)) => next,
Some(Child::Element(_)) => None,
Some(_) => self.get_next_text_node(children, index + 1),
_ => None,
}
}
fn get_whitespace_minification_for_tag(
&self,
namespace: Namespace,
@ -966,17 +1045,17 @@ impl Minifier {
true
}
fn minify_children(&mut self, children: &mut Vec<Child>) {
fn minify_children(&mut self, children: &Vec<Child>) -> Vec<Child> {
let (namespace, tag_name) = match &self.current_element {
Some(element) => (element.namespace, &element.tag_name),
_ => return,
_ => {
unreachable!();
}
};
let mode = self.get_whitespace_minification_for_tag(namespace, tag_name);
let child_will_be_retained = |child: &mut Child,
prev: Option<&Child>,
next: Option<&Child>| {
let child_will_be_retained = |child: &mut Child, children: &Vec<Child>, index: usize| {
match child {
Child::Comment(comment) if self.remove_comments => {
self.is_preserved_comment(&comment.data)
@ -989,7 +1068,8 @@ impl Minifier {
|| (element.namespace == Namespace::HTML
&& &*element.tag_name == "noscript"))
&& element.attributes.is_empty()
&& self.empty_children(&element.children) =>
&& self.empty_children(&element.children)
&& element.content.is_none() =>
{
false
}
@ -1016,16 +1096,20 @@ impl Minifier {
let mut is_smart_right_trim = false;
if self.collapse_whitespaces == CollapseWhitespaces::Smart {
let prev_display = if let Some(Child::Element(Element {
namespace,
tag_name,
..
})) = &prev
{
Some(self.get_display(*namespace, tag_name))
let prev = if index >= 1 {
children.get(index - 1)
} else {
None
};
let prev_display = match prev {
Some(Child::Element(Element {
namespace,
tag_name,
..
})) => Some(self.get_display(*namespace, tag_name)),
Some(Child::Comment(_)) => Some(Display::None),
_ => None,
};
is_smart_left_trim = match prev_display {
// Block-level containers:
@ -1033,8 +1117,8 @@ impl Minifier {
// `Display::Block` - `display: block flow`
// `Display::ListItem` - `display: block flow list-item`
// `Display::Table` - `display: block table`
// + internal table display (only whitespace characters allowed
// there)
//
// + internal table display (only whitespace characters allowed there)
Some(
Display::Block
| Display::ListItem
@ -1048,62 +1132,106 @@ impl Minifier {
| Display::TableRowGroup
| Display::TableFooterGroup,
) => true,
// These elements are not displayed
Some(Display::None) if prev.is_some() => {
if let Some(Child::Element(Element {
namespace,
tag_name,
..
})) = &prev
{
!self.is_element_displayed(*namespace, tag_name)
} else {
true
}
}
// Elements are not displayed
// And
// Inline box
Some(Display::Inline) => {
if let Some(prev) = &prev {
let deep = self.get_deep_last_text_element(prev);
if let Some(deep) = deep {
deep.data.ends_with(is_whitespace)
} else {
false
}
Some(Display::None) | Some(Display::Inline) => {
// A custom element can contain any elements, we cannot predict the
// behavior of spaces
let is_custom_element = if let Some(Child::Element(element)) = &prev
{
self.is_custom_element(&*element.tag_name)
} else {
false
};
if is_custom_element {
false
} else {
match &self.get_prev_displayed_node(children, index - 1) {
Some(Child::Text(text)) => {
text.data.ends_with(is_whitespace)
}
Some(Child::Element(element)) => {
let deep = if !element.children.is_empty() {
self.get_last_displayed_text_node(
&element.children,
element.children.len() - 1,
)
} else {
None
};
if let Some(deep) = deep {
deep.data.ends_with(is_whitespace)
} else {
false
}
}
_ => {
let parent_display =
self.get_display(namespace, tag_name);
match parent_display {
Display::Inline => {
if let Some(Child::Text(Text {
data, ..
})) = &self.latest_element
{
data.ends_with(is_whitespace)
} else {
false
}
}
_ => true,
}
}
}
}
}
// Inline level containers and etc
Some(_) => false,
None => {
let parent_display = self.get_display(namespace, tag_name);
// Template can be used in any place, so let's keep whitespaces
//
// For custom elements - an unnamed `<slot>` will be filled with all
// of the custom element's top-level
// child nodes that do not have the slot
// attribute. This includes text nodes.
// Also they can be used for custom logic
match parent_display {
Display::Inline => {
if let Some(Child::Text(Text { data, .. })) =
&self.latest_element
{
data.ends_with(is_whitespace)
} else {
false
if (namespace == Namespace::HTML && tag_name == "template")
|| self.is_custom_element(tag_name)
{
false
} else {
let parent_display = self.get_display(namespace, tag_name);
match parent_display {
Display::Inline => {
if let Some(Child::Text(Text { data, .. })) =
&self.latest_element
{
data.ends_with(is_whitespace)
} else {
false
}
}
_ => true,
}
_ => true,
}
}
};
let next_display = if let Some(Child::Element(Element {
namespace,
tag_name,
..
})) = &next
{
Some(self.get_display(*namespace, tag_name))
} else {
None
let next = children.get(index + 1);
let next_display = match next {
Some(Child::Element(Element {
namespace,
tag_name,
..
})) => Some(self.get_display(*namespace, tag_name)),
Some(Child::Comment(_)) => Some(Display::None),
_ => None,
};
is_smart_right_trim = match next_display {
@ -1112,8 +1240,8 @@ impl Minifier {
// `Display::Block` - `display: block flow`
// `Display::ListItem` - `display: block flow list-item`
// `Display::Table` - `display: block table`
// + internal table display (only whitespace characters allowed
// there)
//
// + internal table display (only whitespace characters allowed there)
Some(
Display::Block
| Display::ListItem
@ -1128,23 +1256,39 @@ impl Minifier {
| Display::TableFooterGroup,
) => true,
// These elements are not displayed
Some(Display::None) if prev.is_some() => {
if let Some(Child::Element(Element {
namespace,
tag_name,
..
})) = &next
{
!self.is_element_displayed(*namespace, tag_name)
} else {
true
Some(Display::None) => {
match &self.get_next_displayed_node(children, index + 1) {
Some(Child::Text(text)) => text.data.starts_with(is_whitespace),
Some(Child::Element(element)) => {
let deep = self
.get_first_displayed_text_node(&element.children, 0);
if let Some(deep) = deep {
!deep.data.starts_with(is_whitespace)
} else {
false
}
}
_ => {
let parent_display = self.get_display(namespace, tag_name);
!matches!(parent_display, Display::Inline)
}
}
}
Some(_) => false,
None => {
let parent_display = self.get_display(namespace, tag_name);
// Template can be used in any place, so let's keep whitespaces
let is_template =
namespace == Namespace::HTML && tag_name == "template";
!matches!(parent_display, Display::Inline)
if is_template {
false
} else {
let parent_display = self.get_display(namespace, tag_name);
!matches!(parent_display, Display::Inline)
}
}
};
}
@ -1177,56 +1321,59 @@ impl Minifier {
}
};
let cloned_children = children.clone();
let mut new_children = Vec::with_capacity(children.len());
let mut index = 0;
let mut pending_text = vec![];
for (index, child) in children.iter().enumerate() {
let mut child = child.clone();
children.retain_mut(|child| {
match child {
Child::Text(text)
if self
.get_next_text_node(&cloned_children, index + 1)
.is_some()
&& !child_will_be_retained(
&mut cloned_children.get(index + 1).cloned().unwrap(),
self.get_prev_non_comment_node(&cloned_children, index),
self.get_next_non_comment_node(&cloned_children, index + 2),
) =>
{
pending_text.push(text.data.clone());
// Merge adjacent text nodes
let merged = match &mut child {
Child::Text(text) => {
if let Some(Child::Text(prev_text)) = new_children.last_mut() {
let mut new_data =
String::with_capacity(prev_text.data.len() + text.data.len());
index += 1;
new_data.push_str(&prev_text.data);
new_data.push_str(&text.data);
return false;
}
Child::Text(text) if !pending_text.is_empty() => {
let mut new_value = String::new();
text.data = new_data.into();
for text in take(&mut pending_text) {
new_value.push_str(&text);
new_children.pop();
true
} else {
false
}
new_value.push_str(&text.data);
text.data = new_value.into();
}
_ => {}
}
let prev = if index >= 1 {
self.get_prev_non_comment_node(&cloned_children, index - 1)
} else {
None
_ => false,
};
let next = self.get_next_non_comment_node(&cloned_children, index + 1);
let result = child_will_be_retained(child, prev, next);
let mut merged_children = new_children.clone();
index += 1;
let (merged_children, offset) = if merged {
merged_children.push(child.clone());
result
});
let offset = merged_children.len() - 1;
merged_children.extend_from_slice(&children[index + 1..]);
(merged_children, offset)
} else {
let offset = merged_children.len();
merged_children.extend_from_slice(&children[index..]);
(merged_children, offset)
};
let result = child_will_be_retained(&mut child, &merged_children, offset);
if result {
new_children.push(child);
}
}
new_children
}
fn get_attribute_value(&self, attributes: &Vec<Attribute>, name: &str) -> Option<JsWord> {
@ -1548,7 +1695,7 @@ impl Minifier {
let mut document_or_document_fragment = match mode {
HtmlMinificationMode::ConditionalComments => {
// Emulate content inside conditional comments like content inside the
// `template` element
// `template` element, because it can be used in any place in source code
context_element = Some(Element {
span: Default::default(),
tag_name: "template".into(),
@ -1660,7 +1807,7 @@ impl VisitMut for Minifier {
}
fn visit_mut_document_fragment(&mut self, n: &mut DocumentFragment) {
self.minify_children(&mut n.children);
n.children = self.minify_children(&n.children);
n.visit_mut_children_with(self);
}
@ -1682,8 +1829,13 @@ impl VisitMut for Minifier {
self.current_element = None;
if self.need_collapse_whitespace() {
self.latest_element = Some(n.clone());
if self.collapse_whitespaces == CollapseWhitespaces::Smart {
match n {
Child::Text(_) | Child::Element(_) => {
self.latest_element = Some(n.clone());
}
_ => {}
}
}
}
@ -1705,7 +1857,7 @@ impl VisitMut for Minifier {
self.descendant_of_pre = get_white_space(n.namespace, &n.tag_name) == WhiteSpace::Pre;
}
self.minify_children(&mut n.children);
n.children = self.minify_children(&n.children);
n.visit_mut_children_with(self);
@ -1714,7 +1866,7 @@ impl VisitMut for Minifier {
&& &*n.tag_name == "body"
&& self.need_collapse_whitespace()
{
self.remove_leading_and_trailing_whitespaces(&mut n.children);
self.remove_leading_and_trailing_whitespaces(&mut n.children, true, true);
}
if self.need_collapse_whitespace() {

View File

@ -1,9 +1,4 @@
<!doctype html><html lang=en><body>
<svg>
<!doctype html><html lang=en><svg>
</svg>
</svg>

View File

@ -1 +1 @@
<!doctype html><html lang=en><meta charset=UTF-8><title>Document</title><body><template ngfor #hero [ngforof]=heroes><hero-detail *ngif=hero [hero]=hero></hero-detail></template><form (ngsubmit)=onSubmit(theForm) #theform=ngForm><div class=form-group><label for=name>Name</label> <input class=form-control required ngcontrol=firstName [(ngmodel)]=currentHero.firstName></div><button [disabled]=!theForm.form.valid>Submit</button></form>
<!doctype html><html lang=en><meta charset=UTF-8><title>Document</title><body><template ngfor #hero [ngforof]=heroes> <hero-detail *ngif=hero [hero]=hero></hero-detail> </template><form (ngsubmit)=onSubmit(theForm) #theform=ngForm><div class=form-group><label for=name>Name</label> <input class=form-control required ngcontrol=firstName [(ngmodel)]=currentHero.firstName></div><button [disabled]=!theForm.form.valid>Submit</button></form>

View File

@ -432,5 +432,14 @@
</style>
</svg>
<div>
<span>test</span> a <!-- test -->b <span>test</span>
<span>test</span> a<!-- test --> b <span>test</span>
<span>test</span> a <!-- test --> b <span>test</span>
</div>
<div><foo-bar> <span>test</span> </foo-bar> <foo-bar> <span>test</span> </foo-bar></div>
<div><svg> <linearGradient id=gradient /> </svg> <span>a</span></div>
</body>
</html>

View File

@ -21,12 +21,12 @@
Foo
</textarea><div><div>Text</div></div><unknown><div>Text</div></unknown><div></div><svg version=1.1 viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" style=width:100%;height:100%;position:absolute;top:0;left:0;z-index:-1> <linearGradient id=gradient><stop class=begin offset=0% /><stop class=end offset=100% /></linearGradient><rect x=0 y=0 width=100 height=100 style=fill:url(#gradient) /> <circle cx=50 cy=50 r=30 style=fill:url(#gradient) /> </svg><svg viewBox="0 0 100 100"> <a href=/docs/Web/SVG/Element/circle><circle cx=50 cy=40 r=35 /> </a> <a href=/docs/Web/SVG/Element/text><text x=50 y=90 text-anchor=middle>&lt;circle> </text></a></svg><script data-test=test></script> <script>console.log("test")</script><xmp>
</textarea><div><div>Text</div></div><unknown><div>Text</div></unknown><div></div><svg version=1.1 viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" style=width:100%;height:100%;position:absolute;top:0;left:0;z-index:-1> <linearGradient id=gradient><stop class=begin offset=0% /><stop class=end offset=100% /></linearGradient><rect x=0 y=0 width=100 height=100 style=fill:url(#gradient) /> <circle cx=50 cy=50 r=30 style=fill:url(#gradient) /> </svg><svg viewBox="0 0 100 100"> <a href=/docs/Web/SVG/Element/circle><circle cx=50 cy=40 r=35 /> </a><a href=/docs/Web/SVG/Element/text><text x=50 y=90 text-anchor=middle>&lt;circle></text></a></svg><script data-test=test></script><script>console.log("test")</script><xmp>
test
</xmp><div>foo <a>baz </a>bar foo <a>baz </a>bar foo <a>baz </a>bar</div><div>foo <a>baz </a>bar foo <a>baz </a>bar foo <a>baz </a>bar</div><div>foo <img src=https://prettier.io/icon.png></div><div>text <img src=https://colourlex.com/wp-content/uploads/2021/02/vine-black-painted-swatch.jpg alt=test> test</div><span>test<script>console.log("test")</script>test</span> <span>test <script>console.log("test")</script> test</span><div><p>blah</div><div>test <br> test</div><div>test <wbr> test</div><div>a <input> c</div><div><div>a</div><div>b</div></div><div><span> a </span><span>b</span></div><div><div>test</div><span>test</span></div><div><div>test</div><span>test</span></div><div><span>test</span><div>test</div></div><div><span>test</span> <span>test</span></div><div><div>test</div><div>test</div></div><div><span>test</span><p>test<p>test<p>test</div><div><p>test<p>test<p>test</p><span>test</span></div><div><a href=test> test </a><a href=test>test</a></div><div><a href=test>test</a><a href=test>test</a></div><div><p>blah</div><div>test <button>test</button></div><div><button>test</button> <button>test</button></div><div>foo <button>test</button> foo</div><div>foo<button>test</button>foo</div><div>foo <button>test</button>foo</div><div>foo<button>test</button> foo</div><div>foo<button>test</button>foo</div><div>foo <button>test</button>foo</div><div>foo<button>test</button> foo</div><div><span> foo </span></div><p>foo <img> bar<p>foo<img>bar<p>foo <img>bar<p>foo<img> bar<p>foo <wbr> bar<p>foo <br> bar<p>foo <nobr>a</nobr> bar<div> fo o </div><div>foo</div><p><p>a b<div class=leaveAlone></div><div>foo bar</div><div class=leaveAlone><div></div><span> </span>foo bar</div><div class=leaveAlone><span> </span>foo bar</div><p>foo <span></span><p>foo<span></span><div>foo <button>test</button> foo</div><div>foo <button>test</button> foo <button>test</button> foo</div><div>foo <span>foo</span> foo</div><div>foo<span> foo</span>foo</div><div><span>a </span>b<span> c</span></div><div><span>a </span>b <span>c</span></div><div><span>a </span>b <span>c</span></div><div>foo <span>baz</span></div><div>foo <span>baz</span></div><div>foo<span> baz</span></div><div>foo<span>baz</span></div><span>test </span><span><span><span><span>foo <span>baz</span></span></span></span></span> <span><span><span><span>foo <span>baz</span></span></span></span></span><span>test </span><div>test</div><span><span><span><span>foo <span>baz</span></span></span></span></span> <span><span><span><span>foo <span>baz</span></span></span></span></span><div>test</div><div><div></div></div><pre>
</xmp><div>foo <a>baz </a>bar foo <a>baz </a>bar foo <a>baz </a>bar</div><div>foo <a>baz </a>bar foo <a>baz </a>bar foo <a>baz </a>bar</div><div>foo <img src=https://prettier.io/icon.png></div><div>text <img src=https://colourlex.com/wp-content/uploads/2021/02/vine-black-painted-swatch.jpg alt=test> test</div><span>test<script>console.log("test")</script>test</span> <span>test<script>console.log("test")</script> test</span><div><p>blah</div><div>test <br> test</div><div>test <wbr> test</div><div>a <input> c</div><div><div>a</div><div>b</div></div><div><span> a </span><span>b</span></div><div><div>test</div><span>test</span></div><div><div>test</div><span>test</span></div><div><span>test</span><div>test</div></div><div><span>test</span> <span>test</span></div><div><div>test</div><div>test</div></div><div><span>test</span><p>test<p>test<p>test</div><div><p>test<p>test<p>test</p><span>test</span></div><div><a href=test> test </a><a href=test>test</a></div><div><a href=test>test</a><a href=test>test</a></div><div><p>blah</div><div>test <button>test</button></div><div><button>test</button> <button>test</button></div><div>foo <button>test</button> foo</div><div>foo<button>test</button>foo</div><div>foo <button>test</button>foo</div><div>foo<button>test</button> foo</div><div>foo<button>test</button>foo</div><div>foo <button>test</button>foo</div><div>foo<button>test</button> foo</div><div><span> foo </span></div><p>foo <img> bar<p>foo<img>bar<p>foo <img>bar<p>foo<img> bar<p>foo <wbr> bar<p>foo <br> bar<p>foo <nobr>a</nobr> bar<div> fo o </div><div>foo</div><p><p>a b<div class=leaveAlone></div><div>foo bar</div><div class=leaveAlone><div></div><span> </span>foo bar</div><div class=leaveAlone><span> </span>foo bar</div><p>foo <span></span><p>foo<span></span><div>foo <button>test</button> foo</div><div>foo <button>test</button> foo <button>test</button> foo</div><div>foo <span>foo</span> foo</div><div>foo<span> foo</span>foo</div><div><span>a </span>b<span> c</span></div><div><span>a </span>b <span>c</span></div><div><span>a </span>b <span>c</span></div><div>foo <span>baz</span></div><div>foo <span>baz</span></div><div>foo<span> baz</span></div><div>foo<span>baz</span></div><span>test </span><span><span><span><span>foo <span>baz</span></span></span></span></span> <span><span><span><span>foo <span>baz</span></span></span></span></span><span>test </span><div>test</div><span><span><span><span>foo <span>baz</span></span></span></span></span> <span><span><span><span>foo <span>baz</span></span></span></span></span><div>test</div><div><div></div></div><pre>
foo
baz
</pre><div>a <input> c</div><div>Empty</div><!--[if lte IE 6]> <span>A</span> <span title=" sigificant whitespace ">blah blah</span><![endif]--><div><a href=#> <span><b>foo </b><i> bar </i></span></a></div><div>a b</div><div>a b c d</div><div>text</div><span> text </span><span> text </span><div><span>test</span><span>test</span></div><div><span>test</span> <command>test</command> <span>test</span></div><div><span>test</span><link rel=stylesheet href=""><span>test</span></div><div><span>test</span><meta name=content><span>test</span></div><div><span>test</span> <script>console.log("test")</script> <span>test</span></div><div><span>test</span><style>a{color:red}</style><span>test</span></div><div><span>test</span><title>test</title><span>test</span></div><div><meta name=test><meta name=test></div><div><link rel=stylesheet href=""><link rel=stylesheet href=""></div><div><script>console.log("test")</script> <script>console.log("test")</script></div><div><script>console.log("test")</script> <span>test</span> <script>console.log("test")</script></div><div><style>a{color:red}</style><style>a{color:red}</style></div><div><script>console.log("test")</script><style>a{color:red}</style></div><div><span itemscope><meta itemprop=name content="The Castle">test</span> <span>test</span></div><div><meta name=test></div><div><style>a{color:red}</style></div><div><meta name=test><div>test</div><meta name=test></div><div><meta name=test><span>test</span><meta name=test></div><svg> <title>test</title> <metadata>test</metadata> <desc>test</desc> </svg><svg> <a>test</a> <a>test</a> </svg><svg> <text x=20 y=35><tspan font-weight=bold fill=red>This is bold and red</tspan> <tspan font-weight=bold fill=red>This is bold and red</tspan> </text></svg><svg> <tspan>test</tspan> <foreignObject>test</foreignObject> </svg><svg> <text x=20 y=35><tspan font-weight=bold fill=red>This is bold and red</tspan> <tspan font-weight=bold fill=red>This is bold and red</tspan> </text></svg><svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" style=width:100%;height:100%;position:absolute;top:0;left:0;z-index:-1> <linearGradient id=gradient><stop class=begin offset=0% /><stop class=end offset=100% /></linearGradient><rect x=0 y=0 width=100 height=100 style=fill:url(#gradient) /> <circle cx=50 cy=50 r=30 style=fill:url(#gradient) /> </svg><svg> <script>console.log("test")</script></svg><svg><style>a{color:red}</style></svg>
</pre><div>a <input> c</div><div>Empty</div><!--[if lte IE 6]> <span>A</span> <span title=" sigificant whitespace ">blah blah</span> <![endif]--><div><a href=#> <span><b>foo </b><i> bar </i></span></a></div><div>a b</div><div>a b c d</div><div>text</div><span> text </span><span> text </span><div><span>test</span> <span>test</span></div><div><span>test</span> <command>test</command><span>test</span></div><div><span>test</span><link rel=stylesheet href=""> <span>test</span></div><div><span>test</span><meta name=content> <span>test</span></div><div><span>test</span><script>console.log("test")</script> <span>test</span></div><div><span>test</span><style>a{color:red}</style> <span>test</span></div><div><span>test</span><title>test</title> <span>test</span></div><div><meta name=test><meta name=test></div><div><link rel=stylesheet href=""><link rel=stylesheet href=""></div><div><script>console.log("test")</script><script>console.log("test")</script></div><div><script>console.log("test")</script> <span>test</span><script>console.log("test")</script></div><div><style>a{color:red}</style><style>a{color:red}</style></div><div><script>console.log("test")</script><style>a{color:red}</style></div><div><span itemscope><meta itemprop=name content="The Castle">test</span> <span>test</span></div><div><meta name=test></div><div><style>a{color:red}</style></div><div><meta name=test><div>test</div><meta name=test></div><div><meta name=test> <span>test</span><meta name=test></div><svg> <title>test</title> <metadata>test</metadata> <desc>test</desc> </svg><svg> <a>test</a> <a>test</a> </svg><svg><text x=20 y=35><tspan font-weight=bold fill=red>This is bold and red</tspan> <tspan font-weight=bold fill=red>This is bold and red</tspan></text></svg><svg> <tspan>test</tspan><foreignObject>test</foreignObject></svg><svg><text x=20 y=35><tspan font-weight=bold fill=red>This is bold and red</tspan> <tspan font-weight=bold fill=red>This is bold and red</tspan></text></svg><svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" style=width:100%;height:100%;position:absolute;top:0;left:0;z-index:-1> <linearGradient id=gradient><stop class=begin offset=0% /><stop class=end offset=100% /></linearGradient><rect x=0 y=0 width=100 height=100 style=fill:url(#gradient) /> <circle cx=50 cy=50 r=30 style=fill:url(#gradient) /> </svg><svg> <script>console.log("test")</script></svg><svg> <style>a{color:red}</style></svg><div><span>test</span> a b <span>test</span> <span>test</span> a b <span>test</span> <span>test</span> a b <span>test</span></div><div><foo-bar> <span>test</span> </foo-bar> <foo-bar> <span>test</span> </foo-bar></div><div><svg> <linearGradient id=gradient /> </svg><span>a</span></div>

View File

@ -1 +1 @@
<!doctype html><html lang=en><div><a href=#><span><b>foo</b>z <i>bar</i></span></a></div>
<!doctype html><html lang=en><div><a href=#><span><b>foo </b>z <i>bar</i></span></a></div>

View File

@ -1,3 +1,6 @@
<!doctype html>
<html lang="en">
<span> <!-- test --> text <!-- test --></span> <span> <!-- test --> text <!-- test --></span>
<span> <!-- test --> text <!-- test --></span> <span><!-- test --> text <!-- test --></span>
<span> <!-- test --> text <!-- test --> </span> <span><!-- test --> text <!-- test --></span>
<span> <!-- test --> text <!-- test --></span> <span> <!-- test --> text <!-- test --></span>
<span> <!-- test --> text <!-- test --> </span> <span> <!-- test --> text <!-- test --></span>

View File

@ -1 +1 @@
<!doctype html><html lang=en><span>text</span> <span>text</span>
<!doctype html><html lang=en><span>text </span><span> text </span><span> text </span><span> text </span><span> text </span><span> text </span><span> text </span><span> text</span>

View File

@ -1 +1 @@
<!doctype html><svg><linearGradient id=gradient /></svg><span>a</span>
<!doctype html><svg><linearGradient id=gradient /> </svg><span>a</span>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,3 @@
<!doctype html>
<html lang="en">
<span> <span><!-- test --> text <!-- test --> </span></span> <span><span> <!-- test --> text <!-- test --></span> </span>

View File

@ -0,0 +1 @@
<!doctype html><html lang=en><span><span>text </span></span><span><span> text</span></span>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,3 @@
<!doctype html>
<html lang="en">
<span> <div><!-- test --> text <!-- test --> </div></span> <span><div> <!-- test --> text <!-- test --></div> </span>

View File

@ -0,0 +1 @@
<!doctype html><html lang=en><span><div>text</div></span><span><div>text</div></span>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,3 @@
<!doctype html>
<html lang="en">
<span> <span><!-- test --> text <!-- test --> </span><meta name="test"><!-- test --></span> <span><!-- test --><meta name="test"><span> <!-- test --> text <!-- test --></span> </span>

View File

@ -0,0 +1 @@
<!doctype html><html lang=en><span><span>text </span><meta name=test></span><span><meta name=test><span> text</span></span>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,3 @@
<!doctype html>
<html lang="en">
<foo-bar><span>test</span> a </foo-bar> b <foo-bar> c <span> test</span></foo-bar>

View File

@ -0,0 +1 @@
<!doctype html><html lang=en><foo-bar><span>test</span> a </foo-bar> b <foo-bar> c <span>test</span></foo-bar>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,3 @@
<!doctype html>
<html lang="en">
<foo-bar> <span>test</span> </foo-bar> <foo-bar> <span>test</span> </foo-bar>

View File

@ -0,0 +1 @@
<!doctype html><html lang=en><foo-bar><span>test</span> </foo-bar> <foo-bar> <span>test</span></foo-bar>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,18 @@
<!doctype html>
<div><span>test</span> <meta name="test"> <span>test</span></div>
<div><span>test</span> a <meta name="test"> <span>test</span></div>
<div><span>test</span> <meta name="test"> b <span>test</span></div>
<div><span>test</span> a <meta name="test"> b <span>test</span></div>
<div> <meta name="test"> <span>test</span> <meta name="test"> <span>test</span> <meta name="test"> </div>
<div> <span>test</span> <meta name="test"><meta name="test"><meta name="test"> <span>test</span> </div>
<div> <span>test</span> <meta name="test"> <meta name="test"> <meta name="test"> <span>test</span> </div>
<div><span>test</span> <template></template> <span>test</span></div>
<div><div>test</div> <meta name="test"> <div>test</div></div>
<div><img src="" alt=""> <meta name="test"> <img src="" alt=""></div>
<div><meta name="test"> <span>test</span> <meta name="test"></div>
<div><span>test</span> a<meta name="test"> b <span>test</span></div>
<div><span>test</span> a <meta name="test">b <span>test</span></div>
<div><span>test</span> a <meta name="test"> b <span>test</span></div>
<div><span>test</span> a<meta name="test">b <span>test</span></div>
<div> <meta name="test"> <span>test</span> <meta name="test"> <span>test</span> <meta name="test"> </div>
<div><span>test </span> a <meta name="test"> b <span>test</span></div>

View File

@ -0,0 +1 @@
<!doctype html><div><span>test</span><meta name=test> <span>test</span></div><div><span>test</span> a<meta name=test> <span>test</span></div><div><span>test</span><meta name=test> b <span>test</span></div><div><span>test</span> a<meta name=test> b <span>test</span></div><div><meta name=test> <span>test</span><meta name=test> <span>test</span><meta name=test></div><div><span>test</span><meta name=test><meta name=test><meta name=test> <span>test</span></div><div><span>test</span><meta name=test><meta name=test><meta name=test> <span>test</span></div><div><span>test</span><template></template> <span>test</span></div><div><div>test</div><meta name=test><div>test</div></div><div><img src="" alt=""><meta name=test> <img src="" alt=""></div><div><meta name=test> <span>test</span><meta name=test></div><div><span>test</span> a<meta name=test> b <span>test</span></div><div><span>test</span> a <meta name=test>b <span>test</span></div><div><span>test</span> a<meta name=test> b <span>test</span></div><div><span>test</span> a<meta name=test>b <span>test</span></div><div><meta name=test> <span>test</span><meta name=test> <span>test</span><meta name=test></div><div><span>test </span>a<meta name=test> b <span>test</span></div>

View File

@ -1 +1 @@
<!doctype html><html lang=en><meta charset=UTF-8><meta name=viewport content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"><meta http-equiv=X-UA-Compatible content="ie=edge"><title>Document</title><div><span>test</span><noscript><a href=#>External Link</a></noscript></div><div><span>test</span><noscript><a href=#>External Link</a></noscript></div>
<!doctype html><html lang=en><meta charset=UTF-8><meta name=viewport content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"><meta http-equiv=X-UA-Compatible content="ie=edge"><title>Document</title><div><span>test</span><noscript><a href=#>External Link</a></noscript></div><div><span>test</span><noscript> <a href=#>External Link</a></noscript></div>

View File

@ -1 +1 @@
<!doctype html><html lang=en><title>Document</title><body><template><span>test</span> <slot name=test>Test</slot></template> <template><span>test</span><slot name=test>Test</slot></template> <template><div>test</div><slot name=test>Test</slot></template> <template><div>test</div><slot name=test>Test</slot></template> <template><slot>A</slot> B <slot>C</slot></template>
<!doctype html><html lang=en><title>Document</title><body><template> <span>test</span> <slot name=test>Test</slot> </template><template> <span>test</span><slot name=test>Test</slot> </template><template><div>test</div><slot name=test>Test</slot> </template><template><div>test</div><slot name=test>Test</slot> </template><template> <slot>A</slot> B <slot>C</slot> </template>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,6 @@
<!doctype html>
<template id="template">
<slot name="a"><p>a</p></slot>
<slot name="b"><span>test</span> <span>test</span></slot>
<slot name="C"><div>test</div> <div>test</div></slot>
</template>

View File

@ -0,0 +1 @@
<!doctype html><template id=template> <slot name=a><p>a</p></slot> <slot name=b><span>test</span> <span>test</span></slot> <slot name=C><div>test</div><div>test</div></slot> </template>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>element-details - web component using &lt;template&gt; and &lt;slot&gt;</title>
<style>
dl { margin-left: 6px; }
dt { font-weight: bold; color: #217ac0; font-size: 110% }
dt { font-family: Consolas, "Liberation Mono", Courier }
dd { margin-left: 16px }
</style>
</head>
<body>
<h1>element-details - web component using <code>&lt;template&gt;</code> and <code>&lt;slot&gt;</code></h1>
<template id="element-details-template-1">
VALUE: !<slot>?</slot>!
</template>
<element-details>
<span>test</span> <span>foo</span>
</element-details>
<script>
customElements.define('element-details',
class extends HTMLElement {
constructor() {
super();
const template = document
.getElementById('element-details-template-1')
.content;
const shadowRoot = this.attachShadow({mode: 'open'})
.appendChild(template.cloneNode(true));
}
});
</script>
</body>
</html>

View File

@ -0,0 +1 @@
<!doctype html><meta charset=utf-8><title>element-details - web component using &lt;template> and &lt;slot></title><style>dl{margin-left:6px}dt{font-weight:700;color:#217ac0;font-size:110%}dt{font-family:Consolas,"Liberation Mono",Courier}dd{margin-left:16px}</style><h1>element-details - web component using <code>&lt;template></code> and <code>&lt;slot></code></h1><template id=element-details-template-1> VALUE: !<slot>?</slot>! </template> <element-details> <span>test</span> <span>foo</span> </element-details> <script>customElements.define("element-details",class extends HTMLElement{constructor(){super();let a=document.getElementById("element-details-template-1").content,b=this.attachShadow({mode:"open"}).appendChild(a.cloneNode(true))}})</script>

View File

@ -1 +1 @@
<!doctype html><meta charset=utf-8><title>element-details - web component using &lt;template> and &lt;slot></title><style>dl{margin-left:6px}dt{font-weight:700;color:#217ac0;font-size:110%}dt{font-family:Consolas,"Liberation Mono",Courier}dd{margin-left:16px}</style><h1>element-details - web component using <code>&lt;template></code> and <code>&lt;slot></code></h1><template id=element-details-template-1>VALUE: <slot name=q>?</slot></template> <template id=element-details-template-2>VALUE:<slot name=q>?</slot></template> <template id=element-details-template-3><div>VALUE:</div><slot name=q>?</slot></template> <element-details><span slot=q>1</span> </element-details><element-details> <span slot=q>2</span> </element-details><element-details-more> <span slot=q>3</span> </element-details-more><element-details-more> <span slot=q>4</span> </element-details-more><script>customElements.define("element-details",class extends HTMLElement{constructor(){super();let a=document.getElementById("element-details-template-1").content,b=this.attachShadow({mode:"open"}).appendChild(a.cloneNode(true))}});customElements.define("element-details-more",class extends HTMLElement{constructor(){super();let a=document.getElementById("element-details-template-2").content,b=this.attachShadow({mode:"open"}).appendChild(a.cloneNode(true))}})</script>
<!doctype html><meta charset=utf-8><title>element-details - web component using &lt;template> and &lt;slot></title><style>dl{margin-left:6px}dt{font-weight:700;color:#217ac0;font-size:110%}dt{font-family:Consolas,"Liberation Mono",Courier}dd{margin-left:16px}</style><h1>element-details - web component using <code>&lt;template></code> and <code>&lt;slot></code></h1><template id=element-details-template-1> VALUE: <slot name=q>?</slot> </template><template id=element-details-template-2> VALUE:<slot name=q>?</slot> </template><template id=element-details-template-3><div>VALUE:</div><slot name=q>?</slot> </template> <element-details> <span slot=q>1</span> </element-details> <element-details> <span slot=q>2</span> </element-details> <element-details-more> <span slot=q>3</span> </element-details-more> <element-details-more> <span slot=q>4</span> </element-details-more> <script>customElements.define("element-details",class extends HTMLElement{constructor(){super();let a=document.getElementById("element-details-template-1").content,b=this.attachShadow({mode:"open"}).appendChild(a.cloneNode(true))}});customElements.define("element-details-more",class extends HTMLElement{constructor(){super();let a=document.getElementById("element-details-template-2").content,b=this.attachShadow({mode:"open"}).appendChild(a.cloneNode(true))}})</script>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,2 @@
<!doctype html>
<span>test</span> <svg><text x="0" y="150" class="small">Мой</text> </svg> <span>a</span>

View File

@ -0,0 +1 @@
<!doctype html><span>test</span> <svg><text x=0 y=150 class=small>Мой</text></svg><span>a</span>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,2 @@
<!doctype html>
<span>test</span><svg> a <text x="0" y="150" class="small">Мой</text></svg><span>a</span>

View File

@ -0,0 +1 @@
<!doctype html><span>test</span><svg> a<text x=0 y=150 class=small>Мой</text></svg><span>a</span>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,13 @@
<!doctype html>
<svg width="350" height="60" xmlns="http://www.w3.org/2000/svg">
<text>
This is <tspan font-weight="bold" fill="red">bold and red</tspan> <tspan font-weight="bold" fill="red">bold and red</tspan>
</text>
<style><![CDATA[
text{
dominant-baseline: hanging;
font: 28px Verdana, Helvetica, Arial, sans-serif;
}
]]></style>
</svg>

View File

@ -0,0 +1 @@
<!doctype html><svg width=350 height=60><text>This is <tspan font-weight=bold fill=red>bold and red</tspan> <tspan font-weight=bold fill=red>bold and red</tspan></text><style>text{dominant-baseline:hanging;font:28px Verdana,Helvetica,Arial,sans-serif}</style></svg>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,96 @@
<!doctype html>
<svg>
<a href=""> </a>
<altGlyph> </altGlyph>
<altGlyphDef> </altGlyphDef>
<altGlyphItem> </altGlyphItem>
<animate> </animate>
<animateColor> </animateColor>
<animateMotion> </animateMotion>
<animateTransform> </animateTransform>
<animation> </animation>
<audio src=""></audio>
<canvas> </canvas>
<circle> </circle>
<clipPath> </clipPath>
<color-profile> </color-profile>
<cursor> </cursor>
<defs> </defs>
<desc> </desc>
<discard> </discard>
<ellipse> </ellipse>
<feBlend> </feBlend>
<feColorMatrix> </feColorMatrix>
<feComponentTransfer> </feComponentTransfer>
<feComposite> </feComposite>
<feConvolveMatrix> </feConvolveMatrix>
<feDiffuseLighting> </feDiffuseLighting>
<feDisplacementMap> </feDisplacementMap>
<feDistantLight> </feDistantLight>
<feDropShadow> </feDropShadow>
<feFlood> </feFlood>
<feFuncA> </feFuncA>
<feFuncB> </feFuncB>
<feFuncG> </feFuncG>
<feFuncR> </feFuncR>
<feGaussianBlur> </feGaussianBlur>
<feImage> </feImage>
<feMerge> </feMerge>
<feMergeNode> </feMergeNode>
<feMorphology> </feMorphology>
<feOffset> </feOffset>
<fePointLight> </fePointLight>
<feSpecularLighting> </feSpecularLighting>
<feSpotLight> </feSpotLight>
<feTile> </feTile>
<feTurbulence> </feTurbulence>
<filter> </filter>
<font> </font>
<font-face> </font-face>
<font-face-format> </font-face-format>
<font-face-name> </font-face-name>
<font-face-src> </font-face-src>
<font-face-uri> </font-face-uri>
<foreignObject> </foreignObject>
<g> </g>
<glyph> </glyph>
<glyphRef> </glyphRef>
<handler> </handler>
<hkern> </hkern>
<iframe src="" frameborder="0"></iframe>
<image> </image>
<line> </line>
<linearGradient> </linearGradient>
<listener> </listener>
<marker> </marker>
<mask> </mask>
<metadata> </metadata>
<missing-glyph> </missing-glyph>
<mpath> </mpath>
<path> </path>
<pattern> </pattern>
<polygon> </polygon>
<polyline> </polyline>
<prefetch> </prefetch>
<radialGradient> </radialGradient>
<rect> </rect>
<script> </script>
<set> </set>
<solidColor> </solidColor>
<stop> </stop>
<style> </style>
<svg> </svg>
<switch> </switch>
<symbol> </symbol>
<tbreak> </tbreak>
<text> </text>
<textArea> </textArea>
<textPath> </textPath>
<title> </title>
<tref> </tref>
<tspan> </tspan>
<unknown> </unknown>
<use> </use>
<video src=""></video>
<view> </view>
</svg>

View File

@ -0,0 +1 @@
<!doctype html><svg><a href="" /><altGlyph/><altGlyphDef/><altGlyphItem/><animate/><animateColor/><animateMotion/><animateTransform/><animation/><audio src="" /> <canvas/><circle> </circle><clipPath/><color-profile/><cursor/><defs/><desc/><discard/><ellipse> </ellipse><feBlend/><feColorMatrix/><feComponentTransfer/><feComposite/><feConvolveMatrix/><feDiffuseLighting/><feDisplacementMap/><feDistantLight/><feDropShadow/><feFlood/><feFuncA/><feFuncB/><feFuncG/><feFuncR/><feGaussianBlur/><feImage/><feMerge/><feMergeNode/><feMorphology/><feOffset/><fePointLight/><feSpecularLighting/><feSpotLight/><feTile/><feTurbulence/><filter/><font/><font-face/><font-face-format/><font-face-name/><font-face-src/><font-face-uri/><foreignObject/><g> </g><glyph/><glyphRef/><handler/><hkern/><iframe src="" frameborder=0 /> <image/><line> </line><linearGradient/><listener/><marker/><mask/><metadata/><missing-glyph/><mpath/><path> </path><pattern/><polygon> </polygon><polyline> </polyline><prefetch/><radialGradient/><rect> </rect><set/><solidcolor/><stop/><svg> </svg><switch> </switch><symbol> </symbol><tbreak/><text/><textarea/><textPath/><title/><tref/><tspan> </tspan><unknown/><use> </use><video src="" /> <view/></svg>

View File

@ -0,0 +1,3 @@
{
"collapseWhitespaces": "smart"
}

View File

@ -0,0 +1,2 @@
<!doctype html>
<span>test</span> <svg> <text x="0" y="150" class="small">Мой</text> </svg> <span>a</span>

View File

@ -0,0 +1 @@
<!doctype html><span>test</span> <svg><text x=0 y=150 class=small>Мой</text></svg><span>a</span>

View File

@ -1 +1 @@
<!doctype html><html lang=en><title>Document</title><div><span>test</span> <template><div>test</div></template> <template><div>test</div></template> <span>test</span></div><div><span>test</span><template><div>test</div></template> <template><div>test</div></template><span>test</span></div><div><span>test</span> <template><div>test</div></template><template><div>test</div></template><span>test</span></div><div><span>test</span><template><div>test</div></template><template><div>test</div></template> <span>test</span></div>
<!doctype html><html lang=en><title>Document</title><div><span>test</span><template><div>test</div></template><template><div>test</div></template> <span>test</span></div><div><span>test</span><template><div>test</div></template><template><div>test</div></template><span>test</span></div><div><span>test</span><template><div>test</div></template><template><div>test</div></template><span>test</span></div><div><span>test</span><template><div>test</div></template><template><div>test</div></template> <span>test</span></div>