1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-06-08 08:26:20 +00:00
Jan Korf d533557324
Websocket refactoring (#190)
Websocket refactoring
2024-02-24 19:21:47 +01:00

285 lines
7.8 KiB
JavaScript

/*
Language: JavaScript
Description: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions.
Category: common, scripting
Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript
*/
import * as ECMAScript from "./lib/ecmascript";
import * as regex from "../lib/regex";
export default function(hljs) {
var IDENT_RE = ECMAScript.IDENT_RE;
var FRAGMENT = {
begin: '<>',
end: '</>'
};
var XML_TAG = {
begin: /<[A-Za-z0-9\\._:-]+/,
end: /\/[A-Za-z0-9\\._:-]+>|\/>/
};
var KEYWORDS = {
$pattern: ECMAScript.IDENT_RE,
keyword: ECMAScript.KEYWORDS.join(" "),
literal: ECMAScript.LITERALS.join(" "),
built_in: ECMAScript.BUILT_INS.join(" ")
};
var NUMBER = {
className: 'number',
variants: [
{ begin: '\\b(0[bB][01]+)n?' },
{ begin: '\\b(0[oO][0-7]+)n?' },
{ begin: hljs.C_NUMBER_RE + 'n?' }
],
relevance: 0
};
var SUBST = {
className: 'subst',
begin: '\\$\\{', end: '\\}',
keywords: KEYWORDS,
contains: [] // defined later
};
var HTML_TEMPLATE = {
begin: 'html`', end: '',
starts: {
end: '`', returnEnd: false,
contains: [
hljs.BACKSLASH_ESCAPE,
SUBST
],
subLanguage: 'xml',
}
};
var CSS_TEMPLATE = {
begin: 'css`', end: '',
starts: {
end: '`', returnEnd: false,
contains: [
hljs.BACKSLASH_ESCAPE,
SUBST
],
subLanguage: 'css',
}
};
var TEMPLATE_STRING = {
className: 'string',
begin: '`', end: '`',
contains: [
hljs.BACKSLASH_ESCAPE,
SUBST
]
};
SUBST.contains = [
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
HTML_TEMPLATE,
CSS_TEMPLATE,
TEMPLATE_STRING,
NUMBER,
hljs.REGEXP_MODE
];
var PARAMS_CONTAINS = SUBST.contains.concat([
// eat recursive parens in sub expressions
{ begin: /\(/, end: /\)/,
contains: ["self"].concat(SUBST.contains, [hljs.C_BLOCK_COMMENT_MODE, hljs.C_LINE_COMMENT_MODE])
},
hljs.C_BLOCK_COMMENT_MODE,
hljs.C_LINE_COMMENT_MODE
]);
var PARAMS = {
className: 'params',
begin: /\(/, end: /\)/,
excludeBegin: true,
excludeEnd: true,
contains: PARAMS_CONTAINS
};
return {
name: 'JavaScript',
aliases: ['js', 'jsx', 'mjs', 'cjs'],
keywords: KEYWORDS,
contains: [
hljs.SHEBANG({
binary: "node",
relevance: 5
}),
{
className: 'meta',
relevance: 10,
begin: /^\s*['"]use (strict|asm)['"]/
},
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
HTML_TEMPLATE,
CSS_TEMPLATE,
TEMPLATE_STRING,
hljs.C_LINE_COMMENT_MODE,
hljs.COMMENT(
'/\\*\\*',
'\\*/',
{
relevance : 0,
contains : [
{
className : 'doctag',
begin : '@[A-Za-z]+',
contains : [
{
className: 'type',
begin: '\\{',
end: '\\}',
relevance: 0
},
{
className: 'variable',
begin: IDENT_RE + '(?=\\s*(-)|$)',
endsParent: true,
relevance: 0
},
// eat spaces (not newlines) so we can find
// types or variables
{
begin: /(?=[^\n])\s/,
relevance: 0
},
]
}
]
}
),
hljs.C_BLOCK_COMMENT_MODE,
NUMBER,
{ // object attr container
begin: regex.concat(/[{,\n]\s*/,
// we need to look ahead to make sure that we actually have an
// attribute coming up so we don't steal a comma from a potential
// "value" container
//
// NOTE: this might not work how you think. We don't actually always
// enter this mode and stay. Instead it might merely match `,
// <comments up next>` and then immediately end after the , because it
// fails to find any actual attrs. But this still does the job because
// it prevents the value contain rule from grabbing this instead and
// prevening this rule from firing when we actually DO have keys.
regex.lookahead(regex.concat(
// we also need to allow for multiple possible comments inbetween
// the first key:value pairing
/(((\/\/.*)|(\/\*(.|\n)*\*\/))\s*)*/,
IDENT_RE + '\\s*:'))),
relevance: 0,
contains: [
{
className: 'attr',
begin: IDENT_RE + regex.lookahead('\\s*:'),
relevance: 0,
},
]
},
{ // "value" container
begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
keywords: 'return throw case',
contains: [
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
hljs.REGEXP_MODE,
{
className: 'function',
// we have to count the parens to make sure we actually have the
// correct bounding ( ) before the =>. There could be any number of
// sub-expressions inside also surrounded by parens.
begin: '(\\([^(]*' +
'(\\([^(]*' +
'(\\([^(]*' +
'\\))?' +
'\\))?' +
'\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\s*=>', returnBegin: true,
end: '\\s*=>',
contains: [
{
className: 'params',
variants: [
{
begin: hljs.UNDERSCORE_IDENT_RE
},
{
className: null,
begin: /\(\s*\)/,
skip: true
},
{
begin: /\(/, end: /\)/,
excludeBegin: true, excludeEnd: true,
keywords: KEYWORDS,
contains: PARAMS_CONTAINS
}
]
}
]
},
{ // could be a comma delimited list of params to a function call
begin: /,/, relevance: 0,
},
{
className: '',
begin: /\s/,
end: /\s*/,
skip: true,
},
{ // JSX
variants: [
{ begin: FRAGMENT.begin, end: FRAGMENT.end },
{ begin: XML_TAG.begin, end: XML_TAG.end }
],
subLanguage: 'xml',
contains: [
{
begin: XML_TAG.begin, end: XML_TAG.end, skip: true,
contains: ['self']
}
]
},
],
relevance: 0
},
{
className: 'function',
beginKeywords: 'function', end: /\{/, excludeEnd: true,
contains: [
hljs.inherit(hljs.TITLE_MODE, {begin: IDENT_RE}),
PARAMS
],
illegal: /\[|%/
},
{
begin: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
},
hljs.METHOD_GUARD,
{ // ES6 class
className: 'class',
beginKeywords: 'class', end: /[{;=]/, excludeEnd: true,
illegal: /[:"\[\]]/,
contains: [
{beginKeywords: 'extends'},
hljs.UNDERSCORE_TITLE_MODE
]
},
{
beginKeywords: 'constructor', end: /\{/, excludeEnd: true
},
{
begin: '(get|set)\\s+(?=' + IDENT_RE + '\\()',
end: /{/,
keywords: "get set",
contains: [
hljs.inherit(hljs.TITLE_MODE, {begin: IDENT_RE}),
{ begin: /\(\)/ }, // eat to avoid empty params
PARAMS
]
}
],
illegal: /#(?!!)/
};
}