forked from wilsonzlin/minify-html
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathattrs.ts
More file actions
100 lines (86 loc) · 2.91 KB
/
attrs.ts
File metadata and controls
100 lines (86 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import htmlData from '@wzlin/html-data';
import {writeFileSync} from 'fs';
import {join} from 'path';
import {RUST_OUT_DIR} from './_common';
const rsTagAttr = ({
redundantIfEmpty,
defaultValue,
collapseAndTrim,
boolean,
}: {
boolean: boolean;
redundantIfEmpty: boolean;
collapseAndTrim: boolean;
defaultValue?: string;
}) => `AttributeMinification { boolean: ${boolean}, redundant_if_empty: ${redundantIfEmpty}, collapse_and_trim: ${collapseAndTrim}, default_value: ${defaultValue
== undefined ? 'None' : `Some(b"${defaultValue}")`} }`;
let code = `
use lazy_static::lazy_static;
use std::collections::HashMap;
use crate::spec::tag::ns::Namespace;
pub struct AttributeMinification {
pub boolean: bool,
pub redundant_if_empty: bool,
pub collapse_and_trim: bool,
pub default_value: Option<&'static [u8]>,
}
pub enum AttrMapEntry {
AllNamespaceElements(AttributeMinification),
SpecificNamespaceElements(HashMap<&'static [u8], AttributeMinification>),
}
pub struct ByNamespace {
// Make pub so this struct can be statically created in gen/attrs.rs.
pub html: Option<AttrMapEntry>,
pub svg: Option<AttrMapEntry>,
}
impl ByNamespace {
#[inline(always)]
fn get(&self, ns: Namespace) -> Option<&AttrMapEntry> {
match ns {
Namespace::Html => self.html.as_ref(),
Namespace::Svg => self.svg.as_ref(),
}
}
}
pub struct AttrMap(HashMap<&'static [u8], ByNamespace>);
impl AttrMap {
#[inline(always)]
pub const fn new(map: HashMap<&'static [u8], ByNamespace>) -> AttrMap {
AttrMap(map)
}
#[inline(always)]
pub fn get(&self, ns: Namespace, tag: &[u8], attr: &[u8]) -> Option<&AttributeMinification> {
self.0.get(attr).and_then(|namespaces| namespaces.get(ns)).and_then(|entry| match entry {
AttrMapEntry::AllNamespaceElements(min) => Some(min),
AttrMapEntry::SpecificNamespaceElements(map) => map.get(tag),
})
}
}
`;
code += `
lazy_static! {
pub static ref ATTRS: AttrMap = {
let mut m = HashMap::<&'static [u8], ByNamespace>::new();
${[...Object.entries(htmlData.attributes)].map(([attr_name, namespaces]) => ` m.insert(b\"${attr_name}\", ByNamespace {
${(['html', 'svg'] as const).map(ns => ` ${ns}: ` + (() => {
const tagsMap = namespaces[ns];
if (!tagsMap) {
return 'None';
}
const globalAttr = tagsMap['*'];
if (globalAttr) {
return `Some(AttrMapEntry::AllNamespaceElements(${rsTagAttr(globalAttr)}))`;
}
const entries = Object.entries(tagsMap);
return `Some({
let ${entries.length ? 'mut' : ''} m = HashMap::<&'static [u8], AttributeMinification>::new();
${entries.map(([tagName, tagAttr]) => ` m.insert(b\"${tagName}\", ${rsTagAttr(tagAttr)});`).join('\n')}
AttrMapEntry::SpecificNamespaceElements(m)
})`;
})() + ',').join('\n')}
});
`).join('')}
AttrMap::new(m)
};
}`;
writeFileSync(join(RUST_OUT_DIR, 'attrs.rs'), code);