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 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 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 4463x 4463x 4463x 1x 1x 4461x 4461x 4461x 4461x 4461x 4461x 4461x 4461x 4461x 4461x 4463x 4461x 4461x 4461x 4461x 4461x 4461x 4461x 4463x 156x 156x 156x 2x 2x 156x 156x 78x 78x 78x 78x 156x 156x 6x 6x 6x 6x 6x 1x 1x 5x 5x 5x 5x 5x 156x 4460x 4460x 4460x 4460x 4460x 4460x 4460x 4460x 4460x 4460x 4460x 4460x | /** @import { Program } from 'estree' */ /** @import { AST, Directive } from '#compiler' */ /** @import { Parser } from '../index.js' */ import * as acorn from '../acorn.js'; import { regex_not_newline_characters } from '../../patterns.js'; import * as e from '../../../errors.js'; import * as w from '../../../warnings.js'; import { is_text_attribute } from '../../../utils/ast.js'; const regex_closing_script_tag = /<\/script\s*>/; const regex_starts_with_closing_script_tag = /^<\/script\s*>/; const RESERVED_ATTRIBUTES = ['server', 'client', 'worker', 'test', 'default']; const ALLOWED_ATTRIBUTES = ['context', 'generics', 'lang', 'module']; /** * @param {Parser} parser * @param {number} start * @param {Array<AST.Attribute | AST.SpreadAttribute | Directive>} attributes * @returns {AST.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) { e.element_unclosed(parser.template.length, 'script'); } const source = parser.template.slice(0, script_start).replace(regex_not_newline_characters, ' ') + data; parser.read(regex_starts_with_closing_script_tag); /** @type {Program} */ let ast; try { ast = acorn.parse(source, parser.ts); } catch (err) { parser.acorn_error(err); } // TODO is this necessary? ast.start = script_start; /** @type {'default' | 'module'} */ let context = 'default'; for (const attribute of /** @type {AST.Attribute[]} */ (attributes)) { if (RESERVED_ATTRIBUTES.includes(attribute.name)) { e.script_reserved_attribute(attribute, attribute.name); } if (!ALLOWED_ATTRIBUTES.includes(attribute.name)) { w.script_unknown_attribute(attribute); } if (attribute.name === 'module') { if (attribute.value !== true) { // Deliberately a generic code to future-proof for potential other attributes e.script_invalid_attribute_value(attribute, attribute.name); } context = 'module'; } if (attribute.name === 'context') { if (attribute.value === true || !is_text_attribute(attribute)) { e.script_invalid_context(attribute); } const value = attribute.value[0].data; if (value !== 'module') { e.script_invalid_context(attribute); } w.script_context_deprecated(attribute); context = 'module'; } } return { type: 'Script', start, end: parser.index, context, content: ast, parent: null, // @ts-ignore attributes }; } |