l0bsterssg

node.js static responsive blog post generator
Log | Files | Refs | README

javascript.js (10180B)


      1 const IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';
      2 const KEYWORDS = [
      3   "as", // for exports
      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   // JS handles these with a special rule
     34   // "get",
     35   // "set",
     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 const TYPES = [
     55   "Intl",
     56   "DataView",
     57   "Number",
     58   "Math",
     59   "Date",
     60   "String",
     61   "RegExp",
     62   "Object",
     63   "Function",
     64   "Boolean",
     65   "Error",
     66   "Symbol",
     67   "Set",
     68   "Map",
     69   "WeakSet",
     70   "WeakMap",
     71   "Proxy",
     72   "Reflect",
     73   "JSON",
     74   "Promise",
     75   "Float64Array",
     76   "Int16Array",
     77   "Int32Array",
     78   "Int8Array",
     79   "Uint16Array",
     80   "Uint32Array",
     81   "Float32Array",
     82   "Array",
     83   "Uint8Array",
     84   "Uint8ClampedArray",
     85   "ArrayBuffer"
     86 ];
     87 
     88 const ERROR_TYPES = [
     89   "EvalError",
     90   "InternalError",
     91   "RangeError",
     92   "ReferenceError",
     93   "SyntaxError",
     94   "TypeError",
     95   "URIError"
     96 ];
     97 
     98 const BUILT_IN_GLOBALS = [
     99   "setInterval",
    100   "setTimeout",
    101   "clearInterval",
    102   "clearTimeout",
    103 
    104   "require",
    105   "exports",
    106 
    107   "eval",
    108   "isFinite",
    109   "isNaN",
    110   "parseFloat",
    111   "parseInt",
    112   "decodeURI",
    113   "decodeURIComponent",
    114   "encodeURI",
    115   "encodeURIComponent",
    116   "escape",
    117   "unescape"
    118 ];
    119 
    120 const BUILT_IN_VARIABLES = [
    121   "arguments",
    122   "this",
    123   "super",
    124   "console",
    125   "window",
    126   "document",
    127   "localStorage",
    128   "module",
    129   "global" // Node.js
    130 ];
    131 
    132 const BUILT_INS = [].concat(
    133   BUILT_IN_GLOBALS,
    134   BUILT_IN_VARIABLES,
    135   TYPES,
    136   ERROR_TYPES
    137 );
    138 
    139 /**
    140  * @param {string} value
    141  * @returns {RegExp}
    142  * */
    143 
    144 /**
    145  * @param {RegExp | string } re
    146  * @returns {string}
    147  */
    148 function source(re) {
    149   if (!re) return null;
    150   if (typeof re === "string") return re;
    151 
    152   return re.source;
    153 }
    154 
    155 /**
    156  * @param {RegExp | string } re
    157  * @returns {string}
    158  */
    159 function lookahead(re) {
    160   return concat('(?=', re, ')');
    161 }
    162 
    163 /**
    164  * @param {...(RegExp | string) } args
    165  * @returns {string}
    166  */
    167 function concat(...args) {
    168   const joined = args.map((x) => source(x)).join("");
    169   return joined;
    170 }
    171 
    172 /*
    173 Language: JavaScript
    174 Description: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions.
    175 Category: common, scripting
    176 Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript
    177 */
    178 
    179 function javascript(hljs) {
    180   var IDENT_RE$1 = IDENT_RE;
    181   var FRAGMENT = {
    182     begin: '<>',
    183     end: '</>'
    184   };
    185   var XML_TAG = {
    186     begin: /<[A-Za-z0-9\\._:-]+/,
    187     end: /\/[A-Za-z0-9\\._:-]+>|\/>/
    188   };
    189   var KEYWORDS$1 = {
    190     $pattern: IDENT_RE,
    191     keyword: KEYWORDS.join(" "),
    192     literal: LITERALS.join(" "),
    193     built_in: BUILT_INS.join(" ")
    194   };
    195   var NUMBER = {
    196     className: 'number',
    197     variants: [
    198       { begin: '\\b(0[bB][01]+)n?' },
    199       { begin: '\\b(0[oO][0-7]+)n?' },
    200       { begin: hljs.C_NUMBER_RE + 'n?' }
    201     ],
    202     relevance: 0
    203   };
    204   var SUBST = {
    205     className: 'subst',
    206     begin: '\\$\\{', end: '\\}',
    207     keywords: KEYWORDS$1,
    208     contains: []  // defined later
    209   };
    210   var HTML_TEMPLATE = {
    211     begin: 'html`', end: '',
    212     starts: {
    213       end: '`', returnEnd: false,
    214       contains: [
    215         hljs.BACKSLASH_ESCAPE,
    216         SUBST
    217       ],
    218       subLanguage: 'xml',
    219     }
    220   };
    221   var CSS_TEMPLATE = {
    222     begin: 'css`', end: '',
    223     starts: {
    224       end: '`', returnEnd: false,
    225       contains: [
    226         hljs.BACKSLASH_ESCAPE,
    227         SUBST
    228       ],
    229       subLanguage: 'css',
    230     }
    231   };
    232   var TEMPLATE_STRING = {
    233     className: 'string',
    234     begin: '`', end: '`',
    235     contains: [
    236       hljs.BACKSLASH_ESCAPE,
    237       SUBST
    238     ]
    239   };
    240   SUBST.contains = [
    241     hljs.APOS_STRING_MODE,
    242     hljs.QUOTE_STRING_MODE,
    243     HTML_TEMPLATE,
    244     CSS_TEMPLATE,
    245     TEMPLATE_STRING,
    246     NUMBER,
    247     hljs.REGEXP_MODE
    248   ];
    249   var PARAMS_CONTAINS = SUBST.contains.concat([
    250     // eat recursive parens in sub expressions
    251     { begin: /\(/, end: /\)/,
    252       contains: ["self"].concat(SUBST.contains, [hljs.C_BLOCK_COMMENT_MODE, hljs.C_LINE_COMMENT_MODE])
    253     },
    254     hljs.C_BLOCK_COMMENT_MODE,
    255     hljs.C_LINE_COMMENT_MODE
    256   ]);
    257   var PARAMS = {
    258     className: 'params',
    259     begin: /\(/, end: /\)/,
    260     excludeBegin: true,
    261     excludeEnd: true,
    262     contains: PARAMS_CONTAINS
    263   };
    264 
    265   return {
    266     name: 'JavaScript',
    267     aliases: ['js', 'jsx', 'mjs', 'cjs'],
    268     keywords: KEYWORDS$1,
    269     contains: [
    270       hljs.SHEBANG({
    271         binary: "node",
    272         relevance: 5
    273       }),
    274       {
    275         className: 'meta',
    276         relevance: 10,
    277         begin: /^\s*['"]use (strict|asm)['"]/
    278       },
    279       hljs.APOS_STRING_MODE,
    280       hljs.QUOTE_STRING_MODE,
    281       HTML_TEMPLATE,
    282       CSS_TEMPLATE,
    283       TEMPLATE_STRING,
    284       hljs.C_LINE_COMMENT_MODE,
    285       hljs.COMMENT(
    286         '/\\*\\*',
    287         '\\*/',
    288         {
    289           relevance : 0,
    290           contains : [
    291             {
    292               className : 'doctag',
    293               begin : '@[A-Za-z]+',
    294               contains : [
    295                 {
    296                   className: 'type',
    297                   begin: '\\{',
    298                   end: '\\}',
    299                   relevance: 0
    300                 },
    301                 {
    302                   className: 'variable',
    303                   begin: IDENT_RE$1 + '(?=\\s*(-)|$)',
    304                   endsParent: true,
    305                   relevance: 0
    306                 },
    307                 // eat spaces (not newlines) so we can find
    308                 // types or variables
    309                 {
    310                   begin: /(?=[^\n])\s/,
    311                   relevance: 0
    312                 },
    313               ]
    314             }
    315           ]
    316         }
    317       ),
    318       hljs.C_BLOCK_COMMENT_MODE,
    319       NUMBER,
    320       { // object attr container
    321         begin: concat(/[{,\n]\s*/,
    322           // we need to look ahead to make sure that we actually have an
    323           // attribute coming up so we don't steal a comma from a potential
    324           // "value" container
    325           //
    326           // NOTE: this might not work how you think.  We don't actually always
    327           // enter this mode and stay.  Instead it might merely match `,
    328           // <comments up next>` and then immediately end after the , because it
    329           // fails to find any actual attrs. But this still does the job because
    330           // it prevents the value contain rule from grabbing this instead and
    331           // prevening this rule from firing when we actually DO have keys.
    332           lookahead(concat(
    333             // we also need to allow for multiple possible comments inbetween
    334             // the first key:value pairing
    335             /(((\/\/.*$)|(\/\*(.|\n)*\*\/))\s*)*/,
    336             IDENT_RE$1 + '\\s*:'))),
    337         relevance: 0,
    338         contains: [
    339           {
    340             className: 'attr',
    341             begin: IDENT_RE$1 + lookahead('\\s*:'),
    342             relevance: 0,
    343           },
    344         ]
    345       },
    346       { // "value" container
    347         begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
    348         keywords: 'return throw case',
    349         contains: [
    350           hljs.C_LINE_COMMENT_MODE,
    351           hljs.C_BLOCK_COMMENT_MODE,
    352           hljs.REGEXP_MODE,
    353           {
    354             className: 'function',
    355             // we have to count the parens to make sure we actually have the
    356             // correct bounding ( ) before the =>.  There could be any number of
    357             // sub-expressions inside also surrounded by parens.
    358             begin: '(\\([^(]*' +
    359               '(\\([^(]*' +
    360                 '(\\([^(]*' +
    361                 '\\))?' +
    362               '\\))?' +
    363             '\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\s*=>', returnBegin: true,
    364             end: '\\s*=>',
    365             contains: [
    366               {
    367                 className: 'params',
    368                 variants: [
    369                   {
    370                     begin: hljs.UNDERSCORE_IDENT_RE
    371                   },
    372                   {
    373                     className: null,
    374                     begin: /\(\s*\)/,
    375                     skip: true
    376                   },
    377                   {
    378                     begin: /\(/, end: /\)/,
    379                     excludeBegin: true, excludeEnd: true,
    380                     keywords: KEYWORDS$1,
    381                     contains: PARAMS_CONTAINS
    382                   }
    383                 ]
    384               }
    385             ]
    386           },
    387           { // could be a comma delimited list of params to a function call
    388             begin: /,/, relevance: 0,
    389           },
    390           {
    391             className: '',
    392             begin: /\s/,
    393             end: /\s*/,
    394             skip: true,
    395           },
    396           { // JSX
    397             variants: [
    398               { begin: FRAGMENT.begin, end: FRAGMENT.end },
    399               { begin: XML_TAG.begin, end: XML_TAG.end }
    400             ],
    401             subLanguage: 'xml',
    402             contains: [
    403               {
    404                 begin: XML_TAG.begin, end: XML_TAG.end, skip: true,
    405                 contains: ['self']
    406               }
    407             ]
    408           },
    409         ],
    410         relevance: 0
    411       },
    412       {
    413         className: 'function',
    414         beginKeywords: 'function', end: /\{/, excludeEnd: true,
    415         contains: [
    416           hljs.inherit(hljs.TITLE_MODE, {begin: IDENT_RE$1}),
    417           PARAMS
    418         ],
    419         illegal: /\[|%/
    420       },
    421       {
    422         begin: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
    423       },
    424 
    425       hljs.METHOD_GUARD,
    426       { // ES6 class
    427         className: 'class',
    428         beginKeywords: 'class', end: /[{;=]/, excludeEnd: true,
    429         illegal: /[:"\[\]]/,
    430         contains: [
    431           {beginKeywords: 'extends'},
    432           hljs.UNDERSCORE_TITLE_MODE
    433         ]
    434       },
    435       {
    436         beginKeywords: 'constructor', end: /\{/, excludeEnd: true
    437       },
    438       {
    439         begin: '(get|set)\\s+(?=' + IDENT_RE$1 + '\\()',
    440         end: /{/,
    441         keywords: "get set",
    442         contains: [
    443           hljs.inherit(hljs.TITLE_MODE, {begin: IDENT_RE$1}),
    444           { begin: /\(\)/ }, // eat to avoid empty params
    445           PARAMS
    446         ]
    447 
    448       }
    449     ],
    450     illegal: /#(?!!)/
    451   };
    452 }
    453 
    454 module.exports = javascript;