Use lazy_static instead of phf due to phf incompatibility with latest Rust versions

This commit is contained in:
Wilson Lin 2020-07-03 17:32:09 +10:00
parent fba2dd965d
commit 2a010088fa
7 changed files with 418 additions and 315 deletions

View File

@ -16,7 +16,7 @@ include = ["/src/**/*", "/Cargo.toml", "/LICENSE", "/README.md"]
maintenance = { status = "actively-developed" }
[dependencies]
phf = { version = "0.8.0", features = ["macros"] }
lazy_static = "1.4.0"
[profile.release]
panic = 'abort'

View File

@ -48,12 +48,7 @@ const rsTagAttr = ({
defaultValue,
collapseAndTrim,
boolean,
}: AttrConfig) => `AttributeMinification {
boolean: ${boolean},
redundant_if_empty: ${redundantIfEmpty},
collapse_and_trim: ${collapseAndTrim},
default_value: ${defaultValue == undefined ? 'None' : `Some(b"${defaultValue}")`},
}`;
}: AttrConfig) => `AttributeMinification { boolean: ${boolean}, redundant_if_empty: ${redundantIfEmpty}, collapse_and_trim: ${collapseAndTrim}, default_value: ${defaultValue == undefined ? 'None' : `Some(b"${defaultValue}")`} }`;
const processReactTypeDeclarations = (source: SourceFile) => {
const nodes: Node[] = [source];
@ -127,7 +122,9 @@ const processReactTypeDeclarations = (source: SourceFile) => {
}
let code = `
use crate::spec::tag::ns::Namespace;
use lazy_static::lazy_static;
use std::collections::HashMap;
use crate::spec::tag::ns::Namespace;
pub struct AttributeMinification {
pub boolean: bool,
@ -138,29 +135,28 @@ pub struct AttributeMinification {
pub enum AttrMapEntry {
AllNamespaceElements(AttributeMinification),
SpecificNamespaceElements(phf::Map<&'static [u8], AttributeMinification>),
SpecificNamespaceElements(HashMap<&'static [u8], AttributeMinification>),
}
#[derive(Clone, Copy)]
pub struct ByNamespace {
// Make pub so this struct can be statically created in gen/attrs.rs.
pub html: Option<&'static AttrMapEntry>,
pub svg: Option<&'static AttrMapEntry>,
pub html: Option<AttrMapEntry>,
pub svg: Option<AttrMapEntry>,
}
impl ByNamespace {
fn get(&self, ns: Namespace) -> Option<&'static AttrMapEntry> {
fn get(&self, ns: Namespace) -> Option<&AttrMapEntry> {
match ns {
Namespace::Html => self.html,
Namespace::Svg => self.svg,
Namespace::Html => self.html.as_ref(),
Namespace::Svg => self.svg.as_ref(),
}
}
}
pub struct AttrMap(phf::Map<&'static [u8], ByNamespace>);
pub struct AttrMap(HashMap<&'static [u8], ByNamespace>);
impl AttrMap {
pub const fn new(map: phf::Map<&'static [u8], ByNamespace>) -> AttrMap {
pub const fn new(map: HashMap<&'static [u8], ByNamespace>) -> AttrMap {
AttrMap(map)
}
@ -174,35 +170,32 @@ impl AttrMap {
`;
for (const [attrName, namespaces] of attributes) {
let byNsCode = '';
byNsCode += `static ${attrName.toUpperCase()}_ATTR: ByNamespace = ByNamespace {\n`;
for (const ns of ['html', 'svg'] as const) {
byNsCode += `\t${ns}: `;
const tagsMap = namespaces.get(ns);
if (!tagsMap) {
byNsCode += 'None';
} else {
code += `
lazy_static! {
pub static ref ATTRS: AttrMap = {
let mut m = HashMap::<&'static [u8], ByNamespace>::new();
${[...attributes].map(([attr_name, namespaces]) => ` m.insert(b\"${attr_name}\", ByNamespace {
${(['html', 'svg'] as const).map(ns => ` ${ns}: ` + (() => {
const tagsMap = namespaces.get(ns);
if (!tagsMap) {
return 'None';
}
const globalAttr = tagsMap.get('*');
if (globalAttr) {
code += `static ${ns.toUpperCase()}_${attrName.toUpperCase()}_ATTR: &AttrMapEntry = &AttrMapEntry::AllNamespaceElements(${rsTagAttr(globalAttr)});\n\n`;
} else {
code += `static ${ns.toUpperCase()}_${attrName.toUpperCase()}_ATTR: &AttrMapEntry = &AttrMapEntry::SpecificNamespaceElements(phf::phf_map! {\n${
[...tagsMap].map(([tagName, tagAttr]) => `b\"${tagName}\" => ${rsTagAttr(tagAttr)}`).join(',\n')
}\n});\n\n`;
return `Some(AttrMapEntry::AllNamespaceElements(${rsTagAttr(globalAttr)}))`;
}
byNsCode += `Some(${ns.toUpperCase()}_${attrName.toUpperCase()}_ATTR)`;
}
byNsCode += ',\n';
}
byNsCode += '};\n\n';
code += byNsCode;
}
code += 'pub static ATTRS: AttrMap = AttrMap::new(phf::phf_map! {\n';
for (const attr_name of attributes.keys()) {
code += `\tb\"${attr_name}\" => ${attr_name.toUpperCase()}_ATTR,\n`;
}
code += '});\n\n';
return `Some({
let mut m = HashMap::<&'static [u8], AttributeMinification>::new();
${[...tagsMap].map(([tagName, tagAttr]) => ` m.insert(b\"${tagName}\", ${rsTagAttr(tagAttr)});`).join('\n')}
AttrMapEntry::SpecificNamespaceElements(m)
})`;
})() + ',').join('\n')}
});
`).join('')}
AttrMap::new(m)
};
}`;
return code;
};

View File

@ -1,4 +1,5 @@
use phf::{Map, phf_map, phf_set, Set};
use lazy_static::lazy_static;
use std::collections::{HashSet, HashMap};
// Rules sourced from https://html.spec.whatwg.org/multipage/syntax.html#syntax-tag-omission.
// TODO html, head, body
@ -10,12 +11,12 @@ pub enum ClosingTagOmissionRuleIfLast {
// Closing tag can never be omitted if it's the last node of its parent's children.
Never,
// Closing tag can be omitted if it's the last node of its parent's children and the parent tag name is not one of these.
ParentIsNot(Set<&'static [u8]>),
ParentIsNot(HashSet<&'static [u8]>),
}
pub struct ClosingTagOmissionRule {
// Closing tag can be omitted if immediately followed by an element node with one of these tag names.
followed_by: Set<&'static [u8]>,
followed_by: HashSet<&'static [u8]>,
// Closing tag can be omitted if it's the last node of its parent's children.
is_last: ClosingTagOmissionRuleIfLast,
}
@ -37,128 +38,218 @@ impl ClosingTagOmissionRule {
}
}
static LI_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"li"),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
lazy_static! {
static ref LI_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"li");
s
},
is_last: ClosingTagOmissionRuleIfLast::Always,
};
}
static DT_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"dt", b"dd"),
is_last: ClosingTagOmissionRuleIfLast::Never,
};
lazy_static! {
static ref DT_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"dt");
s.insert(b"dd");
s
},
is_last: ClosingTagOmissionRuleIfLast::Never,
};
}
static DD_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"dd", b"dt"),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
lazy_static! {
static ref DD_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"dd");
s.insert(b"dt");
s
},
is_last: ClosingTagOmissionRuleIfLast::Always,
};
}
static P_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(
b"address",
b"article",
b"aside",
b"blockquote",
b"details",
b"div",
b"dl",
b"fieldset",
b"figcaption",
b"figure",
b"footer",
b"form",
b"h1",
b"h2",
b"h3",
b"h4",
b"h5",
b"h6",
b"header",
b"hgroup",
b"hr",
b"main",
b"menu",
b"nav",
b"ol",
b"p",
b"pre",
b"section",
b"table",
b"ul",
),
is_last: ClosingTagOmissionRuleIfLast::ParentIsNot(phf_set!(
b"a",
b"audio",
b"del",
b"ins",
b"map",
b"noscript",
b"video",
)),
};
lazy_static! {
static ref P_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = {
let mut followed_by = HashSet::<&'static [u8]>::new();
followed_by.insert(b"address");
followed_by.insert(b"article");
followed_by.insert(b"aside");
followed_by.insert(b"blockquote");
followed_by.insert(b"details");
followed_by.insert(b"div");
followed_by.insert(b"dl");
followed_by.insert(b"fieldset");
followed_by.insert(b"figcaption");
followed_by.insert(b"figure");
followed_by.insert(b"footer");
followed_by.insert(b"form");
followed_by.insert(b"h1");
followed_by.insert(b"h2");
followed_by.insert(b"h3");
followed_by.insert(b"h4");
followed_by.insert(b"h5");
followed_by.insert(b"h6");
followed_by.insert(b"header");
followed_by.insert(b"hgroup");
followed_by.insert(b"hr");
followed_by.insert(b"main");
followed_by.insert(b"menu");
followed_by.insert(b"nav");
followed_by.insert(b"ol");
followed_by.insert(b"p");
followed_by.insert(b"pre");
followed_by.insert(b"section");
followed_by.insert(b"table");
followed_by.insert(b"ul");
static RT_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"rt", b"rp"),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
let mut is_last_tags = HashSet::<&'static [u8]>::new();
is_last_tags.insert(b"a");
is_last_tags.insert(b"audio");
is_last_tags.insert(b"del");
is_last_tags.insert(b"ins");
is_last_tags.insert(b"map");
is_last_tags.insert(b"noscript");
is_last_tags.insert(b"video");
static RP_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"rt", b"rp"),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
ClosingTagOmissionRule { followed_by, is_last: ClosingTagOmissionRuleIfLast::ParentIsNot(is_last_tags) }
};
}
static OPTGROUP_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"optgroup"),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
lazy_static! {
static ref RT_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"rt");
s.insert(b"rp");
s
},
is_last: ClosingTagOmissionRuleIfLast::Always,
};
}
static OPTION_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"option", b"optgroup"),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
lazy_static! {
static ref RP_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"rt");
s.insert(b"rp");
s
},
is_last: ClosingTagOmissionRuleIfLast::Always,
};
}
static THEAD_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"tbody", b"tfoot"),
is_last: ClosingTagOmissionRuleIfLast::Never,
};
lazy_static! {
static ref OPTGROUP_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"optgroup");
s
},
is_last: ClosingTagOmissionRuleIfLast::Always,
};
}
static TBODY_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"tbody", b"tfoot"),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
lazy_static! {
static ref OPTION_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"option");
s.insert(b"optgroup");
s
},
is_last: ClosingTagOmissionRuleIfLast::Always,
};
}
static TFOOT_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
lazy_static! {
static ref THEAD_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"tbody");
s.insert(b"tfoot");
s
},
is_last: ClosingTagOmissionRuleIfLast::Never,
};
}
static TR_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"tr"),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
lazy_static! {
static ref TBODY_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"tbody");
s.insert(b"tfoot");
s
},
is_last: ClosingTagOmissionRuleIfLast::Always,
};
}
static TD_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"td", b"th"),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
lazy_static! {
static ref TFOOT_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: HashSet::<&'static [u8]>::new(),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
}
static TH_CLOSING_TAG_OMISSION_RULE: &ClosingTagOmissionRule = &ClosingTagOmissionRule {
followed_by: phf_set!(b"td", b"th"),
is_last: ClosingTagOmissionRuleIfLast::Always,
};
lazy_static! {
static ref TR_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"tr");
s
},
is_last: ClosingTagOmissionRuleIfLast::Always,
};
}
pub static CLOSING_TAG_OMISSION_RULES: Map<&'static [u8], &ClosingTagOmissionRule> = phf_map! {
b"li" => LI_CLOSING_TAG_OMISSION_RULE,
b"dt" => DT_CLOSING_TAG_OMISSION_RULE,
b"dd" => DD_CLOSING_TAG_OMISSION_RULE,
b"p" => P_CLOSING_TAG_OMISSION_RULE,
b"rt" => RT_CLOSING_TAG_OMISSION_RULE,
b"rp" => RP_CLOSING_TAG_OMISSION_RULE,
b"optgroup" => OPTGROUP_CLOSING_TAG_OMISSION_RULE,
b"option" => OPTION_CLOSING_TAG_OMISSION_RULE,
b"thead" => THEAD_CLOSING_TAG_OMISSION_RULE,
b"tbody" => TBODY_CLOSING_TAG_OMISSION_RULE,
b"tfoot" => TFOOT_CLOSING_TAG_OMISSION_RULE,
b"tr" => TR_CLOSING_TAG_OMISSION_RULE,
b"td" => TD_CLOSING_TAG_OMISSION_RULE,
b"th" => TH_CLOSING_TAG_OMISSION_RULE,
};
lazy_static! {
static ref TD_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"td");
s.insert(b"th");
s
},
is_last: ClosingTagOmissionRuleIfLast::Always,
};
}
lazy_static! {
static ref TH_CLOSING_TAG_OMISSION_RULE: ClosingTagOmissionRule = ClosingTagOmissionRule {
followed_by: {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"td");
s.insert(b"th");
s
},
is_last: ClosingTagOmissionRuleIfLast::Always,
};
}
lazy_static! {
pub static ref CLOSING_TAG_OMISSION_RULES: HashMap<&'static [u8], &'static ClosingTagOmissionRule> = {
let mut m = HashMap::<&'static [u8], &'static ClosingTagOmissionRule>::new();
m.insert(b"li", &LI_CLOSING_TAG_OMISSION_RULE);
m.insert(b"dt", &DT_CLOSING_TAG_OMISSION_RULE);
m.insert(b"dd", &DD_CLOSING_TAG_OMISSION_RULE);
m.insert(b"p", &P_CLOSING_TAG_OMISSION_RULE);
m.insert(b"rt", &RT_CLOSING_TAG_OMISSION_RULE);
m.insert(b"rp", &RP_CLOSING_TAG_OMISSION_RULE);
m.insert(b"optgroup", &OPTGROUP_CLOSING_TAG_OMISSION_RULE);
m.insert(b"option", &OPTION_CLOSING_TAG_OMISSION_RULE);
m.insert(b"thead", &THEAD_CLOSING_TAG_OMISSION_RULE);
m.insert(b"tbody", &TBODY_CLOSING_TAG_OMISSION_RULE);
m.insert(b"tfoot", &TFOOT_CLOSING_TAG_OMISSION_RULE);
m.insert(b"tr", &TR_CLOSING_TAG_OMISSION_RULE);
m.insert(b"td", &TD_CLOSING_TAG_OMISSION_RULE);
m.insert(b"th", &TH_CLOSING_TAG_OMISSION_RULE);
m
};
}

View File

@ -1,19 +1,24 @@
use phf::{phf_set, Set};
use lazy_static::lazy_static;
use std::collections::HashSet;
pub static VOID_TAGS: Set<&'static [u8]> = phf_set! {
b"area",
b"base",
b"br",
b"col",
b"embed",
b"hr",
b"img",
b"input",
b"keygen",
b"link",
b"meta",
b"param",
b"source",
b"track",
b"wbr",
};
lazy_static! {
pub static ref VOID_TAGS: HashSet<&'static [u8]> = {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"area");
s.insert(b"base");
s.insert(b"br");
s.insert(b"col");
s.insert(b"embed");
s.insert(b"hr");
s.insert(b"img");
s.insert(b"input");
s.insert(b"keygen");
s.insert(b"link");
s.insert(b"meta");
s.insert(b"param");
s.insert(b"source");
s.insert(b"track");
s.insert(b"wbr");
s
};
}

View File

@ -1,4 +1,5 @@
use phf::{Map, phf_map};
use lazy_static::lazy_static;
use std::collections::HashMap;
pub struct WhitespaceMinification {
pub collapse: bool,
@ -48,116 +49,121 @@ static DEFAULT: &WhitespaceMinification = &WhitespaceMinification {
trim: false,
};
static TAG_WHITESPACE_MINIFICATION: Map<&'static [u8], &'static WhitespaceMinification> = phf_map! {
// Content tags.
b"address" => CONTENT,
b"audio" => CONTENT,
b"button" => CONTENT,
b"canvas" => CONTENT,
b"caption" => CONTENT,
b"figcaption" => CONTENT,
b"h1" => CONTENT,
b"h2" => CONTENT,
b"h3" => CONTENT,
b"h4" => CONTENT,
b"h5" => CONTENT,
b"h6" => CONTENT,
b"legend" => CONTENT,
b"meter" => CONTENT,
b"object" => CONTENT,
b"option" => CONTENT,
b"p" => CONTENT,
b"summary" => CONTENT,
b"textarea" => CONTENT,
b"video" => CONTENT,
lazy_static! {
static ref TAG_WHITESPACE_MINIFICATION: HashMap<&'static [u8], &'static WhitespaceMinification> = {
let mut m = HashMap::<&'static [u8], &'static WhitespaceMinification>::new();
// Content tags.
m.insert(b"address", CONTENT);
m.insert(b"audio", CONTENT);
m.insert(b"button", CONTENT);
m.insert(b"canvas", CONTENT);
m.insert(b"caption", CONTENT);
m.insert(b"figcaption", CONTENT);
m.insert(b"h1", CONTENT);
m.insert(b"h2", CONTENT);
m.insert(b"h3", CONTENT);
m.insert(b"h4", CONTENT);
m.insert(b"h5", CONTENT);
m.insert(b"h6", CONTENT);
m.insert(b"legend", CONTENT);
m.insert(b"meter", CONTENT);
m.insert(b"object", CONTENT);
m.insert(b"option", CONTENT);
m.insert(b"p", CONTENT);
m.insert(b"summary", CONTENT);
m.insert(b"textarea", CONTENT);
m.insert(b"video", CONTENT);
// Content-first tags.
b"dd" => CONTENT_FIRST,
b"details" => CONTENT_FIRST,
b"dt" => CONTENT_FIRST,
b"iframe" => CONTENT_FIRST,
b"label" => CONTENT_FIRST,
b"li" => CONTENT_FIRST,
b"noscript" => CONTENT_FIRST,
b"output" => CONTENT_FIRST,
b"progress" => CONTENT_FIRST,
b"slot" => CONTENT_FIRST,
b"td" => CONTENT_FIRST,
b"template" => CONTENT_FIRST,
b"th" => CONTENT_FIRST,
// Content-first tags.
m.insert(b"dd", CONTENT_FIRST);
m.insert(b"details", CONTENT_FIRST);
m.insert(b"dt", CONTENT_FIRST);
m.insert(b"iframe", CONTENT_FIRST);
m.insert(b"label", CONTENT_FIRST);
m.insert(b"li", CONTENT_FIRST);
m.insert(b"noscript", CONTENT_FIRST);
m.insert(b"output", CONTENT_FIRST);
m.insert(b"progress", CONTENT_FIRST);
m.insert(b"slot", CONTENT_FIRST);
m.insert(b"td", CONTENT_FIRST);
m.insert(b"template", CONTENT_FIRST);
m.insert(b"th", CONTENT_FIRST);
// Formatting tags.
// Sourced from https://developer.mozilla.org/en-US/docs/Web/HTML/Element#Inline_text_semantics.
// Differences to tags listed in table at above URL: -br, +del, +ins.
b"a" => FORMATTING,
b"abbr" => FORMATTING,
b"b" => FORMATTING,
b"bdi" => FORMATTING,
b"bdo" => FORMATTING,
b"cite" => FORMATTING,
b"data" => FORMATTING,
b"del" => FORMATTING,
b"dfn" => FORMATTING,
b"em" => FORMATTING,
b"i" => FORMATTING,
b"ins" => FORMATTING,
b"kbd" => FORMATTING,
b"mark" => FORMATTING,
b"q" => FORMATTING,
b"rp" => FORMATTING,
b"rt" => FORMATTING,
b"rtc" => FORMATTING,
b"ruby" => FORMATTING,
b"s" => FORMATTING,
b"samp" => FORMATTING,
b"small" => FORMATTING,
b"span" => FORMATTING,
b"strong" => FORMATTING,
b"sub" => FORMATTING,
b"sup" => FORMATTING,
b"time" => FORMATTING,
b"u" => FORMATTING,
b"var" => FORMATTING,
b"wbr" => FORMATTING,
// Formatting tags.
// Sourced from https://developer.mozilla.org/en-US/docs/Web/HTML/Element#Inline_text_semantics.
// Differences to tags listed in table at above URL: -br, +del, +ins.
m.insert(b"a", FORMATTING);
m.insert(b"abbr", FORMATTING);
m.insert(b"b", FORMATTING);
m.insert(b"bdi", FORMATTING);
m.insert(b"bdo", FORMATTING);
m.insert(b"cite", FORMATTING);
m.insert(b"data", FORMATTING);
m.insert(b"del", FORMATTING);
m.insert(b"dfn", FORMATTING);
m.insert(b"em", FORMATTING);
m.insert(b"i", FORMATTING);
m.insert(b"ins", FORMATTING);
m.insert(b"kbd", FORMATTING);
m.insert(b"mark", FORMATTING);
m.insert(b"q", FORMATTING);
m.insert(b"rp", FORMATTING);
m.insert(b"rt", FORMATTING);
m.insert(b"rtc", FORMATTING);
m.insert(b"ruby", FORMATTING);
m.insert(b"s", FORMATTING);
m.insert(b"samp", FORMATTING);
m.insert(b"small", FORMATTING);
m.insert(b"span", FORMATTING);
m.insert(b"strong", FORMATTING);
m.insert(b"sub", FORMATTING);
m.insert(b"sup", FORMATTING);
m.insert(b"time", FORMATTING);
m.insert(b"u", FORMATTING);
m.insert(b"var", FORMATTING);
m.insert(b"wbr", FORMATTING);
// Layout tags.
b"article" => LAYOUT,
b"aside" => LAYOUT,
b"blockquote" => LAYOUT,
b"body" => LAYOUT,
b"colgroup" => LAYOUT,
b"datalist" => LAYOUT,
b"dialog" => LAYOUT,
b"div" => LAYOUT,
b"dl" => LAYOUT,
b"fieldset" => LAYOUT,
b"figure" => LAYOUT,
b"footer" => LAYOUT,
b"form" => LAYOUT,
b"head" => LAYOUT,
b"header" => LAYOUT,
b"hgroup" => LAYOUT,
b"html" => LAYOUT,
b"main" => LAYOUT,
b"map" => LAYOUT,
b"menu" => LAYOUT,
b"nav" => LAYOUT,
b"ol" => LAYOUT,
b"optgroup" => LAYOUT,
b"picture" => LAYOUT,
b"section" => LAYOUT,
b"select" => LAYOUT,
b"table" => LAYOUT,
b"tbody" => LAYOUT,
b"tfoot" => LAYOUT,
b"thead" => LAYOUT,
b"tr" => LAYOUT,
b"ul" => LAYOUT,
// Layout tags.
m.insert(b"article", LAYOUT);
m.insert(b"aside", LAYOUT);
m.insert(b"blockquote", LAYOUT);
m.insert(b"body", LAYOUT);
m.insert(b"colgroup", LAYOUT);
m.insert(b"datalist", LAYOUT);
m.insert(b"dialog", LAYOUT);
m.insert(b"div", LAYOUT);
m.insert(b"dl", LAYOUT);
m.insert(b"fieldset", LAYOUT);
m.insert(b"figure", LAYOUT);
m.insert(b"footer", LAYOUT);
m.insert(b"form", LAYOUT);
m.insert(b"head", LAYOUT);
m.insert(b"header", LAYOUT);
m.insert(b"hgroup", LAYOUT);
m.insert(b"html", LAYOUT);
m.insert(b"main", LAYOUT);
m.insert(b"map", LAYOUT);
m.insert(b"menu", LAYOUT);
m.insert(b"nav", LAYOUT);
m.insert(b"ol", LAYOUT);
m.insert(b"optgroup", LAYOUT);
m.insert(b"picture", LAYOUT);
m.insert(b"section", LAYOUT);
m.insert(b"select", LAYOUT);
m.insert(b"table", LAYOUT);
m.insert(b"tbody", LAYOUT);
m.insert(b"tfoot", LAYOUT);
m.insert(b"thead", LAYOUT);
m.insert(b"tr", LAYOUT);
m.insert(b"ul", LAYOUT);
// Whitespace-sensitive tags.
b"code" => WHITESPACE_SENSITIVE,
b"pre" => WHITESPACE_SENSITIVE,
};
// Whitespace-sensitive tags.
m.insert(b"code", WHITESPACE_SENSITIVE);
m.insert(b"pre", WHITESPACE_SENSITIVE);
m
};
}
pub fn get_whitespace_minification_for_tag(tag_name: Option<&[u8]>) -> &'static WhitespaceMinification {
match tag_name {

View File

@ -1,5 +1,5 @@
use phf::{Map, phf_map};
use lazy_static::lazy_static;
use std::collections::HashMap;
use crate::err::ProcessingResult;
use crate::proc::checkpoint::Checkpoint;
use crate::proc::MatchAction::*;
@ -40,17 +40,21 @@ fn entity_requires_semicolon(next_char: u8) -> bool {
}
// See comment in `process_attr_value` for full description of why these intentionally do not have semicolons.
static ENCODED: Map<u8, &'static [u8]> = phf_map! {
b'\'' => b"&#39",
b'"' => b"&#34",
b'>' => b"&gt",
// Whitespace characters as defined by spec in crate::spec::codepoint::is_whitespace.
b'\x09' => b"&#9",
b'\x0a' => b"&#10",
b'\x0c' => b"&#12",
b'\x0d' => b"&#13",
b'\x20' => b"&#32",
};
lazy_static! {
static ref ENCODED: HashMap<u8, &'static [u8]> = {
let mut m = HashMap::<u8, &'static [u8]>::new();
m.insert(b'\'', b"&#39");
m.insert(b'"', b"&#34");
m.insert(b'>', b"&gt");
// Whitespace characters as defined by spec in crate::spec::codepoint::is_whitespace.
m.insert(b'\x09', b"&#9");
m.insert(b'\x0a', b"&#10");
m.insert(b'\x0c', b"&#12");
m.insert(b'\x0d', b"&#13");
m.insert(b'\x20', b"&#32");
m
};
}
#[derive(Clone, Copy)]
enum CharType {

View File

@ -1,5 +1,5 @@
use phf::{phf_set, Set};
use lazy_static::lazy_static;
use std::collections::HashSet;
use crate::err::{ErrorType, ProcessingResult};
use crate::proc::checkpoint::Checkpoint;
use crate::proc::MatchAction::*;
@ -16,24 +16,28 @@ use crate::unit::style::process_style;
use crate::gen::attrs::{ATTRS, AttributeMinification};
use crate::spec::tag::ns::Namespace;
pub static JAVASCRIPT_MIME_TYPES: Set<&'static [u8]> = phf_set! {
b"application/ecmascript",
b"application/javascript",
b"application/x-ecmascript",
b"application/x-javascript",
b"text/ecmascript",
b"text/javascript",
b"text/javascript1.0",
b"text/javascript1.1",
b"text/javascript1.2",
b"text/javascript1.3",
b"text/javascript1.4",
b"text/javascript1.5",
b"text/jscript",
b"text/livescript",
b"text/x-ecmascript",
b"text/x-javascript",
};
lazy_static! {
pub static ref JAVASCRIPT_MIME_TYPES: HashSet<&'static [u8]> = {
let mut s = HashSet::<&'static [u8]>::new();
s.insert(b"application/ecmascript");
s.insert(b"application/javascript");
s.insert(b"application/x-ecmascript");
s.insert(b"application/x-javascript");
s.insert(b"text/ecmascript");
s.insert(b"text/javascript");
s.insert(b"text/javascript1.0");
s.insert(b"text/javascript1.1");
s.insert(b"text/javascript1.2");
s.insert(b"text/javascript1.3");
s.insert(b"text/javascript1.4");
s.insert(b"text/javascript1.5");
s.insert(b"text/jscript");
s.insert(b"text/livescript");
s.insert(b"text/x-ecmascript");
s.insert(b"text/x-javascript");
s
};
}
// Tag names may only use ASCII alphanumerics. However, some people also use `:` and `-`.
// See https://html.spec.whatwg.org/multipage/syntax.html#syntax-tag-name for spec.