plugin.js 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089
  1. /**
  2. * Copyright (c) Tiny Technologies, Inc. All rights reserved.
  3. * Licensed under the LGPL or a commercial license.
  4. * For LGPL see License.txt in the project root for license information.
  5. * For commercial licenses see https://www.tiny.cloud/
  6. *
  7. * Version: 5.1.0 (2019-10-17)
  8. */
  9. (function (domGlobals) {
  10. 'use strict';
  11. var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
  12. var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
  13. var window = {};
  14. var global$2 = window;
  15. var _self = typeof window !== 'undefined' ? window : typeof WorkerGlobalScope !== 'undefined' && domGlobals.self instanceof WorkerGlobalScope ? domGlobals.self : {};
  16. var Prism = function () {
  17. var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i;
  18. var _ = _self.Prism = {
  19. util: {
  20. encode: function (tokens) {
  21. if (tokens instanceof Token) {
  22. return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
  23. } else if (_.util.type(tokens) === 'Array') {
  24. return tokens.map(_.util.encode);
  25. } else {
  26. return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
  27. }
  28. },
  29. type: function (o) {
  30. return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1];
  31. },
  32. clone: function (o) {
  33. var type = _.util.type(o);
  34. switch (type) {
  35. case 'Object':
  36. var clone = {};
  37. for (var key in o) {
  38. if (o.hasOwnProperty(key)) {
  39. clone[key] = _.util.clone(o[key]);
  40. }
  41. }
  42. return clone;
  43. case 'Array':
  44. return o.map && o.map(function (v) {
  45. return _.util.clone(v);
  46. });
  47. }
  48. return o;
  49. }
  50. },
  51. languages: {
  52. extend: function (id, redef) {
  53. var lang = _.util.clone(_.languages[id]);
  54. for (var key in redef) {
  55. lang[key] = redef[key];
  56. }
  57. return lang;
  58. },
  59. insertBefore: function (inside, before, insert, root) {
  60. root = root || _.languages;
  61. var grammar = root[inside];
  62. if (arguments.length === 2) {
  63. insert = arguments[1];
  64. for (var newToken in insert) {
  65. if (insert.hasOwnProperty(newToken)) {
  66. grammar[newToken] = insert[newToken];
  67. }
  68. }
  69. return grammar;
  70. }
  71. var ret = {};
  72. for (var token in grammar) {
  73. if (grammar.hasOwnProperty(token)) {
  74. if (token === before) {
  75. for (var newToken in insert) {
  76. if (insert.hasOwnProperty(newToken)) {
  77. ret[newToken] = insert[newToken];
  78. }
  79. }
  80. }
  81. ret[token] = grammar[token];
  82. }
  83. }
  84. _.languages.DFS(_.languages, function (key, value) {
  85. if (value === root[inside] && key !== inside) {
  86. this[key] = ret;
  87. }
  88. });
  89. return root[inside] = ret;
  90. },
  91. DFS: function (o, callback, type) {
  92. for (var i in o) {
  93. if (o.hasOwnProperty(i)) {
  94. callback.call(o, i, o[i], type || i);
  95. if (_.util.type(o[i]) === 'Object') {
  96. _.languages.DFS(o[i], callback);
  97. } else if (_.util.type(o[i]) === 'Array') {
  98. _.languages.DFS(o[i], callback, i);
  99. }
  100. }
  101. }
  102. }
  103. },
  104. plugins: {},
  105. highlightAll: function (async, callback) {
  106. var elements = domGlobals.document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');
  107. for (var i = 0, element = void 0; element = elements[i++];) {
  108. _.highlightElement(element, async === true, callback);
  109. }
  110. },
  111. highlightElement: function (element, async, callback) {
  112. var language, grammar, parent = element;
  113. while (parent && !lang.test(parent.className)) {
  114. parent = parent.parentNode;
  115. }
  116. if (parent) {
  117. language = (parent.className.match(lang) || [
  118. ,
  119. ''
  120. ])[1];
  121. grammar = _.languages[language];
  122. }
  123. element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
  124. parent = element.parentNode;
  125. if (/pre/i.test(parent.nodeName)) {
  126. parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
  127. }
  128. var code = element.textContent;
  129. var env = {
  130. element: element,
  131. language: language,
  132. grammar: grammar,
  133. code: code
  134. };
  135. if (!code || !grammar) {
  136. _.hooks.run('complete', env);
  137. return;
  138. }
  139. _.hooks.run('before-highlight', env);
  140. if (async && _self.Worker) {
  141. var worker = new domGlobals.Worker(_.filename);
  142. worker.onmessage = function (evt) {
  143. env.highlightedCode = evt.data;
  144. _.hooks.run('before-insert', env);
  145. env.element.innerHTML = env.highlightedCode;
  146. if (callback) {
  147. callback.call(env.element);
  148. }
  149. _.hooks.run('after-highlight', env);
  150. _.hooks.run('complete', env);
  151. };
  152. worker.postMessage(JSON.stringify({
  153. language: env.language,
  154. code: env.code,
  155. immediateClose: true
  156. }));
  157. } else {
  158. env.highlightedCode = _.highlight(env.code, env.grammar, env.language);
  159. _.hooks.run('before-insert', env);
  160. env.element.innerHTML = env.highlightedCode;
  161. if (callback) {
  162. callback.call(element);
  163. }
  164. _.hooks.run('after-highlight', env);
  165. _.hooks.run('complete', env);
  166. }
  167. },
  168. highlight: function (text, grammar, language) {
  169. var tokens = _.tokenize(text, grammar);
  170. return Token.stringify(_.util.encode(tokens), language);
  171. },
  172. tokenize: function (text, grammar, language) {
  173. var Token = _.Token;
  174. var strarr = [text];
  175. var rest = grammar.rest;
  176. if (rest) {
  177. for (var token in rest) {
  178. grammar[token] = rest[token];
  179. }
  180. delete grammar.rest;
  181. }
  182. tokenloop:
  183. for (var token in grammar) {
  184. if (!grammar.hasOwnProperty(token) || !grammar[token]) {
  185. continue;
  186. }
  187. var patterns = grammar[token];
  188. patterns = _.util.type(patterns) === 'Array' ? patterns : [patterns];
  189. for (var j = 0; j < patterns.length; ++j) {
  190. var pattern = patterns[j];
  191. var inside = pattern.inside;
  192. var lookbehind = !!pattern.lookbehind;
  193. var lookbehindLength = 0;
  194. var alias = pattern.alias;
  195. pattern = pattern.pattern || pattern;
  196. for (var i = 0; i < strarr.length; i++) {
  197. var str = strarr[i];
  198. if (strarr.length > text.length) {
  199. break tokenloop;
  200. }
  201. if (str instanceof Token) {
  202. continue;
  203. }
  204. pattern.lastIndex = 0;
  205. var match = pattern.exec(str);
  206. if (match) {
  207. if (lookbehind) {
  208. lookbehindLength = match[1].length;
  209. }
  210. var from = match.index - 1 + lookbehindLength;
  211. match = match[0].slice(lookbehindLength);
  212. var len = match.length, to = from + len, before = str.slice(0, from + 1), after = str.slice(to + 1);
  213. var args = [
  214. i,
  215. 1
  216. ];
  217. if (before) {
  218. args.push(before);
  219. }
  220. var wrapped = new Token(token, inside ? _.tokenize(match, inside) : match, alias);
  221. args.push(wrapped);
  222. if (after) {
  223. args.push(after);
  224. }
  225. Array.prototype.splice.apply(strarr, args);
  226. }
  227. }
  228. }
  229. }
  230. return strarr;
  231. },
  232. hooks: {
  233. all: {},
  234. add: function (name, callback) {
  235. var hooks = _.hooks.all;
  236. hooks[name] = hooks[name] || [];
  237. hooks[name].push(callback);
  238. },
  239. run: function (name, env) {
  240. var callbacks = _.hooks.all[name];
  241. if (!callbacks || !callbacks.length) {
  242. return;
  243. }
  244. for (var i = 0, callback = void 0; callback = callbacks[i++];) {
  245. callback(env);
  246. }
  247. }
  248. }
  249. };
  250. var Token = _.Token = function (type, content, alias) {
  251. this.type = type;
  252. this.content = content;
  253. this.alias = alias;
  254. };
  255. Token.stringify = function (o, language, parent) {
  256. if (typeof o === 'string') {
  257. return o;
  258. }
  259. if (_.util.type(o) === 'Array') {
  260. return o.map(function (element) {
  261. return Token.stringify(element, language, o);
  262. }).join('');
  263. }
  264. var env = {
  265. type: o.type,
  266. content: Token.stringify(o.content, language, parent),
  267. tag: 'span',
  268. classes: [
  269. 'token',
  270. o.type
  271. ],
  272. attributes: {},
  273. language: language,
  274. parent: parent
  275. };
  276. if (env.type === 'comment') {
  277. env.attributes.spellcheck = 'true';
  278. }
  279. if (o.alias) {
  280. var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias];
  281. Array.prototype.push.apply(env.classes, aliases);
  282. }
  283. _.hooks.run('wrap', env);
  284. var attributes = '';
  285. for (var name in env.attributes) {
  286. attributes += (attributes ? ' ' : '') + name + '="' + (env.attributes[name] || '') + '"';
  287. }
  288. return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + '</' + env.tag + '>';
  289. };
  290. if (!_self.document) {
  291. if (!_self.addEventListener) {
  292. return _self.Prism;
  293. }
  294. _self.addEventListener('message', function (evt) {
  295. var message = JSON.parse(evt.data), lang = message.language, code = message.code, immediateClose = message.immediateClose;
  296. _self.postMessage(_.highlight(code, _.languages[lang], lang));
  297. if (immediateClose) {
  298. _self.close();
  299. }
  300. }, false);
  301. return _self.Prism;
  302. }
  303. }();
  304. if (typeof global$2 !== 'undefined') {
  305. global$2.Prism = Prism;
  306. }
  307. Prism.languages.markup = {
  308. comment: /<!--[\w\W]*?-->/,
  309. prolog: /<\?[\w\W]+?\?>/,
  310. doctype: /<!DOCTYPE[\w\W]+?>/,
  311. cdata: /<!\[CDATA\[[\w\W]*?]]>/i,
  312. tag: {
  313. pattern: /<\/?[^\s>\/=.]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,
  314. inside: {
  315. 'tag': {
  316. pattern: /^<\/?[^\s>\/]+/i,
  317. inside: {
  318. punctuation: /^<\/?/,
  319. namespace: /^[^\s>\/:]+:/
  320. }
  321. },
  322. 'attr-value': {
  323. pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,
  324. inside: { punctuation: /[=>"']/ }
  325. },
  326. 'punctuation': /\/?>/,
  327. 'attr-name': {
  328. pattern: /[^\s>\/]+/,
  329. inside: { namespace: /^[^\s>\/:]+:/ }
  330. }
  331. }
  332. },
  333. entity: /&#?[\da-z]{1,8};/i
  334. };
  335. Prism.hooks.add('wrap', function (env) {
  336. if (env.type === 'entity') {
  337. env.attributes.title = env.content.replace(/&amp;/, '&');
  338. }
  339. });
  340. Prism.languages.xml = Prism.languages.markup;
  341. Prism.languages.html = Prism.languages.markup;
  342. Prism.languages.mathml = Prism.languages.markup;
  343. Prism.languages.svg = Prism.languages.markup;
  344. Prism.languages.css = {
  345. comment: /\/\*[\w\W]*?\*\//,
  346. atrule: {
  347. pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i,
  348. inside: { rule: /@[\w-]+/ }
  349. },
  350. url: /url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,
  351. selector: /[^\{\}\s][^\{\};]*?(?=\s*\{)/,
  352. string: /("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,
  353. property: /(\b|\B)[\w-]+(?=\s*:)/i,
  354. important: /\B!important\b/i,
  355. function: /[-a-z0-9]+(?=\()/i,
  356. punctuation: /[(){};:]/
  357. };
  358. Prism.languages.css.atrule.inside.rest = Prism.util.clone(Prism.languages.css);
  359. if (Prism.languages.markup) {
  360. Prism.languages.insertBefore('markup', 'tag', {
  361. style: {
  362. pattern: /<style[\w\W]*?>[\w\W]*?<\/style>/i,
  363. inside: {
  364. tag: {
  365. pattern: /<style[\w\W]*?>|<\/style>/i,
  366. inside: Prism.languages.markup.tag.inside
  367. },
  368. rest: Prism.languages.css
  369. },
  370. alias: 'language-css'
  371. }
  372. });
  373. Prism.languages.insertBefore('inside', 'attr-value', {
  374. 'style-attr': {
  375. pattern: /\s*style=("|').*?\1/i,
  376. inside: {
  377. 'attr-name': {
  378. pattern: /^\s*style/i,
  379. inside: Prism.languages.markup.tag.inside
  380. },
  381. 'punctuation': /^\s*=\s*['"]|['"]\s*$/,
  382. 'attr-value': {
  383. pattern: /.+/i,
  384. inside: Prism.languages.css
  385. }
  386. },
  387. alias: 'language-css'
  388. }
  389. }, Prism.languages.markup.tag);
  390. }
  391. Prism.languages.clike = {
  392. 'comment': [
  393. {
  394. pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
  395. lookbehind: true
  396. },
  397. {
  398. pattern: /(^|[^\\:])\/\/.*/,
  399. lookbehind: true
  400. }
  401. ],
  402. 'string': /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
  403. 'class-name': {
  404. pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,
  405. lookbehind: true,
  406. inside: { punctuation: /(\.|\\)/ }
  407. },
  408. 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
  409. 'boolean': /\b(true|false)\b/,
  410. 'function': /[a-z0-9_]+(?=\()/i,
  411. 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,
  412. 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,
  413. 'punctuation': /[{}[\];(),.:]/
  414. };
  415. Prism.languages.javascript = Prism.languages.extend('clike', {
  416. keyword: /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|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|true|try|typeof|var|void|while|with|yield)\b/,
  417. number: /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,
  418. function: /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i
  419. });
  420. Prism.languages.insertBefore('javascript', 'keyword', {
  421. regex: {
  422. pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,
  423. lookbehind: true
  424. }
  425. });
  426. Prism.languages.insertBefore('javascript', 'class-name', {
  427. 'template-string': {
  428. pattern: /`(?:\\`|\\?[^`])*`/,
  429. inside: {
  430. interpolation: {
  431. pattern: /\$\{[^}]+\}/,
  432. inside: {
  433. 'interpolation-punctuation': {
  434. pattern: /^\$\{|\}$/,
  435. alias: 'punctuation'
  436. },
  437. 'rest': Prism.languages.javascript
  438. }
  439. },
  440. string: /[\s\S]+/
  441. }
  442. }
  443. });
  444. if (Prism.languages.markup) {
  445. Prism.languages.insertBefore('markup', 'tag', {
  446. script: {
  447. pattern: /<script[\w\W]*?>[\w\W]*?<\/script>/i,
  448. inside: {
  449. tag: {
  450. pattern: /<script[\w\W]*?>|<\/script>/i,
  451. inside: Prism.languages.markup.tag.inside
  452. },
  453. rest: Prism.languages.javascript
  454. },
  455. alias: 'language-javascript'
  456. }
  457. });
  458. }
  459. Prism.languages.js = Prism.languages.javascript;
  460. Prism.languages.c = Prism.languages.extend('clike', {
  461. keyword: /\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,
  462. operator: /\-[>-]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|?\||[~^%?*\/]/,
  463. number: /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i
  464. });
  465. Prism.languages.insertBefore('c', 'string', {
  466. macro: {
  467. pattern: /(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im,
  468. lookbehind: true,
  469. alias: 'property',
  470. inside: {
  471. string: {
  472. pattern: /(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,
  473. lookbehind: true
  474. }
  475. }
  476. }
  477. });
  478. delete Prism.languages.c['class-name'];
  479. delete Prism.languages.c.boolean;
  480. Prism.languages.csharp = Prism.languages.extend('clike', {
  481. keyword: /\b(abstract|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/,
  482. string: [
  483. /@("|')(\1\1|\\\1|\\?(?!\1)[\s\S])*\1/,
  484. /("|')(\\?.)*?\1/
  485. ],
  486. number: /\b-?(0x[\da-f]+|\d*\.?\d+)\b/i
  487. });
  488. Prism.languages.insertBefore('csharp', 'keyword', {
  489. preprocessor: {
  490. pattern: /(^\s*)#.*/m,
  491. lookbehind: true
  492. }
  493. });
  494. Prism.languages.cpp = Prism.languages.extend('c', {
  495. keyword: /\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,
  496. boolean: /\b(true|false)\b/,
  497. operator: /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/
  498. });
  499. Prism.languages.insertBefore('cpp', 'keyword', {
  500. 'class-name': {
  501. pattern: /(class\s+)[a-z0-9_]+/i,
  502. lookbehind: true
  503. }
  504. });
  505. Prism.languages.java = Prism.languages.extend('clike', {
  506. keyword: /\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,
  507. number: /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,
  508. operator: {
  509. pattern: /(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<<?=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,
  510. lookbehind: true
  511. }
  512. });
  513. Prism.languages.php = Prism.languages.extend('clike', {
  514. keyword: /\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,
  515. constant: /\b[A-Z0-9_]{2,}\b/,
  516. comment: {
  517. pattern: /(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,
  518. lookbehind: true
  519. }
  520. });
  521. Prism.languages.insertBefore('php', 'class-name', {
  522. 'shell-comment': {
  523. pattern: /(^|[^\\])#.*/,
  524. lookbehind: true,
  525. alias: 'comment'
  526. }
  527. });
  528. Prism.languages.insertBefore('php', 'keyword', {
  529. delimiter: /\?>|<\?(?:php)?/i,
  530. variable: /\$\w+\b/i,
  531. package: {
  532. pattern: /(\\|namespace\s+|use\s+)[\w\\]+/,
  533. lookbehind: true,
  534. inside: { punctuation: /\\/ }
  535. }
  536. });
  537. Prism.languages.insertBefore('php', 'operator', {
  538. property: {
  539. pattern: /(->)[\w]+/,
  540. lookbehind: true
  541. }
  542. });
  543. if (Prism.languages.markup) {
  544. Prism.hooks.add('before-highlight', function (env) {
  545. if (env.language !== 'php') {
  546. return;
  547. }
  548. env.tokenStack = [];
  549. env.backupCode = env.code;
  550. env.code = env.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/ig, function (match) {
  551. env.tokenStack.push(match);
  552. return '{{{PHP' + env.tokenStack.length + '}}}';
  553. });
  554. });
  555. Prism.hooks.add('before-insert', function (env) {
  556. if (env.language === 'php') {
  557. env.code = env.backupCode;
  558. delete env.backupCode;
  559. }
  560. });
  561. Prism.hooks.add('after-highlight', function (env) {
  562. if (env.language !== 'php') {
  563. return;
  564. }
  565. for (var i = 0, t = void 0; t = env.tokenStack[i]; i++) {
  566. env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php').replace(/\$/g, '$$$$'));
  567. }
  568. env.element.innerHTML = env.highlightedCode;
  569. });
  570. Prism.hooks.add('wrap', function (env) {
  571. if (env.language === 'php' && env.type === 'markup') {
  572. env.content = env.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g, '<span class="token php">$1</span>');
  573. }
  574. });
  575. Prism.languages.insertBefore('php', 'comment', {
  576. markup: {
  577. pattern: /<[^?]\/?(.*?)>/,
  578. inside: Prism.languages.markup
  579. },
  580. php: /\{\{\{PHP[0-9]+\}\}\}/
  581. });
  582. }
  583. Prism.languages.python = {
  584. 'comment': {
  585. pattern: /(^|[^\\])#.*/,
  586. lookbehind: true
  587. },
  588. 'string': /"""[\s\S]+?"""|'''[\s\S]+?'''|("|')(?:\\?.)*?\1/,
  589. 'function': {
  590. pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g,
  591. lookbehind: true
  592. },
  593. 'class-name': {
  594. pattern: /(\bclass\s+)[a-z0-9_]+/i,
  595. lookbehind: true
  596. },
  597. 'keyword': /\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/,
  598. 'boolean': /\b(?:True|False)\b/,
  599. 'number': /\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,
  600. 'operator': /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,
  601. 'punctuation': /[{}[\];(),.:]/
  602. };
  603. (function (Prism) {
  604. Prism.languages.ruby = Prism.languages.extend('clike', {
  605. comment: /#(?!\{[^\r\n]*?\}).*/,
  606. keyword: /\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/
  607. });
  608. var interpolation = {
  609. pattern: /#\{[^}]+\}/,
  610. inside: {
  611. delimiter: {
  612. pattern: /^#\{|\}$/,
  613. alias: 'tag'
  614. },
  615. rest: Prism.util.clone(Prism.languages.ruby)
  616. }
  617. };
  618. Prism.languages.insertBefore('ruby', 'keyword', {
  619. regex: [
  620. {
  621. pattern: /%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/,
  622. inside: { interpolation: interpolation }
  623. },
  624. {
  625. pattern: /%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,
  626. inside: { interpolation: interpolation }
  627. },
  628. {
  629. pattern: /%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,
  630. inside: { interpolation: interpolation }
  631. },
  632. {
  633. pattern: /%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,
  634. inside: { interpolation: interpolation }
  635. },
  636. {
  637. pattern: /%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,
  638. inside: { interpolation: interpolation }
  639. },
  640. {
  641. pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,
  642. lookbehind: true
  643. }
  644. ],
  645. variable: /[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/,
  646. symbol: /:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/
  647. });
  648. Prism.languages.insertBefore('ruby', 'number', {
  649. builtin: /\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,
  650. constant: /\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/
  651. });
  652. Prism.languages.ruby.string = [
  653. {
  654. pattern: /%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/,
  655. inside: { interpolation: interpolation }
  656. },
  657. {
  658. pattern: /%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,
  659. inside: { interpolation: interpolation }
  660. },
  661. {
  662. pattern: /%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,
  663. inside: { interpolation: interpolation }
  664. },
  665. {
  666. pattern: /%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,
  667. inside: { interpolation: interpolation }
  668. },
  669. {
  670. pattern: /%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,
  671. inside: { interpolation: interpolation }
  672. },
  673. {
  674. pattern: /("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/,
  675. inside: { interpolation: interpolation }
  676. }
  677. ];
  678. }(Prism));
  679. function isCodeSample(elm) {
  680. return elm && elm.nodeName === 'PRE' && elm.className.indexOf('language-') !== -1;
  681. }
  682. function trimArg(predicateFn) {
  683. return function (arg1, arg2) {
  684. return predicateFn(arg2);
  685. };
  686. }
  687. var Utils = {
  688. isCodeSample: isCodeSample,
  689. trimArg: trimArg
  690. };
  691. var noop = function () {
  692. };
  693. var constant = function (value) {
  694. return function () {
  695. return value;
  696. };
  697. };
  698. var never = constant(false);
  699. var always = constant(true);
  700. var none = function () {
  701. return NONE;
  702. };
  703. var NONE = function () {
  704. var eq = function (o) {
  705. return o.isNone();
  706. };
  707. var call = function (thunk) {
  708. return thunk();
  709. };
  710. var id = function (n) {
  711. return n;
  712. };
  713. var me = {
  714. fold: function (n, s) {
  715. return n();
  716. },
  717. is: never,
  718. isSome: never,
  719. isNone: always,
  720. getOr: id,
  721. getOrThunk: call,
  722. getOrDie: function (msg) {
  723. throw new Error(msg || 'error: getOrDie called on none.');
  724. },
  725. getOrNull: constant(null),
  726. getOrUndefined: constant(undefined),
  727. or: id,
  728. orThunk: call,
  729. map: none,
  730. each: noop,
  731. bind: none,
  732. exists: never,
  733. forall: always,
  734. filter: none,
  735. equals: eq,
  736. equals_: eq,
  737. toArray: function () {
  738. return [];
  739. },
  740. toString: constant('none()')
  741. };
  742. if (Object.freeze) {
  743. Object.freeze(me);
  744. }
  745. return me;
  746. }();
  747. var some = function (a) {
  748. var constant_a = constant(a);
  749. var self = function () {
  750. return me;
  751. };
  752. var bind = function (f) {
  753. return f(a);
  754. };
  755. var me = {
  756. fold: function (n, s) {
  757. return s(a);
  758. },
  759. is: function (v) {
  760. return a === v;
  761. },
  762. isSome: always,
  763. isNone: never,
  764. getOr: constant_a,
  765. getOrThunk: constant_a,
  766. getOrDie: constant_a,
  767. getOrNull: constant_a,
  768. getOrUndefined: constant_a,
  769. or: self,
  770. orThunk: self,
  771. map: function (f) {
  772. return some(f(a));
  773. },
  774. each: function (f) {
  775. f(a);
  776. },
  777. bind: bind,
  778. exists: bind,
  779. forall: bind,
  780. filter: function (f) {
  781. return f(a) ? me : NONE;
  782. },
  783. toArray: function () {
  784. return [a];
  785. },
  786. toString: function () {
  787. return 'some(' + a + ')';
  788. },
  789. equals: function (o) {
  790. return o.is(a);
  791. },
  792. equals_: function (o, elementEq) {
  793. return o.fold(never, function (b) {
  794. return elementEq(a, b);
  795. });
  796. }
  797. };
  798. return me;
  799. };
  800. var from = function (value) {
  801. return value === null || value === undefined ? NONE : some(value);
  802. };
  803. var Option = {
  804. some: some,
  805. none: none,
  806. from: from
  807. };
  808. var getSelectedCodeSample = function (editor) {
  809. var node = editor.selection ? editor.selection.getNode() : null;
  810. if (Utils.isCodeSample(node)) {
  811. return Option.some(node);
  812. }
  813. return Option.none();
  814. };
  815. var insertCodeSample = function (editor, language, code) {
  816. editor.undoManager.transact(function () {
  817. var node = getSelectedCodeSample(editor);
  818. code = global$1.DOM.encode(code);
  819. return node.fold(function () {
  820. editor.insertContent('<pre id="__new" class="language-' + language + '">' + code + '</pre>');
  821. editor.selection.select(editor.$('#__new').removeAttr('id')[0]);
  822. }, function (n) {
  823. editor.dom.setAttrib(n, 'class', 'language-' + language);
  824. n.innerHTML = code;
  825. Prism.highlightElement(n);
  826. editor.selection.select(n);
  827. });
  828. });
  829. };
  830. var getCurrentCode = function (editor) {
  831. var node = getSelectedCodeSample(editor);
  832. return node.fold(function () {
  833. return '';
  834. }, function (n) {
  835. return n.textContent;
  836. });
  837. };
  838. var CodeSample = {
  839. getSelectedCodeSample: getSelectedCodeSample,
  840. insertCodeSample: insertCodeSample,
  841. getCurrentCode: getCurrentCode
  842. };
  843. var getLanguages = function (editor) {
  844. return editor.settings.codesample_languages;
  845. };
  846. var Settings = { getLanguages: getLanguages };
  847. var getLanguages$1 = function (editor) {
  848. var defaultLanguages = [
  849. {
  850. text: 'HTML/XML',
  851. value: 'markup'
  852. },
  853. {
  854. text: 'JavaScript',
  855. value: 'javascript'
  856. },
  857. {
  858. text: 'CSS',
  859. value: 'css'
  860. },
  861. {
  862. text: 'PHP',
  863. value: 'php'
  864. },
  865. {
  866. text: 'Ruby',
  867. value: 'ruby'
  868. },
  869. {
  870. text: 'Python',
  871. value: 'python'
  872. },
  873. {
  874. text: 'Java',
  875. value: 'java'
  876. },
  877. {
  878. text: 'C',
  879. value: 'c'
  880. },
  881. {
  882. text: 'C#',
  883. value: 'csharp'
  884. },
  885. {
  886. text: 'C++',
  887. value: 'cpp'
  888. }
  889. ];
  890. var customLanguages = Settings.getLanguages(editor);
  891. return customLanguages ? customLanguages : defaultLanguages;
  892. };
  893. var getCurrentLanguage = function (editor, fallback) {
  894. var node = CodeSample.getSelectedCodeSample(editor);
  895. return node.fold(function () {
  896. return fallback;
  897. }, function (n) {
  898. var matches = n.className.match(/language-(\w+)/);
  899. return matches ? matches[1] : fallback;
  900. });
  901. };
  902. var Languages = {
  903. getLanguages: getLanguages$1,
  904. getCurrentLanguage: getCurrentLanguage
  905. };
  906. var typeOf = function (x) {
  907. if (x === null) {
  908. return 'null';
  909. }
  910. var t = typeof x;
  911. if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
  912. return 'array';
  913. }
  914. if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
  915. return 'string';
  916. }
  917. return t;
  918. };
  919. var isType = function (type) {
  920. return function (value) {
  921. return typeOf(value) === type;
  922. };
  923. };
  924. var isFunction = isType('function');
  925. var nativeSlice = Array.prototype.slice;
  926. var head = function (xs) {
  927. return xs.length === 0 ? Option.none() : Option.some(xs[0]);
  928. };
  929. var from$1 = isFunction(Array.from) ? Array.from : function (x) {
  930. return nativeSlice.call(x);
  931. };
  932. var open = function (editor) {
  933. var languages = Languages.getLanguages(editor);
  934. var defaultLanguage = head(languages).fold(function () {
  935. return '';
  936. }, function (l) {
  937. return l.value;
  938. });
  939. var currentLanguage = Languages.getCurrentLanguage(editor, defaultLanguage);
  940. var currentCode = CodeSample.getCurrentCode(editor);
  941. editor.windowManager.open({
  942. title: 'Insert/Edit Code Sample',
  943. size: 'large',
  944. body: {
  945. type: 'panel',
  946. items: [
  947. {
  948. type: 'selectbox',
  949. name: 'language',
  950. label: 'Language',
  951. items: languages
  952. },
  953. {
  954. type: 'textarea',
  955. name: 'code',
  956. label: 'Code view'
  957. }
  958. ]
  959. },
  960. buttons: [
  961. {
  962. type: 'cancel',
  963. name: 'cancel',
  964. text: 'Cancel'
  965. },
  966. {
  967. type: 'submit',
  968. name: 'save',
  969. text: 'Save',
  970. primary: true
  971. }
  972. ],
  973. initialData: {
  974. language: currentLanguage,
  975. code: currentCode
  976. },
  977. onSubmit: function (api) {
  978. var data = api.getData();
  979. CodeSample.insertCodeSample(editor, data.language, data.code);
  980. api.close();
  981. }
  982. });
  983. };
  984. var Dialog = { open: open };
  985. var register = function (editor) {
  986. editor.addCommand('codesample', function () {
  987. var node = editor.selection.getNode();
  988. if (editor.selection.isCollapsed() || Utils.isCodeSample(node)) {
  989. Dialog.open(editor);
  990. } else {
  991. editor.formatter.toggle('code');
  992. }
  993. });
  994. };
  995. var Commands = { register: register };
  996. var setup = function (editor) {
  997. var $ = editor.$;
  998. editor.on('PreProcess', function (e) {
  999. $('pre[contenteditable=false]', e.node).filter(Utils.trimArg(Utils.isCodeSample)).each(function (idx, elm) {
  1000. var $elm = $(elm), code = elm.textContent;
  1001. $elm.attr('class', $.trim($elm.attr('class')));
  1002. $elm.removeAttr('contentEditable');
  1003. $elm.empty().append($('<code></code>').each(function () {
  1004. this.textContent = code;
  1005. }));
  1006. });
  1007. });
  1008. editor.on('SetContent', function () {
  1009. var unprocessedCodeSamples = $('pre').filter(Utils.trimArg(Utils.isCodeSample)).filter(function (idx, elm) {
  1010. return elm.contentEditable !== 'false';
  1011. });
  1012. if (unprocessedCodeSamples.length) {
  1013. editor.undoManager.transact(function () {
  1014. unprocessedCodeSamples.each(function (idx, elm) {
  1015. $(elm).find('br').each(function (idx, elm) {
  1016. elm.parentNode.replaceChild(editor.getDoc().createTextNode('\n'), elm);
  1017. });
  1018. elm.contentEditable = 'false';
  1019. elm.innerHTML = editor.dom.encode(elm.textContent);
  1020. Prism.highlightElement(elm);
  1021. elm.className = $.trim(elm.className);
  1022. });
  1023. });
  1024. }
  1025. });
  1026. };
  1027. var FilterContent = { setup: setup };
  1028. var isCodeSampleSelection = function (editor) {
  1029. var node = editor.selection.getStart();
  1030. return editor.dom.is(node, 'pre.language-markup');
  1031. };
  1032. var register$1 = function (editor) {
  1033. editor.ui.registry.addToggleButton('codesample', {
  1034. icon: 'code-sample',
  1035. tooltip: 'Insert/edit code sample',
  1036. onAction: function () {
  1037. return Dialog.open(editor);
  1038. },
  1039. onSetup: function (api) {
  1040. var nodeChangeHandler = function () {
  1041. api.setActive(isCodeSampleSelection(editor));
  1042. };
  1043. editor.on('NodeChange', nodeChangeHandler);
  1044. return function () {
  1045. return editor.off('NodeChange', nodeChangeHandler);
  1046. };
  1047. }
  1048. });
  1049. editor.ui.registry.addMenuItem('codesample', {
  1050. text: 'Code sample...',
  1051. icon: 'code-sample',
  1052. onAction: function () {
  1053. return Dialog.open(editor);
  1054. }
  1055. });
  1056. };
  1057. var Buttons = { register: register$1 };
  1058. function Plugin () {
  1059. global.add('codesample', function (editor) {
  1060. FilterContent.setup(editor);
  1061. Buttons.register(editor);
  1062. Commands.register(editor);
  1063. editor.on('dblclick', function (ev) {
  1064. if (Utils.isCodeSample(ev.target)) {
  1065. Dialog.open(editor);
  1066. }
  1067. });
  1068. });
  1069. }
  1070. Plugin();
  1071. }(window));