You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
696 lines
16 KiB
JavaScript
696 lines
16 KiB
JavaScript
export function colorize() {
|
|
const isEditor = this.tag == "plaintext";
|
|
|
|
let doStyle;
|
|
let doScript;
|
|
|
|
function doMarkup(tz) {
|
|
let tagStart = null; // [node,offset]
|
|
let tagScript = false;
|
|
let tagScriptType = false;
|
|
let tagStyle = false;
|
|
let textElement;
|
|
|
|
let tt;
|
|
|
|
while (tt = tz.nextToken()) {
|
|
if (isEditor && tz.element != textElement) {
|
|
textElement = tz.element;
|
|
textElement.setAttribute("type", "markup");
|
|
}
|
|
switch (tt) {
|
|
case "tag-start": {
|
|
tagStart = tz.tokenRange.start;
|
|
const tag = tz.markupTag;
|
|
tagScript = tag == "script";
|
|
tagStyle = tag == "style";
|
|
break;
|
|
}
|
|
case "tag-head-end": {
|
|
(new Range(tagStart, tz.tokenRange.end)).highlight("tag");
|
|
if (tagScript) {
|
|
tz.push(tagScriptType, "");
|
|
doScript(tz, tagScriptType, true);
|
|
} else if (tagStyle) {
|
|
tz.push("text/css", "");
|
|
doStyle(tz, true);
|
|
}
|
|
break;
|
|
}
|
|
case "tag-end": tz.tokenRange.highlight("tag"); break;
|
|
case "tag-attr": {
|
|
if (tagScript && tz.markupAttributeName == "type") tagScriptType = tz.markupAttributeValue;
|
|
if (tz.markupAttributeName == "id") tz.tokenRange.highlight("tag-id");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
doScript = function(tz, typ, embedded = false) {
|
|
const KEYWORDS_C = [
|
|
"alignas",
|
|
"alignof",
|
|
"and",
|
|
"and_eq",
|
|
"asm",
|
|
"atomic_cancel",
|
|
"atomic_commit",
|
|
"atomic_noexcept",
|
|
"auto",
|
|
"bitand",
|
|
"bitor",
|
|
"bool",
|
|
"break",
|
|
"case",
|
|
"catch",
|
|
"char",
|
|
"char16_t",
|
|
"char32_t",
|
|
"char8_t",
|
|
"class",
|
|
"compl",
|
|
"concept",
|
|
"const",
|
|
"consteval",
|
|
"constexpr",
|
|
"constinit",
|
|
"const_cast",
|
|
"continue",
|
|
"co_await",
|
|
"co_return",
|
|
"co_yield",
|
|
"decltype",
|
|
"default",
|
|
"delete",
|
|
"do",
|
|
"double",
|
|
"dynamic_cast",
|
|
"else",
|
|
"endif",
|
|
"enum",
|
|
"explicit",
|
|
"export",
|
|
"extern",
|
|
"float",
|
|
"for",
|
|
"friend",
|
|
"goto",
|
|
"if",
|
|
"include",
|
|
"inline",
|
|
"int",
|
|
"long",
|
|
"mutable",
|
|
"namespace",
|
|
"new",
|
|
"noexcept",
|
|
"not",
|
|
"not_eq",
|
|
"nullptr",
|
|
"operator",
|
|
"or",
|
|
"or_eq",
|
|
"private",
|
|
"protected",
|
|
"public",
|
|
"reflexpr",
|
|
"register",
|
|
"reinterpret_cast",
|
|
"requires",
|
|
"return",
|
|
"short",
|
|
"signed",
|
|
"sizeof",
|
|
"static",
|
|
"static_assert",
|
|
"static_cast",
|
|
"struct",
|
|
"switch",
|
|
"synchronized",
|
|
"template",
|
|
"this",
|
|
"thread_local",
|
|
"throw",
|
|
"try",
|
|
"typedef",
|
|
"typeid",
|
|
"typename",
|
|
"union",
|
|
"unsigned",
|
|
"using",
|
|
"virtual",
|
|
"void",
|
|
"volatile",
|
|
"wchar_t",
|
|
"while",
|
|
"xor",
|
|
"xor_eq"
|
|
];
|
|
const LITERALS_C = [ "true", "false", "null" ];
|
|
const SUPPORT_C = [
|
|
"pow", "sqrt", "min", "max", "swap", "gcd", "toupper", "tolower",
|
|
"floor", "ceil", "struct", "union", "enum"
|
|
];
|
|
|
|
const KEYWORDS_PHP = [
|
|
"abstract", "and", "as", "break", "callable", "case", "catch", "class",
|
|
"clone", "const", "continue", "declare", "default",
|
|
"do", "echo", "else", "elseif", "enddeclare", "endfor", "endforeach", "endif",
|
|
"endswitch", "endwhile", "extends", "final", "finally", "fn", "for", "foreach",
|
|
"function", "global", "goto", "if", "implements", "include", "include_once",
|
|
"instanceof", "insteadof", "interface", "match", "namespace", "new", "or", "print",
|
|
"private", "protected", "public", "readonly", "require", "require_once", "return",
|
|
"static", "switch", "throw", "trait", "try", "use", "var", "while", "xor", "yield",
|
|
"yield", "from"
|
|
];
|
|
|
|
const LITERALS_PHP = [ "true", "false", "null" ];
|
|
const SUPPORT_PHP = [
|
|
"array",
|
|
"array_diff",
|
|
"array_filter",
|
|
"array_keys",
|
|
"array_key_exists",
|
|
"array_map",
|
|
"array_merge",
|
|
"array_pop",
|
|
"array_push",
|
|
"array_reverse",
|
|
"array_search",
|
|
"array_shift",
|
|
"array_slice",
|
|
"array_unique",
|
|
"array_unshift",
|
|
"array_values",
|
|
"base64_encode",
|
|
"basename",
|
|
"call_user_func",
|
|
"call_user_func_array",
|
|
"ceil",
|
|
"chr",
|
|
"class_exists",
|
|
"count",
|
|
"date",
|
|
"define",
|
|
"defined",
|
|
"die",
|
|
"dir",
|
|
"dirname",
|
|
"each",
|
|
"echo",
|
|
"empty",
|
|
"end",
|
|
"error_reporting",
|
|
"eval",
|
|
"exit",
|
|
"explode",
|
|
"extension_loaded",
|
|
"fclose",
|
|
"file",
|
|
"file_exists",
|
|
"file_get_contents",
|
|
"file_put_contents",
|
|
"floor",
|
|
"fmod",
|
|
"fopen",
|
|
"function_exists",
|
|
"func_get_args",
|
|
"fwrite",
|
|
"gettype",
|
|
"get_class",
|
|
"header",
|
|
"htmlspecialchars",
|
|
"idate",
|
|
"implode",
|
|
"ini_get",
|
|
"ini_set",
|
|
"intval",
|
|
"in_a",
|
|
"in_array",
|
|
"isset",
|
|
"is_array",
|
|
"is_bool",
|
|
"is_callable",
|
|
"is_dir",
|
|
"is_file",
|
|
"is_int",
|
|
"is_null",
|
|
"is_numeric",
|
|
"is_object",
|
|
"is_string",
|
|
"json_decode",
|
|
"json_encode",
|
|
"ksort",
|
|
"link",
|
|
"list",
|
|
"log",
|
|
"ltrim",
|
|
"mail",
|
|
"max",
|
|
"md5",
|
|
"method_exists",
|
|
"microtime",
|
|
"min",
|
|
"mkdir",
|
|
"ob_start",
|
|
"ord",
|
|
"parse_url",
|
|
"pos",
|
|
"preg_match",
|
|
"preg_match_all",
|
|
"preg_replace",
|
|
"preg_split",
|
|
"printf",
|
|
"print_r",
|
|
"realpath",
|
|
"reset",
|
|
"round",
|
|
"rtrim",
|
|
"serialize",
|
|
"sort",
|
|
"sprintf",
|
|
"stripos",
|
|
"strlen",
|
|
"strpos",
|
|
"strrpos",
|
|
"strtolower",
|
|
"strtotime",
|
|
"strtoupper",
|
|
"strtr",
|
|
"str_repeat",
|
|
"str_replace",
|
|
"substr",
|
|
"time",
|
|
"trim",
|
|
"ucfirst",
|
|
"uniqid",
|
|
"unlink",
|
|
"unserialize",
|
|
"unset",
|
|
"urlencode",
|
|
"version_compare",
|
|
];
|
|
|
|
const KEYWORDS_JS = [
|
|
"abstract",
|
|
"arguments",
|
|
"assert",
|
|
"async",
|
|
"await",
|
|
"boolean",
|
|
"break",
|
|
"byte",
|
|
"case",
|
|
"catch",
|
|
"char",
|
|
"class",
|
|
"const",
|
|
"continue",
|
|
"debug",
|
|
"debugger",
|
|
"default",
|
|
"delete",
|
|
"do",
|
|
"double",
|
|
"else",
|
|
"enum",
|
|
"eval",
|
|
"export",
|
|
"extends",
|
|
"final",
|
|
"finally",
|
|
"float",
|
|
"for",
|
|
"function",
|
|
"get",
|
|
"goto",
|
|
"if",
|
|
"implements",
|
|
"import",
|
|
"in",
|
|
"include",
|
|
"instanceof",
|
|
"int",
|
|
"interface",
|
|
"let",
|
|
"like",
|
|
"long",
|
|
"namespace",
|
|
"native",
|
|
"new",
|
|
"of",
|
|
"otherwise",
|
|
"package",
|
|
"private",
|
|
"property",
|
|
"protected",
|
|
"public",
|
|
"return",
|
|
"set",
|
|
"short",
|
|
"static",
|
|
"super",
|
|
"switch",
|
|
"synchronized",
|
|
"this",
|
|
"throw",
|
|
"throws",
|
|
"transient",
|
|
"try",
|
|
"type",
|
|
"typeof",
|
|
"var",
|
|
"void",
|
|
"volatile",
|
|
"while",
|
|
"with",
|
|
"yield",
|
|
"__file__",
|
|
"__line__",
|
|
"__trace__",
|
|
];
|
|
const LITERALS_JS = [ "true", "false", "null", "undefined", "Infinity", "NaN" ];
|
|
const SUPPORT_JS = [
|
|
"addEventListener",
|
|
"appendChild",
|
|
"Array",
|
|
"ArrayBuffer",
|
|
"AsyncFunction",
|
|
"AsyncGenerator",
|
|
"AsyncGeneratorFunction",
|
|
"AsyncIterator",
|
|
"Atomics",
|
|
"BigInt",
|
|
"Boolean",
|
|
"clearInterval",
|
|
"clearTimeout",
|
|
"createElement",
|
|
"DataView",
|
|
"Date",
|
|
"decodeURI",
|
|
"decodeURIComponent",
|
|
"dispatchEvent",
|
|
"document",
|
|
"encodeURI",
|
|
"encodeURIComponent",
|
|
"escape",
|
|
"eval",
|
|
"extends",
|
|
"fetch",
|
|
"Function",
|
|
"Generator",
|
|
"GeneratorFunction",
|
|
"getAttribute",
|
|
"getComputedStyle",
|
|
"getElementById",
|
|
"getElementsByClassName",
|
|
"getElementsByTagName",
|
|
"getSelection",
|
|
"isFinite",
|
|
"isNaN",
|
|
"Iterator",
|
|
"JSON",
|
|
"Map",
|
|
"Math",
|
|
"Number",
|
|
"Object",
|
|
"parseFloat",
|
|
"parseInt",
|
|
"Promise",
|
|
"promise",
|
|
"Proxy",
|
|
"push",
|
|
"Reflect",
|
|
"RegExp",
|
|
"removeChild",
|
|
"removeEventListener",
|
|
"replace",
|
|
"Set",
|
|
"setAttribute",
|
|
"setInterval",
|
|
"setTimeout",
|
|
"SharedArrayBuffer",
|
|
"String",
|
|
"Symbol",
|
|
"unescape",
|
|
"WeakMap",
|
|
"WeakSet",
|
|
"window"
|
|
];
|
|
|
|
const KEYWORDS_DELPHI = [
|
|
"end" , "array" , "begin" , "dispinterface" ,
|
|
"finalization" , "goto" , "implementation" , "inherited" ,
|
|
"initialization" , "label" , "of" , "packed" ,
|
|
"set" , "type" , "uses" , "with" ,
|
|
"constructor" , "destructor" , "function" , "operator" ,
|
|
"procedure" , "property" , "const" , "out" ,
|
|
"threadvar" , "var" , "for" , "to" ,
|
|
"downto" , "while" , "repeat" , "until" ,
|
|
"do" , "if" , "then" , "case" ,
|
|
"else" , "try" , "finally" , "except" ,
|
|
"on" , "raise" , "at" , "class" ,
|
|
"interface" , "object" , "record" , "cdecl" ,
|
|
"pascal" , "register" , "safecall" , "stdcall" ,
|
|
"winapi" , "library" , "package" , "program" ,
|
|
"unit" , "absolute" , "abstract" , "assembler" ,
|
|
"delayed" , "deprecated" , "dispid" , "dynamic" ,
|
|
"experimental" , "export" , "external" , "final" ,
|
|
"forward" , "implements" , "inline" , "name" ,
|
|
"message" , "overload" , "override" , "packed" ,
|
|
"platform" , "readonly" , "reintroduce" , "static" ,
|
|
"unsafe" , "varargs" , "virtual" , "writeonly" ,
|
|
"helper" , "reference" , "sealed" , "contains" ,
|
|
"requires" , "far" , "near" , "resident" ,
|
|
"private" , "protected" , "public" , "published" ,
|
|
"strict" , "default" , "index" , "node" ,
|
|
"fault" , "read" , "stored" , "write" ,
|
|
"and" , "as" , "div" , "in" ,
|
|
"is" , "mod" , "not" , "or" ,
|
|
"shr" , "shl" , "xor" ,
|
|
|
|
// types
|
|
"byte" , "integer" , "cardinal" , "pointer" ,
|
|
"single" , "double" , "extended" , "comp" ,
|
|
"currency" , "bool" , "dword" , "ulong" ,
|
|
"hdc" , "hresult" , "hwnd" , "word" ,
|
|
"longword" , "longbool" , "boolean" , "shortint" ,
|
|
"smallint" , "longint" , "nativeint" , "nativeuint" ,
|
|
"uint8" , "uint16" , "uint32" , "uint64" ,
|
|
"uint128" , "int8" , "int16" , "int32" ,
|
|
"int64" , "int128" , "ansichar" , "ansistring" ,
|
|
"real48" , "real" , "widechar" , "widestring" ,
|
|
"unicodestring" , "shortstring" , "rawbytestring" , "variant" ,
|
|
"olevariant"
|
|
];
|
|
|
|
const LITERALS_DELPHI = [ "true", "false", "nil" ];
|
|
const SUPPORT_DELPHI = [ "result", "self", "assert" ];
|
|
|
|
const LITERALS_JSON = [ "true", "false", "null" ];
|
|
|
|
const KEYWORDS_COMMON = [
|
|
"begin" , "end" , "and" , "array" ,
|
|
"as" , "bool" , "boolean" , "break" ,
|
|
"case" , "catch" , "char" , "class" ,
|
|
"const" , "continue" , "def" , "delete" ,
|
|
"do" , "double" , "echo" , "else" ,
|
|
"elseif" , "exit" , "extends" , "except" ,
|
|
"finally" , "float" , "for" , "foreach" ,
|
|
"function" , "global" , "if" , "import" ,
|
|
"int" , "integer" , "long" , "new" ,
|
|
"object" , "or" , "print" , "private" ,
|
|
"protected" , "public" , "return" , "self" ,
|
|
"string" , "struct" , "static" , "switch" ,
|
|
"then" , "this" , "throw" , "try" ,
|
|
"signed" , "unsigned" , "var" , "void" ,
|
|
"while" , "procedure"
|
|
];
|
|
|
|
var KEYWORDS = [];
|
|
var LITERALS = [];
|
|
var SUPPORT = [];
|
|
|
|
if (typ == "text/x-pascal") {
|
|
KEYWORDS = KEYWORDS_DELPHI;
|
|
LITERALS = LITERALS_DELPHI;
|
|
SUPPORT = SUPPORT_DELPHI;
|
|
} else if (typ == "text/x-c") {
|
|
KEYWORDS = KEYWORDS_C;
|
|
LITERALS = LITERALS_C;
|
|
SUPPORT = SUPPORT_C;
|
|
} else if (typ == "application/x-php") {
|
|
KEYWORDS = KEYWORDS_PHP;
|
|
LITERALS = LITERALS_PHP;
|
|
SUPPORT = SUPPORT_PHP;
|
|
} else if (typ == "text/javascript") {
|
|
KEYWORDS = KEYWORDS_JS;
|
|
LITERALS = LITERALS_JS;
|
|
SUPPORT = SUPPORT_JS;
|
|
} else if (typ == "application/json") {
|
|
LITERALS = LITERALS_JSON;
|
|
} else {
|
|
LITERALS = LITERALS_JSON;
|
|
KEYWORDS = KEYWORDS_COMMON;
|
|
SUPPORT = SUPPORT_DELPHI;
|
|
}
|
|
|
|
let firstElement = null;
|
|
let lastElement = null;
|
|
|
|
let tt;
|
|
let isVal = false;
|
|
let isInArr = false;
|
|
|
|
loop: while (tt = tz.nextToken()) {
|
|
var el = tz.element;
|
|
firstElement = firstElement || el;
|
|
lastElement = el;
|
|
switch (tt) {
|
|
case "number": tz.tokenRange.highlight("number"); break;
|
|
case "number-unit": tz.tokenRange.highlight("number-unit"); break;
|
|
case "string": {
|
|
if ((typ == "application/json" && (isVal || isInArr)) || typ !== "application/json")
|
|
tz.tokenRange.highlight("string");
|
|
break;
|
|
}
|
|
case "operator": {
|
|
isVal = tz.tokenValue == ":";
|
|
if (tz.tokenValue == "[")
|
|
isInArr = true;
|
|
else if (tz.tokenValue == "]" || tz.tokenValue == "{")
|
|
isInArr = false;
|
|
break;
|
|
}
|
|
case "name": {
|
|
const val = tz.tokenValue;
|
|
if (val[0] == '#' || val[0] == '$')
|
|
tz.tokenRange.highlight("symbol");
|
|
else if (KEYWORDS.includes(val))
|
|
tz.tokenRange.highlight("keyword");
|
|
else if (LITERALS.includes(val))
|
|
tz.tokenRange.highlight("literal");
|
|
else if (SUPPORT.includes(val))
|
|
tz.tokenRange.highlight("support");
|
|
break;
|
|
}
|
|
case "comment": tz.tokenRange.highlight("comment"); break;
|
|
case "island-end":
|
|
tz.pop();
|
|
break loop;
|
|
}
|
|
if (tt !== "operator") isVal = false;
|
|
}
|
|
if (isEditor && embedded) {
|
|
for (var el = firstElement; el; el = el.nextElementSibling) {
|
|
if (el == lastElement)
|
|
break;
|
|
el.setAttribute("type", "script");
|
|
}
|
|
}
|
|
};
|
|
|
|
doStyle = function(tz, embedded = false) {
|
|
const KEYWORDS =
|
|
{
|
|
"rgb": true, "rgba": true, "url": true, "var": true,
|
|
"@import": true, "@media": true, "@set": true, "@const": true,
|
|
"@mixin": true, "@supports": true,
|
|
};
|
|
|
|
const LITERALS = {"inherit": true};
|
|
|
|
let firstElement;
|
|
let lastElement;
|
|
|
|
let tt;
|
|
|
|
loop: while (tt = tz.nextToken()) {
|
|
var el = tz.element;
|
|
if (!firstElement) firstElement = el;
|
|
lastElement = el;
|
|
switch (tt) {
|
|
case "number": tz.tokenRange.highlight("number"); break;
|
|
case "number-unit": tz.tokenRange.highlight("number-unit"); break;
|
|
case "string": tz.tokenRange.highlight("string"); break;
|
|
case "name":
|
|
{
|
|
const val = tz.tokenValue;
|
|
if (val[0] == "#")
|
|
tz.tokenRange.highlight("literal");
|
|
else if (KEYWORDS[val])
|
|
tz.tokenRange.highlight("keyword");
|
|
else if (LITERALS[val])
|
|
tz.tokenRange.highlight("literal");
|
|
break;
|
|
}
|
|
case "comment": tz.tokenRange.highlight("comment"); break;
|
|
case "island-end":
|
|
// got
|
|
tz.pop(); // pop tokenizer layer
|
|
break loop;
|
|
}
|
|
}
|
|
if (isEditor && embedded) {
|
|
for (var el = firstElement; el; el = el.nextElementSibling) {
|
|
if (el == lastElement) break;
|
|
el.setAttribute("type", "style");
|
|
}
|
|
}
|
|
};
|
|
|
|
const me = this;
|
|
|
|
function doIt() {
|
|
if (me.attributes["nosyntax"] === "true") return;
|
|
var syntax = me.attributes["type"];
|
|
|
|
if (syntax === "htm" || syntax === "html") syntax = "text/html";
|
|
else if (syntax === "js") syntax = "text/javascript";
|
|
else if (syntax === "css") syntax = "text/css";
|
|
else if (syntax === "json") syntax = "application/json";
|
|
else if (syntax === "php") syntax = "application/x-php";
|
|
else if (syntax === "delphi" || syntax === "pas") syntax = "text/x-pascal";
|
|
else if (syntax === "c") syntax = "text/x-c";
|
|
else if (syntax === "") syntax = "text/script";
|
|
|
|
if (!syntax.includes("/")) syntax = "text/plain";
|
|
|
|
const tz = new Tokenizer(me, syntax);
|
|
|
|
if (syntax.endsWith("/htm") || syntax.endsWith("/html") || syntax.endsWith("/svg") || syntax.endsWith("/xml"))
|
|
doMarkup(tz);
|
|
else if (syntax.endsWith("/css"))
|
|
doStyle(tz);
|
|
else
|
|
doScript(tz, syntax);
|
|
}
|
|
doIt();
|
|
|
|
Object.defineProperty(me, "value", {
|
|
get: function() {
|
|
return me.state.value;
|
|
},
|
|
set: function(value) {
|
|
me.state.value = value;
|
|
doIt();
|
|
},
|
|
});
|
|
|
|
Object.defineProperty(me, "colorize", {
|
|
value: function() { doIt(); },
|
|
});
|
|
|
|
if (isEditor) {
|
|
this.loadContent = function(text) {
|
|
this.plaintext.content = text;
|
|
doIt();
|
|
};
|
|
|
|
this.on("change", function() {
|
|
this.timer(40, doIt);
|
|
});
|
|
}
|
|
}
|