WebOrbiton
v1.0.0.1

StocketBase

296 lines · 10.9 KB
  1. (function () {
  2. 'use strict';
  3. ​
  4. var STRING = /"(?:\\.|[^"\\\n])*"|'(?:\\.|[^'\\\n])*'/.source;
  5. var NUMBER = /\b0x[\da-f]+\b|\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/.source;
  6. var FUNCTION = /[A-Za-z_$][\w$]*(?=\s*\()/.source;
  7. ​
  8. function words(list) {
  9. return '\\b(?:' + list.join('|') + ')\\b';
  10. }
  11. ​
  12. var JS_KEYWORDS = ['async', 'await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'export', 'extends', 'finally', 'for', 'from', 'function', 'if', 'import', 'in', 'instanceof', 'let', 'new', 'of', 'return', 'static', 'super', 'switch', 'throw', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield', 'interface', 'type', 'enum', 'implements', 'public', 'private', 'protected', 'readonly'];
  13. var PHP_KEYWORDS = ['abstract', 'and', 'array', 'as', 'break', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'extends', 'final', 'finally', 'fn', 'for', 'foreach', 'function', 'global', 'if', 'implements', 'include', 'include_once', 'instanceof', 'interface', 'isset', 'list', 'match', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'readonly', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor', 'yield'];
  14. var PY_KEYWORDS = ['and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield'];
  15. var SQL_KEYWORDS = ['select', 'from', 'where', 'and', 'or', 'not', 'in', 'is', 'null', 'insert', 'into', 'values', 'update', 'set', 'delete', 'create', 'table', 'alter', 'drop', 'add', 'column', 'index', 'primary', 'key', 'foreign', 'references', 'join', 'left', 'right', 'inner', 'outer', 'on', 'as', 'group', 'by', 'order', 'having', 'limit', 'offset', 'distinct', 'union', 'all', 'exists', 'between', 'like', 'case', 'when', 'then', 'else', 'end', 'default', 'unique', 'if', 'engine', 'auto_increment', 'asc', 'desc', 'count', 'sum', 'avg', 'min', 'max'];
  16. var BASH_KEYWORDS = ['if', 'then', 'else', 'elif', 'fi', 'for', 'while', 'do', 'done', 'case', 'esac', 'function', 'in', 'return', 'exit', 'export', 'local', 'echo', 'cd', 'sudo', 'source'];
  17. var CLIKE_KEYWORDS = ['abstract', 'as', 'break', 'case', 'catch', 'char', 'class', 'const', 'continue', 'default', 'do', 'double', 'else', 'enum', 'extends', 'final', 'finally', 'float', 'for', 'fn', 'func', 'go', 'if', 'impl', 'import', 'in', 'int', 'interface', 'let', 'long', 'match', 'mut', 'namespace', 'new', 'package', 'private', 'protected', 'public', 'return', 'short', 'static', 'struct', 'super', 'switch', 'this', 'throw', 'throws', 'try', 'typedef', 'unsigned', 'use', 'using', 'var', 'virtual', 'void', 'volatile', 'while'];
  18. var LITERALS = ['true', 'false', 'null', 'undefined', 'NaN', 'Infinity', 'this', 'None', 'True', 'False', 'self', 'nil', 'TRUE', 'FALSE', 'NULL'];
  19. ​
  20. var LANGUAGES = {
  21. javascript: {
  22. rules: [
  23. ['comment', /\/\/[^\n]*|\/\*[\s\S]*?\*\//.source],
  24. ['string', /`(?:\\[\s\S]|[^`\\])*`/.source + '|' + STRING],
  25. ['keyword', words(JS_KEYWORDS)],
  26. ['literal', words(LITERALS)],
  27. ['function', FUNCTION],
  28. ['number', NUMBER]
  29. ]
  30. },
  31. css: {
  32. rules: [
  33. ['comment', /\/\*[\s\S]*?\*\//.source],
  34. ['string', STRING],
  35. ['keyword', /@[\w-]+/.source],
  36. ['attr', /[\w-]+(?=\s*:[^;{}]*[;}])/.source],
  37. ['tag', /[.#][A-Za-z_][\w-]*(?=[^;{}]*\{)/.source],
  38. ['number', /#[\da-f]{3,8}\b|-?\d*\.?\d+(?:px|em|rem|%|vh|vw|s|ms|deg|fr)?/.source],
  39. ['function', /[\w-]+(?=\()/.source]
  40. ]
  41. },
  42. php: {
  43. rules: [
  44. ['comment', /\/\/[^\n]*|#[^\n]*|\/\*[\s\S]*?\*\//.source],
  45. ['string', STRING],
  46. ['keyword', /<\?php|<\?=|\?>/.source + '|' + words(PHP_KEYWORDS)],
  47. ['variable', /\$[A-Za-z_]\w*/.source],
  48. ['literal', words(LITERALS)],
  49. ['function', FUNCTION],
  50. ['number', NUMBER]
  51. ]
  52. },
  53. python: {
  54. rules: [
  55. ['comment', /#[^\n]*/.source],
  56. ['string', /'''[\s\S]*?'''|"""[\s\S]*?"""/.source + '|' + STRING],
  57. ['keyword', words(PY_KEYWORDS)],
  58. ['literal', words(LITERALS)],
  59. ['tag', /@\w+/.source],
  60. ['function', FUNCTION],
  61. ['number', NUMBER]
  62. ]
  63. },
  64. sql: {
  65. flags: 'gi',
  66. rules: [
  67. ['comment', /--[^\n]*|\/\*[\s\S]*?\*\//.source],
  68. ['string', /'(?:''|[^'])*'/.source],
  69. ['keyword', words(SQL_KEYWORDS)],
  70. ['function', /[A-Za-z_]\w*(?=\s*\()/.source],
  71. ['number', NUMBER]
  72. ]
  73. },
  74. bash: {
  75. rules: [
  76. ['comment', /#[^\n]*/.source],
  77. ['string', STRING],
  78. ['variable', /\$(?:\w+|\{[^}]*\})/.source],
  79. ['keyword', words(BASH_KEYWORDS)],
  80. ['attr', /(?:^|\s)--?[A-Za-z][\w-]*/.source],
  81. ['number', NUMBER]
  82. ]
  83. },
  84. json: {
  85. rules: [
  86. ['attr', /"(?:\\.|[^"\\\n])*"(?=\s*:)/.source],
  87. ['string', STRING],
  88. ['literal', words(['true', 'false', 'null'])],
  89. ['number', /-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/.source]
  90. ]
  91. },
  92. clike: {
  93. rules: [
  94. ['comment', /\/\/[^\n]*|\/\*[\s\S]*?\*\//.source],
  95. ['string', STRING],
  96. ['keyword', words(CLIKE_KEYWORDS)],
  97. ['literal', words(LITERALS)],
  98. ['function', FUNCTION],
  99. ['number', NUMBER]
  100. ]
  101. }
  102. };
  103. ​
  104. var ALIASES = {
  105. js: 'javascript', jsx: 'javascript', ts: 'javascript', tsx: 'javascript', typescript: 'javascript', node: 'javascript',
  106. scss: 'css', less: 'css',
  107. py: 'python',
  108. mysql: 'sql', sqlite: 'sql', postgresql: 'sql',
  109. sh: 'bash', shell: 'bash', zsh: 'bash',
  110. java: 'clike', c: 'clike', cpp: 'clike', csharp: 'clike', cs: 'clike', go: 'clike', rust: 'clike', kotlin: 'clike', swift: 'clike',
  111. html: 'markup', xml: 'markup', svg: 'markup', htm: 'markup'
  112. };
  113. ​
  114. var compiled = {};
  115. ​
  116. function escapeHtml(text) {
  117. return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  118. }
  119. ​
  120. function span(className, text) {
  121. return '<span class="tok-' + className + '">' + escapeHtml(text) + '</span>';
  122. }
  123. ​
  124. function scan(source, pattern, handler) {
  125. var output = '';
  126. var last = 0;
  127. var match;
  128. ​
  129. pattern.lastIndex = 0;
  130. while ((match = pattern.exec(source)) !== null) {
  131. if (match[0] === '') {
  132. pattern.lastIndex++;
  133. continue;
  134. }
  135. output += escapeHtml(source.slice(last, match.index)) + handler(match);
  136. last = pattern.lastIndex;
  137. }
  138. ​
  139. return output + escapeHtml(source.slice(last));
  140. }
  141. ​
  142. function compile(name) {
  143. if (compiled[name]) {
  144. return compiled[name];
  145. }
  146. ​
  147. var spec = LANGUAGES[name];
  148. var source = spec.rules.map(function (rule) {
  149. return '(' + rule[1] + ')';
  150. }).join('|');
  151. ​
  152. compiled[name] = { pattern: new RegExp(source, spec.flags || 'g'), rules: spec.rules };
  153. ​
  154. return compiled[name];
  155. }
  156. ​
  157. function highlightTag(tag) {
  158. var parts = tag.match(/^<(\/?)([^\s>\/]+)([\s\S]*?)(\/?)>$/);
  159. if (!parts) {
  160. return escapeHtml(tag);
  161. }
  162. ​
  163. var attributes = scan(parts[3], /([^\s=\/>]+)(?:(\s*=\s*)("[^"]*"|'[^']*'|[^\s"'>]+))?/g, function (match) {
  164. return span('attr', match[1]) + (match[2] ? escapeHtml(match[2]) + span('string', match[3]) : '');
  165. });
  166. ​
  167. return escapeHtml('<' + parts[1]) + span('tag', parts[2]) + attributes + escapeHtml(parts[4] + '>');
  168. }
  169. ​
  170. function highlightMarkup(source) {
  171. var pattern = /<!--[\s\S]*?-->|<!doctype[^>]*>|<(script|style)\b[^>]*>[\s\S]*?<\/\1\s*>|<\/?[A-Za-z][^>]*>/gi;
  172. ​
  173. return scan(source, pattern, function (match) {
  174. var text = match[0];
  175. ​
  176. if (text.indexOf('<!--') === 0) {
  177. return span('comment', text);
  178. }
  179. if (text.charAt(1) === '!') {
  180. return span('keyword', text);
  181. }
  182. if (match[1]) {
  183. var open = text.match(/^<[^>]*>/)[0];
  184. var close = text.match(/<\/[^>]*>$/)[0];
  185. var body = text.slice(open.length, text.length - close.length);
  186. ​
  187. return highlightTag(open) + highlight(body, match[1].toLowerCase() === 'style' ? 'css' : 'javascript') + highlightTag(close);
  188. }
  189. ​
  190. return highlightTag(text);
  191. });
  192. }
  193. ​
  194. function highlight(source, language) {
  195. var name = ALIASES[language] || language;
  196. ​
  197. if (name === 'markup') {
  198. return highlightMarkup(source);
  199. }
  200. if (!LANGUAGES[name]) {
  201. return escapeHtml(source);
  202. }
  203. ​
  204. var compiledLanguage = compile(name);
  205. ​
  206. return scan(source, compiledLanguage.pattern, function (match) {
  207. for (var index = 0; index < compiledLanguage.rules.length; index++) {
  208. if (match[index + 1] !== undefined) {
  209. return span(compiledLanguage.rules[index][0], match[0]);
  210. }
  211. }
  212. ​
  213. return escapeHtml(match[0]);
  214. });
  215. }
  216. ​
  217. function languageOf(code) {
  218. var match = /(?:^|\s)language-([\w+#-]+)/.exec(code.className);
  219. ​
  220. return match ? match[1].toLowerCase() : '';
  221. }
  222. ​
  223. function initHighlight() {
  224. document.querySelectorAll('pre > code[class*="language-"]').forEach(function (code) {
  225. var language = languageOf(code);
  226. var name = ALIASES[language] || language;
  227. ​
  228. if (name !== 'markup' && !LANGUAGES[name]) {
  229. return;
  230. }
  231. if (code.textContent.length > 60000) {
  232. return;
  233. }
  234. ​
  235. code.innerHTML = highlight(code.textContent, language);
  236. code.classList.add('is-highlighted');
  237. });
  238. }
  239. ​
  240. function copyText(text) {
  241. if (navigator.clipboard && window.isSecureContext) {
  242. return navigator.clipboard.writeText(text);
  243. }
  244. ​
  245. return new Promise(function (resolve, reject) {
  246. var field = document.createElement('textarea');
  247. field.value = text;
  248. field.setAttribute('readonly', '');
  249. field.style.position = 'fixed';
  250. field.style.opacity = '0';
  251. document.body.appendChild(field);
  252. field.select();
  253. ​
  254. try {
  255. document.execCommand('copy') ? resolve() : reject();
  256. } catch (error) {
  257. reject(error);
  258. }
  259. ​
  260. document.body.removeChild(field);
  261. });
  262. }
  263. ​
  264. function initCopy() {
  265. document.querySelectorAll('.code-block .code-copy').forEach(function (button) {
  266. button.addEventListener('click', function () {
  267. var code = button.parentNode.querySelector('code');
  268. if (!code) {
  269. return;
  270. }
  271. ​
  272. copyText(code.textContent).then(function () {
  273. button.textContent = button.getAttribute('data-copied');
  274. button.classList.add('is-copied');
  275. ​
  276. setTimeout(function () {
  277. button.textContent = button.getAttribute('data-label');
  278. button.classList.remove('is-copied');
  279. }, 1800);
  280. });
  281. });
  282. });
  283. }
  284. ​
  285. function init() {
  286. initHighlight();
  287. initCopy();
  288. }
  289. ​
  290. if (document.readyState === 'loading') {
  291. document.addEventListener('DOMContentLoaded', init);
  292. } else {
  293. init();
  294. }
  295. })();
  296. ​