All files / src/compiler/phases/1-parse/read script.js

94.36% Statements 67/71
85.71% Branches 12/14
100% Functions 2/2
94.11% Lines 64/68

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 692x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 3877x 3877x 3877x 3877x 3877x 66x 3877x     66x 66x 66x 3630x 1x 1x 65x 65x 65x 2x 2x 2x 2x 2x 2x 2x 2x 3879x 3879x 3879x 1x 1x 3877x 3877x 3877x 3877x 3877x 3877x 3877x 3877x 3877x 3877x 3879x     3877x 3877x 3877x 3877x 3877x 3877x 3877x 3877x 3877x 3877x 3877x 3877x 3877x  
import * as acorn from '../acorn.js';
import { regex_not_newline_characters } from '../../patterns.js';
import { error } from '../../../errors.js';
 
const regex_closing_script_tag = /<\/script\s*>/;
const regex_starts_with_closing_script_tag = /^<\/script\s*>/;
 
/**
 * @param {any[]} attributes
 * @returns {string}
 */
function get_context(attributes) {
	const context = attributes.find(
		/** @param {any} attribute */ (attribute) => attribute.name === 'context'
	);
	if (!context) return 'default';
 
	if (context.value.length !== 1 || context.value[0].type !== 'Text') {
		error(context.start, 'invalid-script-context');
	}
 
	const value = context.value[0].data;
 
	if (value !== 'module') {
		error(context.start, 'invalid-script-context');
	}
 
	return value;
}
 
/**
 * @param {import('../index.js').Parser} parser
 * @param {number} start
 * @param {Array<import('#compiler').Attribute | import('#compiler').SpreadAttribute | import('#compiler').Directive>} attributes
 * @returns {import('#compiler').Script}
 */
export function read_script(parser, start, attributes) {
	const script_start = parser.index;
	const data = parser.read_until(regex_closing_script_tag);
	if (parser.index >= parser.template.length) {
		error(parser.template.length, 'unclosed-element', '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, parser.ts);
	} catch (err) {
		parser.acorn_error(err);
	}
 
	// TODO is this necessary?
	ast.start = script_start;
 
	return {
		type: 'Script',
		start,
		end: parser.index,
		context: get_context(attributes),
		content: ast,
		parent: null
	};
}