|
|
|
@ -9,6 +9,9 @@ import read_script from '../read/script';
|
|
|
|
import read_style from '../read/style';
|
|
|
|
import read_style from '../read/style';
|
|
|
|
import { closing_tag_omitted, decode_character_references } from '../utils/html';
|
|
|
|
import { closing_tag_omitted, decode_character_references } from '../utils/html';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// characters equivalent to using \s in regex
|
|
|
|
|
|
|
|
const whitespace_characters = ['\r', '\n', '\t', '\f', '\v', ' ', '\u00a0', '\u1680', '\u2000-', '\u200a', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000', '\ufeff'];
|
|
|
|
|
|
|
|
|
|
|
|
// eslint-disable-next-line no-useless-escape
|
|
|
|
// eslint-disable-next-line no-useless-escape
|
|
|
|
const valid_tag_name = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/;
|
|
|
|
const valid_tag_name = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/;
|
|
|
|
|
|
|
|
|
|
|
|
@ -77,6 +80,7 @@ export default function tag(parser: Parser) {
|
|
|
|
|
|
|
|
|
|
|
|
const name = read_tag_name(parser);
|
|
|
|
const name = read_tag_name(parser);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (meta_tags.has(name)) {
|
|
|
|
if (meta_tags.has(name)) {
|
|
|
|
const slug = meta_tags.get(name).toLowerCase();
|
|
|
|
const slug = meta_tags.get(name).toLowerCase();
|
|
|
|
if (is_closing_tag) {
|
|
|
|
if (is_closing_tag) {
|
|
|
|
@ -109,6 +113,7 @@ export default function tag(parser: Parser) {
|
|
|
|
: name === 'title' && parent_is_head(parser.stack) ? 'Title'
|
|
|
|
: name === 'title' && parent_is_head(parser.stack) ? 'Title'
|
|
|
|
: name === 'slot' && !parser.customElement ? 'Slot' : 'Element';
|
|
|
|
: name === 'slot' && !parser.customElement ? 'Slot' : 'Element';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const element: TemplateNode = {
|
|
|
|
const element: TemplateNode = {
|
|
|
|
start,
|
|
|
|
start,
|
|
|
|
end: null, // filled in later
|
|
|
|
end: null, // filled in later
|
|
|
|
@ -160,6 +165,7 @@ export default function tag(parser: Parser) {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const unique_names: Set<string> = new Set();
|
|
|
|
const unique_names: Set<string> = new Set();
|
|
|
|
|
|
|
|
|
|
|
|
let attribute;
|
|
|
|
let attribute;
|
|
|
|
@ -363,6 +369,7 @@ function read_attribute(parser: Parser, unique_names: Set<string>) {
|
|
|
|
parser.error(parser_errors.unexpected_token('='), parser.index);
|
|
|
|
parser.error(parser_errors.unexpected_token('='), parser.index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (type) {
|
|
|
|
if (type) {
|
|
|
|
const [directive_name, ...modifiers] = name.slice(colon_index + 1).split('|');
|
|
|
|
const [directive_name, ...modifiers] = name.slice(colon_index + 1).split('|');
|
|
|
|
|
|
|
|
|
|
|
|
@ -455,6 +462,7 @@ function get_directive_type(name: string): DirectiveType {
|
|
|
|
|
|
|
|
|
|
|
|
function read_attribute_value(parser: Parser) {
|
|
|
|
function read_attribute_value(parser: Parser) {
|
|
|
|
const quote_mark = parser.eat("'") ? "'" : parser.eat('"') ? '"' : null;
|
|
|
|
const quote_mark = parser.eat("'") ? "'" : parser.eat('"') ? '"' : null;
|
|
|
|
|
|
|
|
|
|
|
|
if (quote_mark && parser.eat(quote_mark)) {
|
|
|
|
if (quote_mark && parser.eat(quote_mark)) {
|
|
|
|
return [{
|
|
|
|
return [{
|
|
|
|
start: parser.index - 1,
|
|
|
|
start: parser.index - 1,
|
|
|
|
@ -465,15 +473,10 @@ function read_attribute_value(parser: Parser) {
|
|
|
|
}];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const regex = (
|
|
|
|
|
|
|
|
quote_mark === "'" ? /'/ :
|
|
|
|
|
|
|
|
quote_mark === '"' ? /"/ :
|
|
|
|
|
|
|
|
/(\/>|[\s"'=<>`])/
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let value;
|
|
|
|
let value;
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
value = read_sequence(parser, () => !!parser.match_regex(regex));
|
|
|
|
const characters = quote_mark ? [quote_mark] : [...whitespace_characters, '/>', '"', '"', '=', '<', '>', '`'];
|
|
|
|
|
|
|
|
value = read_sequence(parser, () => characters.some(c => parser.match(c)));
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
if (error.code === 'parse-error') {
|
|
|
|
if (error.code === 'parse-error') {
|
|
|
|
// if the attribute value didn't close + self-closing tag
|
|
|
|
// if the attribute value didn't close + self-closing tag
|
|
|
|
|