File size: 1,840 Bytes
bc20498 |
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 |
import * as acorn from '../acorn.js';
import parser_errors from '../errors.js';
import { regex_not_newline_characters } from '../../utils/patterns.js';
const regex_closing_script_tag = /<\/script\s*>/;
const regex_starts_with_closing_script_tag = /^<\/script\s*>/;
/**
* @param {import('../index.js').Parser} parser
* @param {any[]} attributes
* @param {number} start
* @returns {string}
*/
function get_context(parser, attributes, start) {
const context = attributes.find((attribute) => attribute.name === 'context');
if (!context) return 'default';
if (context.value.length !== 1 || context.value[0].type !== 'Text') {
parser.error(parser_errors.invalid_script_context_attribute, start);
}
const value = context.value[0].data;
if (value !== 'module') {
parser.error(parser_errors.invalid_script_context_value, context.start);
}
return value;
}
/**
* @param {import('../index.js').Parser} parser
* @param {number} start
* @param {import('estree').Node[]} attributes
* @returns {import('../../interfaces.js').Script}
*/
export default function read_script(parser, start, attributes) {
const script_start = parser.index;
const data = parser.read_until(regex_closing_script_tag, parser_errors.unclosed_script);
if (parser.index >= parser.template.length) {
parser.error(parser_errors.unclosed_script);
}
const source =
parser.template.slice(0, script_start).replace(regex_not_newline_characters, ' ') + data;
parser.read(regex_starts_with_closing_script_tag);
/**
* @type {import('estree').Program}
*/
let ast;
try {
ast = acorn.parse(source);
} catch (err) {
parser.acorn_error(err);
}
// TODO is this necessary?
/** @type {any} */ (ast).start = script_start;
return {
type: 'Script',
start,
end: parser.index,
context: get_context(parser, attributes, start),
content: ast
};
}
|