2020-11-13 06:15:51 -05:00
|
|
|
import htmlData from '@wzlin/html-data';
|
|
|
|
import {writeFileSync} from 'fs';
|
2020-06-19 03:16:23 -04:00
|
|
|
import {join} from 'path';
|
2020-11-13 06:15:51 -05:00
|
|
|
import {RUST_OUT_DIR} from './_common';
|
2020-06-19 03:16:23 -04:00
|
|
|
|
|
|
|
const rsTagAttr = ({
|
|
|
|
redundantIfEmpty,
|
|
|
|
defaultValue,
|
|
|
|
collapseAndTrim,
|
|
|
|
boolean,
|
2020-11-13 06:15:51 -05:00
|
|
|
}: {
|
|
|
|
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}")`} }`;
|
2020-06-19 03:16:23 -04:00
|
|
|
|
|
|
|
|
2020-11-13 06:15:51 -05:00
|
|
|
let code = `
|
2020-07-03 03:32:09 -04:00
|
|
|
use lazy_static::lazy_static;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use crate::spec::tag::ns::Namespace;
|
2020-06-19 03:16:23 -04:00
|
|
|
|
|
|
|
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),
|
2020-07-03 03:32:09 -04:00
|
|
|
SpecificNamespaceElements(HashMap<&'static [u8], AttributeMinification>),
|
2020-06-19 03:16:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ByNamespace {
|
|
|
|
// Make pub so this struct can be statically created in gen/attrs.rs.
|
2020-07-03 03:32:09 -04:00
|
|
|
pub html: Option<AttrMapEntry>,
|
|
|
|
pub svg: Option<AttrMapEntry>,
|
2020-06-19 03:16:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ByNamespace {
|
2020-07-27 04:08:53 -04:00
|
|
|
#[inline(always)]
|
2020-07-03 03:32:09 -04:00
|
|
|
fn get(&self, ns: Namespace) -> Option<&AttrMapEntry> {
|
2020-06-19 03:16:23 -04:00
|
|
|
match ns {
|
2020-07-03 03:32:09 -04:00
|
|
|
Namespace::Html => self.html.as_ref(),
|
|
|
|
Namespace::Svg => self.svg.as_ref(),
|
2020-06-19 03:16:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-03 03:32:09 -04:00
|
|
|
pub struct AttrMap(HashMap<&'static [u8], ByNamespace>);
|
2020-06-19 03:16:23 -04:00
|
|
|
|
|
|
|
impl AttrMap {
|
2020-07-27 04:08:53 -04:00
|
|
|
#[inline(always)]
|
2020-07-03 03:32:09 -04:00
|
|
|
pub const fn new(map: HashMap<&'static [u8], ByNamespace>) -> AttrMap {
|
2020-06-19 03:16:23 -04:00
|
|
|
AttrMap(map)
|
|
|
|
}
|
|
|
|
|
2020-07-27 04:08:53 -04:00
|
|
|
#[inline(always)]
|
2020-06-19 03:16:23 -04:00
|
|
|
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),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
`;
|
|
|
|
|
2020-11-13 06:15:51 -05:00
|
|
|
code += `
|
2020-07-03 03:32:09 -04:00
|
|
|
lazy_static! {
|
|
|
|
pub static ref ATTRS: AttrMap = {
|
|
|
|
let mut m = HashMap::<&'static [u8], ByNamespace>::new();
|
2020-11-13 06:15:51 -05:00
|
|
|
${[...Object.entries(htmlData.attributes)].map(([attr_name, namespaces]) => ` m.insert(b\"${attr_name}\", ByNamespace {
|
2020-07-03 03:32:09 -04:00
|
|
|
${(['html', 'svg'] as const).map(ns => ` ${ns}: ` + (() => {
|
2020-11-13 06:15:51 -05:00
|
|
|
const tagsMap = namespaces[ns];
|
|
|
|
if (!tagsMap) {
|
|
|
|
return 'None';
|
|
|
|
}
|
|
|
|
const globalAttr = tagsMap['*'];
|
|
|
|
if (globalAttr) {
|
|
|
|
return `Some(AttrMapEntry::AllNamespaceElements(${rsTagAttr(globalAttr)}))`;
|
|
|
|
}
|
2021-01-05 23:59:40 -05:00
|
|
|
const entries = Object.entries(tagsMap);
|
2020-11-13 06:15:51 -05:00
|
|
|
return `Some({
|
2021-01-05 23:59:40 -05:00
|
|
|
let ${entries.length ? 'mut' : ''} m = HashMap::<&'static [u8], AttributeMinification>::new();
|
|
|
|
${entries.map(([tagName, tagAttr]) => ` m.insert(b\"${tagName}\", ${rsTagAttr(tagAttr)});`).join('\n')}
|
2020-07-03 03:32:09 -04:00
|
|
|
AttrMapEntry::SpecificNamespaceElements(m)
|
|
|
|
})`;
|
2020-11-13 06:15:51 -05:00
|
|
|
})() + ',').join('\n')}
|
2020-07-03 03:32:09 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
`).join('')}
|
|
|
|
AttrMap::new(m)
|
|
|
|
};
|
|
|
|
}`;
|
2020-06-19 03:16:23 -04:00
|
|
|
|
2020-11-13 06:15:51 -05:00
|
|
|
writeFileSync(join(RUST_OUT_DIR, 'attrs.rs'), code);
|