1 | const IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';
|
2 | const KEYWORDS = [
|
3 | "as",
|
4 | "in",
|
5 | "of",
|
6 | "if",
|
7 | "for",
|
8 | "while",
|
9 | "finally",
|
10 | "var",
|
11 | "new",
|
12 | "function",
|
13 | "do",
|
14 | "return",
|
15 | "void",
|
16 | "else",
|
17 | "break",
|
18 | "catch",
|
19 | "instanceof",
|
20 | "with",
|
21 | "throw",
|
22 | "case",
|
23 | "default",
|
24 | "try",
|
25 | "switch",
|
26 | "continue",
|
27 | "typeof",
|
28 | "delete",
|
29 | "let",
|
30 | "yield",
|
31 | "const",
|
32 | "class",
|
33 |
|
34 |
|
35 |
|
36 | "debugger",
|
37 | "async",
|
38 | "await",
|
39 | "static",
|
40 | "import",
|
41 | "from",
|
42 | "export",
|
43 | "extends"
|
44 | ];
|
45 | const LITERALS = [
|
46 | "true",
|
47 | "false",
|
48 | "null",
|
49 | "undefined",
|
50 | "NaN",
|
51 | "Infinity"
|
52 | ];
|
53 |
|
54 |
|
55 | const TYPES = [
|
56 |
|
57 | "Object",
|
58 | "Function",
|
59 | "Boolean",
|
60 | "Symbol",
|
61 |
|
62 | "Math",
|
63 | "Date",
|
64 | "Number",
|
65 | "BigInt",
|
66 |
|
67 | "String",
|
68 | "RegExp",
|
69 |
|
70 | "Array",
|
71 | "Float32Array",
|
72 | "Float64Array",
|
73 | "Int8Array",
|
74 | "Uint8Array",
|
75 | "Uint8ClampedArray",
|
76 | "Int16Array",
|
77 | "Int32Array",
|
78 | "Uint16Array",
|
79 | "Uint32Array",
|
80 | "BigInt64Array",
|
81 | "BigUint64Array",
|
82 |
|
83 | "Set",
|
84 | "Map",
|
85 | "WeakSet",
|
86 | "WeakMap",
|
87 |
|
88 | "ArrayBuffer",
|
89 | "SharedArrayBuffer",
|
90 | "Atomics",
|
91 | "DataView",
|
92 | "JSON",
|
93 |
|
94 | "Promise",
|
95 | "Generator",
|
96 | "GeneratorFunction",
|
97 | "AsyncFunction",
|
98 |
|
99 | "Reflect",
|
100 | "Proxy",
|
101 |
|
102 | "Intl",
|
103 |
|
104 | "WebAssembly"
|
105 | ];
|
106 |
|
107 | const ERROR_TYPES = [
|
108 | "Error",
|
109 | "EvalError",
|
110 | "InternalError",
|
111 | "RangeError",
|
112 | "ReferenceError",
|
113 | "SyntaxError",
|
114 | "TypeError",
|
115 | "URIError"
|
116 | ];
|
117 |
|
118 | const BUILT_IN_GLOBALS = [
|
119 | "setInterval",
|
120 | "setTimeout",
|
121 | "clearInterval",
|
122 | "clearTimeout",
|
123 |
|
124 | "require",
|
125 | "exports",
|
126 |
|
127 | "eval",
|
128 | "isFinite",
|
129 | "isNaN",
|
130 | "parseFloat",
|
131 | "parseInt",
|
132 | "decodeURI",
|
133 | "decodeURIComponent",
|
134 | "encodeURI",
|
135 | "encodeURIComponent",
|
136 | "escape",
|
137 | "unescape"
|
138 | ];
|
139 |
|
140 | const BUILT_IN_VARIABLES = [
|
141 | "arguments",
|
142 | "this",
|
143 | "super",
|
144 | "console",
|
145 | "window",
|
146 | "document",
|
147 | "localStorage",
|
148 | "module",
|
149 | "global"
|
150 | ];
|
151 |
|
152 | const BUILT_INS = [].concat(
|
153 | BUILT_IN_GLOBALS,
|
154 | TYPES,
|
155 | ERROR_TYPES
|
156 | );
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 | function javascript(hljs) {
|
167 | const regex = hljs.regex;
|
168 | |
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 | const hasClosingTag = (match, { after }) => {
|
176 | const tag = "</" + match[0].slice(1);
|
177 | const pos = match.input.indexOf(tag, after);
|
178 | return pos !== -1;
|
179 | };
|
180 |
|
181 | const IDENT_RE$1 = IDENT_RE;
|
182 | const FRAGMENT = {
|
183 | begin: '<>',
|
184 | end: '</>'
|
185 | };
|
186 |
|
187 | const XML_SELF_CLOSING = /<[A-Za-z0-9\\._:-]+\s*\/>/;
|
188 | const XML_TAG = {
|
189 | begin: /<[A-Za-z0-9\\._:-]+/,
|
190 | end: /\/[A-Za-z0-9\\._:-]+>|\/>/,
|
191 | |
192 |
|
193 |
|
194 |
|
195 | isTrulyOpeningTag: (match, response) => {
|
196 | const afterMatchIndex = match[0].length + match.index;
|
197 | const nextChar = match.input[afterMatchIndex];
|
198 | if (
|
199 |
|
200 |
|
201 |
|
202 | nextChar === "<" ||
|
203 |
|
204 |
|
205 | nextChar === ",") {
|
206 | response.ignoreMatch();
|
207 | return;
|
208 | }
|
209 |
|
210 |
|
211 |
|
212 | if (nextChar === ">") {
|
213 |
|
214 |
|
215 | if (!hasClosingTag(match, { after: afterMatchIndex })) {
|
216 | response.ignoreMatch();
|
217 | }
|
218 | }
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 | let m;
|
226 | const afterMatch = match.input.substr(afterMatchIndex);
|
227 |
|
228 | if ((m = afterMatch.match(/^\s+extends\s+/))) {
|
229 | if (m.index === 0) {
|
230 | response.ignoreMatch();
|
231 |
|
232 | return;
|
233 | }
|
234 | }
|
235 | }
|
236 | };
|
237 | const KEYWORDS$1 = {
|
238 | $pattern: IDENT_RE,
|
239 | keyword: KEYWORDS,
|
240 | literal: LITERALS,
|
241 | built_in: BUILT_INS,
|
242 | "variable.language": BUILT_IN_VARIABLES
|
243 | };
|
244 |
|
245 |
|
246 | const decimalDigits = '[0-9](_?[0-9])*';
|
247 | const frac = `\\.(${decimalDigits})`;
|
248 |
|
249 |
|
250 | const decimalInteger = `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`;
|
251 | const NUMBER = {
|
252 | className: 'number',
|
253 | variants: [
|
254 |
|
255 | { begin: `(\\b(${decimalInteger})((${frac})|\\.)?|(${frac}))` +
|
256 | `[eE][+-]?(${decimalDigits})\\b` },
|
257 | { begin: `\\b(${decimalInteger})\\b((${frac})\\b|\\.)?|(${frac})\\b` },
|
258 |
|
259 |
|
260 | { begin: `\\b(0|[1-9](_?[0-9])*)n\\b` },
|
261 |
|
262 |
|
263 | { begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b" },
|
264 | { begin: "\\b0[bB][0-1](_?[0-1])*n?\\b" },
|
265 | { begin: "\\b0[oO][0-7](_?[0-7])*n?\\b" },
|
266 |
|
267 |
|
268 |
|
269 | { begin: "\\b0[0-7]+n?\\b" },
|
270 | ],
|
271 | relevance: 0
|
272 | };
|
273 |
|
274 | const SUBST = {
|
275 | className: 'subst',
|
276 | begin: '\\$\\{',
|
277 | end: '\\}',
|
278 | keywords: KEYWORDS$1,
|
279 | contains: []
|
280 | };
|
281 | const HTML_TEMPLATE = {
|
282 | begin: 'html`',
|
283 | end: '',
|
284 | starts: {
|
285 | end: '`',
|
286 | returnEnd: false,
|
287 | contains: [
|
288 | hljs.BACKSLASH_ESCAPE,
|
289 | SUBST
|
290 | ],
|
291 | subLanguage: 'xml'
|
292 | }
|
293 | };
|
294 | const CSS_TEMPLATE = {
|
295 | begin: 'css`',
|
296 | end: '',
|
297 | starts: {
|
298 | end: '`',
|
299 | returnEnd: false,
|
300 | contains: [
|
301 | hljs.BACKSLASH_ESCAPE,
|
302 | SUBST
|
303 | ],
|
304 | subLanguage: 'css'
|
305 | }
|
306 | };
|
307 | const TEMPLATE_STRING = {
|
308 | className: 'string',
|
309 | begin: '`',
|
310 | end: '`',
|
311 | contains: [
|
312 | hljs.BACKSLASH_ESCAPE,
|
313 | SUBST
|
314 | ]
|
315 | };
|
316 | const JSDOC_COMMENT = hljs.COMMENT(
|
317 | /\/\*\*(?!\/)/,
|
318 | '\\*/',
|
319 | {
|
320 | relevance: 0,
|
321 | contains: [
|
322 | {
|
323 | begin: '(?=@[A-Za-z]+)',
|
324 | relevance: 0,
|
325 | contains: [
|
326 | {
|
327 | className: 'doctag',
|
328 | begin: '@[A-Za-z]+'
|
329 | },
|
330 | {
|
331 | className: 'type',
|
332 | begin: '\\{',
|
333 | end: '\\}',
|
334 | excludeEnd: true,
|
335 | excludeBegin: true,
|
336 | relevance: 0
|
337 | },
|
338 | {
|
339 | className: 'variable',
|
340 | begin: IDENT_RE$1 + '(?=\\s*(-)|$)',
|
341 | endsParent: true,
|
342 | relevance: 0
|
343 | },
|
344 |
|
345 |
|
346 | {
|
347 | begin: /(?=[^\n])\s/,
|
348 | relevance: 0
|
349 | }
|
350 | ]
|
351 | }
|
352 | ]
|
353 | }
|
354 | );
|
355 | const COMMENT = {
|
356 | className: "comment",
|
357 | variants: [
|
358 | JSDOC_COMMENT,
|
359 | hljs.C_BLOCK_COMMENT_MODE,
|
360 | hljs.C_LINE_COMMENT_MODE
|
361 | ]
|
362 | };
|
363 | const SUBST_INTERNALS = [
|
364 | hljs.APOS_STRING_MODE,
|
365 | hljs.QUOTE_STRING_MODE,
|
366 | HTML_TEMPLATE,
|
367 | CSS_TEMPLATE,
|
368 | TEMPLATE_STRING,
|
369 | NUMBER,
|
370 |
|
371 |
|
372 |
|
373 | ];
|
374 | SUBST.contains = SUBST_INTERNALS
|
375 | .concat({
|
376 |
|
377 |
|
378 | begin: /\{/,
|
379 | end: /\}/,
|
380 | keywords: KEYWORDS$1,
|
381 | contains: [
|
382 | "self"
|
383 | ].concat(SUBST_INTERNALS)
|
384 | });
|
385 | const SUBST_AND_COMMENTS = [].concat(COMMENT, SUBST.contains);
|
386 | const PARAMS_CONTAINS = SUBST_AND_COMMENTS.concat([
|
387 |
|
388 | {
|
389 | begin: /\(/,
|
390 | end: /\)/,
|
391 | keywords: KEYWORDS$1,
|
392 | contains: ["self"].concat(SUBST_AND_COMMENTS)
|
393 | }
|
394 | ]);
|
395 | const PARAMS = {
|
396 | className: 'params',
|
397 | begin: /\(/,
|
398 | end: /\)/,
|
399 | excludeBegin: true,
|
400 | excludeEnd: true,
|
401 | keywords: KEYWORDS$1,
|
402 | contains: PARAMS_CONTAINS
|
403 | };
|
404 |
|
405 |
|
406 | const CLASS_OR_EXTENDS = {
|
407 | variants: [
|
408 |
|
409 | {
|
410 | match: [
|
411 | /class/,
|
412 | /\s+/,
|
413 | IDENT_RE$1,
|
414 | /\s+/,
|
415 | /extends/,
|
416 | /\s+/,
|
417 | regex.concat(IDENT_RE$1, "(", regex.concat(/\./, IDENT_RE$1), ")*")
|
418 | ],
|
419 | scope: {
|
420 | 1: "keyword",
|
421 | 3: "title.class",
|
422 | 5: "keyword",
|
423 | 7: "title.class.inherited"
|
424 | }
|
425 | },
|
426 |
|
427 | {
|
428 | match: [
|
429 | /class/,
|
430 | /\s+/,
|
431 | IDENT_RE$1
|
432 | ],
|
433 | scope: {
|
434 | 1: "keyword",
|
435 | 3: "title.class"
|
436 | }
|
437 | },
|
438 |
|
439 | ]
|
440 | };
|
441 |
|
442 | const CLASS_REFERENCE = {
|
443 | relevance: 0,
|
444 | match:
|
445 | regex.either(
|
446 |
|
447 | /\bJSON/,
|
448 |
|
449 | /\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,
|
450 |
|
451 | /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,
|
452 |
|
453 | /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/,
|
454 |
|
455 |
|
456 |
|
457 |
|
458 | ),
|
459 | className: "title.class",
|
460 | keywords: {
|
461 | _: [
|
462 |
|
463 | ...TYPES,
|
464 | ...ERROR_TYPES
|
465 | ]
|
466 | }
|
467 | };
|
468 |
|
469 | const USE_STRICT = {
|
470 | label: "use_strict",
|
471 | className: 'meta',
|
472 | relevance: 10,
|
473 | begin: /^\s*['"]use (strict|asm)['"]/
|
474 | };
|
475 |
|
476 | const FUNCTION_DEFINITION = {
|
477 | variants: [
|
478 | {
|
479 | match: [
|
480 | /function/,
|
481 | /\s+/,
|
482 | IDENT_RE$1,
|
483 | /(?=\s*\()/
|
484 | ]
|
485 | },
|
486 | // anonymous function
|
487 | {
|
488 | match: [
|
489 | /function/,
|
490 | /\s*(?=\()/
|
491 | ]
|
492 | }
|
493 | ],
|
494 | className: {
|
495 | 1: "keyword",
|
496 | 3: "title.function"
|
497 | },
|
498 | label: "func.def",
|
499 | contains: [ PARAMS ],
|
500 | illegal: /%/
|
501 | };
|
502 |
|
503 | const UPPER_CASE_CONSTANT = {
|
504 | relevance: 0,
|
505 | match: /\b[A-Z][A-Z_0-9]+\b/,
|
506 | className: "variable.constant"
|
507 | };
|
508 |
|
509 | function noneOf(list) {
|
510 | return regex.concat("(?!", list.join("|"), ")");
|
511 | }
|
512 |
|
513 | const FUNCTION_CALL = {
|
514 | match: regex.concat(
|
515 | /\b/,
|
516 | noneOf([
|
517 | ...BUILT_IN_GLOBALS,
|
518 | "super"
|
519 | ]),
|
520 | IDENT_RE$1, regex.lookahead(/\(/)),
|
521 | className: "title.function",
|
522 | relevance: 0
|
523 | };
|
524 |
|
525 | const PROPERTY_ACCESS = {
|
526 | begin: regex.concat(/\./, regex.lookahead(
|
527 | regex.concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/)
|
528 | )),
|
529 | end: IDENT_RE$1,
|
530 | excludeBegin: true,
|
531 | keywords: "prototype",
|
532 | className: "property",
|
533 | relevance: 0
|
534 | };
|
535 |
|
536 | const GETTER_OR_SETTER = {
|
537 | match: [
|
538 | /get|set/,
|
539 | /\s+/,
|
540 | IDENT_RE$1,
|
541 | /(?=\()/
|
542 | ],
|
543 | className: {
|
544 | 1: "keyword",
|
545 | 3: "title.function"
|
546 | },
|
547 | contains: [
|
548 | {
|
549 | begin: /\(\)/
|
550 | },
|
551 | PARAMS
|
552 | ]
|
553 | };
|
554 |
|
555 | const FUNC_LEAD_IN_RE = '(\\(' +
|
556 | '[^()]*(\\(' +
|
557 | '[^()]*(\\(' +
|
558 | '[^()]*' +
|
559 | '\\)[^()]*)*' +
|
560 | '\\)[^()]*)*' +
|
561 | '\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\s*=>';
|
562 |
|
563 | const FUNCTION_VARIABLE = {
|
564 | match: [
|
565 | /const|var|let/, /\s+/,
|
566 | IDENT_RE$1, /\s*/,
|
567 | /=\s*/,
|
568 | /(async\s*)?/, // async is optional
|
569 | regex.lookahead(FUNC_LEAD_IN_RE)
|
570 | ],
|
571 | keywords: "async",
|
572 | className: {
|
573 | 1: "keyword",
|
574 | 3: "title.function"
|
575 | },
|
576 | contains: [
|
577 | PARAMS
|
578 | ]
|
579 | };
|
580 |
|
581 | return {
|
582 | name: 'Javascript',
|
583 | aliases: ['js', 'jsx', 'mjs', 'cjs'],
|
584 | keywords: KEYWORDS$1,
|
585 |
|
586 | exports: { PARAMS_CONTAINS, CLASS_REFERENCE },
|
587 | illegal: /#(?![$_A-z])/,
|
588 | contains: [
|
589 | hljs.SHEBANG({
|
590 | label: "shebang",
|
591 | binary: "node",
|
592 | relevance: 5
|
593 | }),
|
594 | USE_STRICT,
|
595 | hljs.APOS_STRING_MODE,
|
596 | hljs.QUOTE_STRING_MODE,
|
597 | HTML_TEMPLATE,
|
598 | CSS_TEMPLATE,
|
599 | TEMPLATE_STRING,
|
600 | COMMENT,
|
601 | NUMBER,
|
602 | CLASS_REFERENCE,
|
603 | {
|
604 | className: 'attr',
|
605 | begin: IDENT_RE$1 + regex.lookahead(':'),
|
606 | relevance: 0
|
607 | },
|
608 | FUNCTION_VARIABLE,
|
609 | {
|
610 | begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
|
611 | keywords: 'return throw case',
|
612 | relevance: 0,
|
613 | contains: [
|
614 | COMMENT,
|
615 | hljs.REGEXP_MODE,
|
616 | {
|
617 | className: 'function',
|
618 |
|
619 |
|
620 |
|
621 | begin: FUNC_LEAD_IN_RE,
|
622 | returnBegin: true,
|
623 | end: '\\s*=>',
|
624 | contains: [
|
625 | {
|
626 | className: 'params',
|
627 | variants: [
|
628 | {
|
629 | begin: hljs.UNDERSCORE_IDENT_RE,
|
630 | relevance: 0
|
631 | },
|
632 | {
|
633 | className: null,
|
634 | begin: /\(\s*\)/,
|
635 | skip: true
|
636 | },
|
637 | {
|
638 | begin: /\(/,
|
639 | end: /\)/,
|
640 | excludeBegin: true,
|
641 | excludeEnd: true,
|
642 | keywords: KEYWORDS$1,
|
643 | contains: PARAMS_CONTAINS
|
644 | }
|
645 | ]
|
646 | }
|
647 | ]
|
648 | },
|
649 | {
|
650 | begin: /,/,
|
651 | relevance: 0
|
652 | },
|
653 | {
|
654 | match: /\s+/,
|
655 | relevance: 0
|
656 | },
|
657 | {
|
658 | variants: [
|
659 | { begin: FRAGMENT.begin, end: FRAGMENT.end },
|
660 | { match: XML_SELF_CLOSING },
|
661 | {
|
662 | begin: XML_TAG.begin,
|
663 |
|
664 |
|
665 | 'on:begin': XML_TAG.isTrulyOpeningTag,
|
666 | end: XML_TAG.end
|
667 | }
|
668 | ],
|
669 | subLanguage: 'xml',
|
670 | contains: [
|
671 | {
|
672 | begin: XML_TAG.begin,
|
673 | end: XML_TAG.end,
|
674 | skip: true,
|
675 | contains: ['self']
|
676 | }
|
677 | ]
|
678 | }
|
679 | ],
|
680 | },
|
681 | FUNCTION_DEFINITION,
|
682 | {
|
683 |
|
684 |
|
685 | beginKeywords: "while if switch catch for"
|
686 | },
|
687 | {
|
688 |
|
689 |
|
690 |
|
691 | begin: '\\b(?!function)' + hljs.UNDERSCORE_IDENT_RE +
|
692 | '\\(' +
|
693 | '[^()]*(\\(' +
|
694 | '[^()]*(\\(' +
|
695 | '[^()]*' +
|
696 | '\\)[^()]*)*' +
|
697 | '\\)[^()]*)*' +
|
698 | '\\)\\s*\\{',
|
699 | returnBegin:true,
|
700 | label: "func.def",
|
701 | contains: [
|
702 | PARAMS,
|
703 | hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1, className: "title.function" })
|
704 | ]
|
705 | },
|
706 |
|
707 | {
|
708 | match: /\.\.\./,
|
709 | relevance: 0
|
710 | },
|
711 | PROPERTY_ACCESS,
|
712 |
|
713 |
|
714 |
|
715 | {
|
716 | match: '\\$' + IDENT_RE$1,
|
717 | relevance: 0
|
718 | },
|
719 | {
|
720 | match: [ /\bconstructor(?=\s*\()/ ],
|
721 | className: { 1: "title.function" },
|
722 | contains: [ PARAMS ]
|
723 | },
|
724 | FUNCTION_CALL,
|
725 | UPPER_CASE_CONSTANT,
|
726 | CLASS_OR_EXTENDS,
|
727 | GETTER_OR_SETTER,
|
728 | {
|
729 | match: /\$[(.]/
|
730 | }
|
731 | ]
|
732 | };
|
733 | }
|
734 |
|
735 | module.exports = javascript;
|