prism-javascript.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. Prism.languages.javascript = Prism.languages.extend('clike', {
  2. 'class-name': [
  3. Prism.languages.clike['class-name'],
  4. {
  5. pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
  6. lookbehind: true
  7. }
  8. ],
  9. 'keyword': [
  10. {
  11. pattern: /((?:^|\})\s*)catch\b/,
  12. lookbehind: true
  13. },
  14. {
  15. pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
  16. lookbehind: true
  17. },
  18. ],
  19. // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
  20. 'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
  21. 'number': {
  22. pattern: RegExp(
  23. /(^|[^\w$])/.source +
  24. '(?:' +
  25. (
  26. // constant
  27. /NaN|Infinity/.source +
  28. '|' +
  29. // binary integer
  30. /0[bB][01]+(?:_[01]+)*n?/.source +
  31. '|' +
  32. // octal integer
  33. /0[oO][0-7]+(?:_[0-7]+)*n?/.source +
  34. '|' +
  35. // hexadecimal integer
  36. /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
  37. '|' +
  38. // decimal bigint
  39. /\d+(?:_\d+)*n/.source +
  40. '|' +
  41. // decimal number (integer or float) but no bigint
  42. /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source
  43. ) +
  44. ')' +
  45. /(?![\w$])/.source
  46. ),
  47. lookbehind: true
  48. },
  49. 'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
  50. });
  51. Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
  52. Prism.languages.insertBefore('javascript', 'keyword', {
  53. 'regex': {
  54. pattern: RegExp(
  55. // lookbehind
  56. // eslint-disable-next-line regexp/no-dupe-characters-character-class
  57. /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
  58. // Regex pattern:
  59. // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
  60. // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
  61. // with the only syntax, so we have to define 2 different regex patterns.
  62. /\//.source +
  63. '(?:' +
  64. /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source +
  65. '|' +
  66. // `v` flag syntax. This supports 3 levels of nested character classes.
  67. /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source +
  68. ')' +
  69. // lookahead
  70. /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
  71. ),
  72. lookbehind: true,
  73. greedy: true,
  74. inside: {
  75. 'regex-source': {
  76. pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
  77. lookbehind: true,
  78. alias: 'language-regex',
  79. inside: Prism.languages.regex
  80. },
  81. 'regex-delimiter': /^\/|\/$/,
  82. 'regex-flags': /^[a-z]+$/,
  83. }
  84. },
  85. // This must be declared before keyword because we use "function" inside the look-forward
  86. 'function-variable': {
  87. pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
  88. alias: 'function'
  89. },
  90. 'parameter': [
  91. {
  92. pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
  93. lookbehind: true,
  94. inside: Prism.languages.javascript
  95. },
  96. {
  97. pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
  98. lookbehind: true,
  99. inside: Prism.languages.javascript
  100. },
  101. {
  102. pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
  103. lookbehind: true,
  104. inside: Prism.languages.javascript
  105. },
  106. {
  107. pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
  108. lookbehind: true,
  109. inside: Prism.languages.javascript
  110. }
  111. ],
  112. 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
  113. });
  114. Prism.languages.insertBefore('javascript', 'string', {
  115. 'hashbang': {
  116. pattern: /^#!.*/,
  117. greedy: true,
  118. alias: 'comment'
  119. },
  120. 'template-string': {
  121. pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
  122. greedy: true,
  123. inside: {
  124. 'template-punctuation': {
  125. pattern: /^`|`$/,
  126. alias: 'string'
  127. },
  128. 'interpolation': {
  129. pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
  130. lookbehind: true,
  131. inside: {
  132. 'interpolation-punctuation': {
  133. pattern: /^\$\{|\}$/,
  134. alias: 'punctuation'
  135. },
  136. rest: Prism.languages.javascript
  137. }
  138. },
  139. 'string': /[\s\S]+/
  140. }
  141. },
  142. 'string-property': {
  143. pattern: /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
  144. lookbehind: true,
  145. greedy: true,
  146. alias: 'property'
  147. }
  148. });
  149. Prism.languages.insertBefore('javascript', 'operator', {
  150. 'literal-property': {
  151. pattern: /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
  152. lookbehind: true,
  153. alias: 'property'
  154. },
  155. });
  156. if (Prism.languages.markup) {
  157. Prism.languages.markup.tag.addInlined('script', 'javascript');
  158. // add attribute support for all DOM events.
  159. // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
  160. Prism.languages.markup.tag.addAttribute(
  161. /on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,
  162. 'javascript'
  163. );
  164. }
  165. Prism.languages.js = Prism.languages.javascript;