guide 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9ecdd35516494ffde39a8b63923030fda139746eb6117f3f5e77dec91f0a18a
4
- data.tar.gz: f49f70bd07c1694242e737d58f8f178cc69f14bd838c811b1de7ef64acc52fab
3
+ metadata.gz: e16bc443fc8ef63b16a46d8ccdfde8659f7d6fc6285539e402af99d140f84571
4
+ data.tar.gz: 38f412d0da66483df051b5e6a8be761f7748e08dbf2f2944beba96687ce54b40
5
5
  SHA512:
6
- metadata.gz: 9bf4cb51a939a00e5b770adf521f30859f05958498c26c7256137e946a2ff186b6f73ebbf6e053f33cb87c942cb1365687a5bab8004afb7303f64b996791b1ac
7
- data.tar.gz: a3e735e79f2c0cb0db15f1118cd8fa8b0291bad4e1c5827192ac476226cbfdf27b7d2ae827b5843a0f248c6be27599a36f23d52f61b769986819b74dbe9f7bff
6
+ metadata.gz: 958c597a15af220c11de53c8f9e3edc73d5a09676ba685aef95262d98dd667e2161c101bfb617db7c91e7f6776bcf9d0967bb0f93e1856d7fa07f2b7b98169b8
7
+ data.tar.gz: 298143a1c3dfb085d017a63fe3a0454b722abc5347a370c283a03af5b772d9e4b29f90a9f7bd6d06bf49f7c352eb77c52bfd5621dae70f36e0a67f07d632affc
data/Rakefile CHANGED
@@ -1,7 +1,34 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
 
6
+ assets_target = 'app/assets'
7
+ js_target = "#{assets_target}/javascripts/guide"
8
+ css_target = "#{assets_target}/stylesheets/guide"
9
+
10
+ CLEAN << assets_target
4
11
  RSpec::Core::RakeTask.new(:spec)
12
+ task spec: %w[generate_assets]
13
+ task build: %w[clean generate_assets]
14
+ task generate_assets: %W[
15
+ #{js_target}/application.js
16
+ #{js_target}/scenario.js
17
+ #{css_target}/application.css
18
+ ]
19
+
20
+ rule(%r{^#{js_target}/.+\.js$} => [->(n) { n.sub(js_target, 'javascript') }, 'node_modules/.install']) do |t|
21
+ sh "yarn browserify #{t.source} -o #{t.name}"
22
+ end
23
+
24
+ rule(%r{^#{css_target}/.+\.css$} => [->(n) { n.sub(css_target, 'styles') }, 'node_modules/.install']) do |t|
25
+ sh "yarn postcss #{t.source} -o #{t.name}"
26
+ end
27
+
28
+ file 'node_modules/.install' => %w[package.json yarn.lock] do
29
+ sh 'yarn install'
30
+ touch 'node_modules/.install'
31
+ end
5
32
 
6
33
  task :setup_test_app, [:rails_version] do |_task, args|
7
34
  require_relative './spec/test_apps/setup'
@@ -1,4 +1,4 @@
1
- (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
1
+ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2
2
  var $ = window.jQuery = require('jquery')
3
3
  require('prismjs')
4
4
 
@@ -14319,446 +14319,1175 @@ return jQuery;
14319
14319
  return MicroPlugin;
14320
14320
  }));
14321
14321
  },{}],18:[function(require,module,exports){
14322
- (function (global){
14322
+ (function (global){(function (){
14323
14323
 
14324
14324
  /* **********************************************
14325
14325
  Begin prism-core.js
14326
14326
  ********************************************** */
14327
14327
 
14328
+ /// <reference lib="WebWorker"/>
14329
+
14328
14330
  var _self = (typeof window !== 'undefined')
14329
14331
  ? window // if in browser
14330
14332
  : (
14331
14333
  (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
14332
- ? self // if in worker
14333
- : {} // if in node js
14334
+ ? self // if in worker
14335
+ : {} // if in node js
14334
14336
  );
14335
14337
 
14336
14338
  /**
14337
14339
  * Prism: Lightweight, robust, elegant syntax highlighting
14338
- * MIT license http://www.opensource.org/licenses/mit-license.php/
14339
- * @author Lea Verou http://lea.verou.me
14340
+ *
14341
+ * @license MIT <https://opensource.org/licenses/MIT>
14342
+ * @author Lea Verou <https://lea.verou.me>
14343
+ * @namespace
14344
+ * @public
14340
14345
  */
14346
+ var Prism = (function (_self) {
14341
14347
 
14342
- var Prism = (function(){
14348
+ // Private helper vars
14349
+ var lang = /\blang(?:uage)?-([\w-]+)\b/i;
14350
+ var uniqueId = 0;
14343
14351
 
14344
- // Private helper vars
14345
- var lang = /\blang(?:uage)?-(\w+)\b/i;
14346
- var uniqueId = 0;
14352
+ // The grammar object for plaintext
14353
+ var plainTextGrammar = {};
14347
14354
 
14348
- var _ = _self.Prism = {
14349
- util: {
14350
- encode: function (tokens) {
14351
- if (tokens instanceof Token) {
14352
- return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias);
14353
- } else if (_.util.type(tokens) === 'Array') {
14354
- return tokens.map(_.util.encode);
14355
- } else {
14356
- return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
14357
- }
14358
- },
14359
14355
 
14360
- type: function (o) {
14361
- return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1];
14362
- },
14356
+ var _ = {
14357
+ /**
14358
+ * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
14359
+ * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
14360
+ * additional languages or plugins yourself.
14361
+ *
14362
+ * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
14363
+ *
14364
+ * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
14365
+ * empty Prism object into the global scope before loading the Prism script like this:
14366
+ *
14367
+ * ```js
14368
+ * window.Prism = window.Prism || {};
14369
+ * Prism.manual = true;
14370
+ * // add a new <script> to load Prism's script
14371
+ * ```
14372
+ *
14373
+ * @default false
14374
+ * @type {boolean}
14375
+ * @memberof Prism
14376
+ * @public
14377
+ */
14378
+ manual: _self.Prism && _self.Prism.manual,
14379
+ disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
14363
14380
 
14364
- objId: function (obj) {
14365
- if (!obj['__id']) {
14366
- Object.defineProperty(obj, '__id', { value: ++uniqueId });
14367
- }
14368
- return obj['__id'];
14369
- },
14381
+ /**
14382
+ * A namespace for utility methods.
14383
+ *
14384
+ * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
14385
+ * change or disappear at any time.
14386
+ *
14387
+ * @namespace
14388
+ * @memberof Prism
14389
+ */
14390
+ util: {
14391
+ encode: function encode(tokens) {
14392
+ if (tokens instanceof Token) {
14393
+ return new Token(tokens.type, encode(tokens.content), tokens.alias);
14394
+ } else if (Array.isArray(tokens)) {
14395
+ return tokens.map(encode);
14396
+ } else {
14397
+ return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
14398
+ }
14399
+ },
14370
14400
 
14371
- // Deep clone a language definition (e.g. to extend it)
14372
- clone: function (o) {
14373
- var type = _.util.type(o);
14401
+ /**
14402
+ * Returns the name of the type of the given value.
14403
+ *
14404
+ * @param {any} o
14405
+ * @returns {string}
14406
+ * @example
14407
+ * type(null) === 'Null'
14408
+ * type(undefined) === 'Undefined'
14409
+ * type(123) === 'Number'
14410
+ * type('foo') === 'String'
14411
+ * type(true) === 'Boolean'
14412
+ * type([1, 2]) === 'Array'
14413
+ * type({}) === 'Object'
14414
+ * type(String) === 'Function'
14415
+ * type(/abc+/) === 'RegExp'
14416
+ */
14417
+ type: function (o) {
14418
+ return Object.prototype.toString.call(o).slice(8, -1);
14419
+ },
14374
14420
 
14375
- switch (type) {
14376
- case 'Object':
14377
- var clone = {};
14421
+ /**
14422
+ * Returns a unique number for the given object. Later calls will still return the same number.
14423
+ *
14424
+ * @param {Object} obj
14425
+ * @returns {number}
14426
+ */
14427
+ objId: function (obj) {
14428
+ if (!obj['__id']) {
14429
+ Object.defineProperty(obj, '__id', { value: ++uniqueId });
14430
+ }
14431
+ return obj['__id'];
14432
+ },
14378
14433
 
14379
- for (var key in o) {
14380
- if (o.hasOwnProperty(key)) {
14381
- clone[key] = _.util.clone(o[key]);
14434
+ /**
14435
+ * Creates a deep clone of the given object.
14436
+ *
14437
+ * The main intended use of this function is to clone language definitions.
14438
+ *
14439
+ * @param {T} o
14440
+ * @param {Record<number, any>} [visited]
14441
+ * @returns {T}
14442
+ * @template T
14443
+ */
14444
+ clone: function deepClone(o, visited) {
14445
+ visited = visited || {};
14446
+
14447
+ var clone; var id;
14448
+ switch (_.util.type(o)) {
14449
+ case 'Object':
14450
+ id = _.util.objId(o);
14451
+ if (visited[id]) {
14452
+ return visited[id];
14382
14453
  }
14383
- }
14454
+ clone = /** @type {Record<string, any>} */ ({});
14455
+ visited[id] = clone;
14384
14456
 
14385
- return clone;
14457
+ for (var key in o) {
14458
+ if (o.hasOwnProperty(key)) {
14459
+ clone[key] = deepClone(o[key], visited);
14460
+ }
14461
+ }
14386
14462
 
14387
- case 'Array':
14388
- // Check for existence for IE8
14389
- return o.map && o.map(function(v) { return _.util.clone(v); });
14390
- }
14463
+ return /** @type {any} */ (clone);
14391
14464
 
14392
- return o;
14393
- }
14394
- },
14465
+ case 'Array':
14466
+ id = _.util.objId(o);
14467
+ if (visited[id]) {
14468
+ return visited[id];
14469
+ }
14470
+ clone = [];
14471
+ visited[id] = clone;
14395
14472
 
14396
- languages: {
14397
- extend: function (id, redef) {
14398
- var lang = _.util.clone(_.languages[id]);
14473
+ (/** @type {Array} */(/** @type {any} */(o))).forEach(function (v, i) {
14474
+ clone[i] = deepClone(v, visited);
14475
+ });
14399
14476
 
14400
- for (var key in redef) {
14401
- lang[key] = redef[key];
14402
- }
14477
+ return /** @type {any} */ (clone);
14403
14478
 
14404
- return lang;
14405
- },
14406
-
14407
- /**
14408
- * Insert a token before another token in a language literal
14409
- * As this needs to recreate the object (we cannot actually insert before keys in object literals),
14410
- * we cannot just provide an object, we need anobject and a key.
14411
- * @param inside The key (or language id) of the parent
14412
- * @param before The key to insert before. If not provided, the function appends instead.
14413
- * @param insert Object with the key/value pairs to insert
14414
- * @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
14415
- */
14416
- insertBefore: function (inside, before, insert, root) {
14417
- root = root || _.languages;
14418
- var grammar = root[inside];
14419
-
14420
- if (arguments.length == 2) {
14421
- insert = arguments[1];
14422
-
14423
- for (var newToken in insert) {
14424
- if (insert.hasOwnProperty(newToken)) {
14425
- grammar[newToken] = insert[newToken];
14426
- }
14479
+ default:
14480
+ return o;
14427
14481
  }
14428
-
14429
- return grammar;
14430
- }
14431
-
14432
- var ret = {};
14433
-
14434
- for (var token in grammar) {
14482
+ },
14435
14483
 
14436
- if (grammar.hasOwnProperty(token)) {
14484
+ /**
14485
+ * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
14486
+ *
14487
+ * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
14488
+ *
14489
+ * @param {Element} element
14490
+ * @returns {string}
14491
+ */
14492
+ getLanguage: function (element) {
14493
+ while (element && !lang.test(element.className)) {
14494
+ element = element.parentElement;
14495
+ }
14496
+ if (element) {
14497
+ return (element.className.match(lang) || [, 'none'])[1].toLowerCase();
14498
+ }
14499
+ return 'none';
14500
+ },
14437
14501
 
14438
- if (token == before) {
14502
+ /**
14503
+ * Returns the script element that is currently executing.
14504
+ *
14505
+ * This does __not__ work for line script element.
14506
+ *
14507
+ * @returns {HTMLScriptElement | null}
14508
+ */
14509
+ currentScript: function () {
14510
+ if (typeof document === 'undefined') {
14511
+ return null;
14512
+ }
14513
+ if ('currentScript' in document && 1 < 2 /* hack to trip TS' flow analysis */) {
14514
+ return /** @type {any} */ (document.currentScript);
14515
+ }
14439
14516
 
14440
- for (var newToken in insert) {
14517
+ // IE11 workaround
14518
+ // we'll get the src of the current script by parsing IE11's error stack trace
14519
+ // this will not work for inline scripts
14441
14520
 
14442
- if (insert.hasOwnProperty(newToken)) {
14443
- ret[newToken] = insert[newToken];
14521
+ try {
14522
+ throw new Error();
14523
+ } catch (err) {
14524
+ // Get file src url from stack. Specifically works with the format of stack traces in IE.
14525
+ // A stack will look like this:
14526
+ //
14527
+ // Error
14528
+ // at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
14529
+ // at Global code (http://localhost/components/prism-core.js:606:1)
14530
+
14531
+ var src = (/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(err.stack) || [])[1];
14532
+ if (src) {
14533
+ var scripts = document.getElementsByTagName('script');
14534
+ for (var i in scripts) {
14535
+ if (scripts[i].src == src) {
14536
+ return scripts[i];
14444
14537
  }
14445
14538
  }
14446
14539
  }
14540
+ return null;
14541
+ }
14542
+ },
14447
14543
 
14448
- ret[token] = grammar[token];
14544
+ /**
14545
+ * Returns whether a given class is active for `element`.
14546
+ *
14547
+ * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
14548
+ * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
14549
+ * given class is just the given class with a `no-` prefix.
14550
+ *
14551
+ * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
14552
+ * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
14553
+ * ancestors have the given class or the negated version of it, then the default activation will be returned.
14554
+ *
14555
+ * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
14556
+ * version of it, the class is considered active.
14557
+ *
14558
+ * @param {Element} element
14559
+ * @param {string} className
14560
+ * @param {boolean} [defaultActivation=false]
14561
+ * @returns {boolean}
14562
+ */
14563
+ isActive: function (element, className, defaultActivation) {
14564
+ var no = 'no-' + className;
14565
+
14566
+ while (element) {
14567
+ var classList = element.classList;
14568
+ if (classList.contains(className)) {
14569
+ return true;
14570
+ }
14571
+ if (classList.contains(no)) {
14572
+ return false;
14573
+ }
14574
+ element = element.parentElement;
14449
14575
  }
14576
+ return !!defaultActivation;
14450
14577
  }
14451
-
14452
- // Update references in other language definitions
14453
- _.languages.DFS(_.languages, function(key, value) {
14454
- if (value === root[inside] && key != inside) {
14455
- this[key] = ret;
14578
+ },
14579
+
14580
+ /**
14581
+ * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
14582
+ *
14583
+ * @namespace
14584
+ * @memberof Prism
14585
+ * @public
14586
+ */
14587
+ languages: {
14588
+ /**
14589
+ * The grammar for plain, unformatted text.
14590
+ */
14591
+ plain: plainTextGrammar,
14592
+ plaintext: plainTextGrammar,
14593
+ text: plainTextGrammar,
14594
+ txt: plainTextGrammar,
14595
+
14596
+ /**
14597
+ * Creates a deep copy of the language with the given id and appends the given tokens.
14598
+ *
14599
+ * If a token in `redef` also appears in the copied language, then the existing token in the copied language
14600
+ * will be overwritten at its original position.
14601
+ *
14602
+ * ## Best practices
14603
+ *
14604
+ * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
14605
+ * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
14606
+ * understand the language definition because, normally, the order of tokens matters in Prism grammars.
14607
+ *
14608
+ * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
14609
+ * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
14610
+ *
14611
+ * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
14612
+ * @param {Grammar} redef The new tokens to append.
14613
+ * @returns {Grammar} The new language created.
14614
+ * @public
14615
+ * @example
14616
+ * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
14617
+ * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
14618
+ * // at its original position
14619
+ * 'comment': { ... },
14620
+ * // CSS doesn't have a 'color' token, so this token will be appended
14621
+ * 'color': /\b(?:red|green|blue)\b/
14622
+ * });
14623
+ */
14624
+ extend: function (id, redef) {
14625
+ var lang = _.util.clone(_.languages[id]);
14626
+
14627
+ for (var key in redef) {
14628
+ lang[key] = redef[key];
14456
14629
  }
14457
- });
14458
14630
 
14459
- return root[inside] = ret;
14460
- },
14631
+ return lang;
14632
+ },
14461
14633
 
14462
- // Traverse a language definition with Depth First Search
14463
- DFS: function(o, callback, type, visited) {
14464
- visited = visited || {};
14465
- for (var i in o) {
14466
- if (o.hasOwnProperty(i)) {
14467
- callback.call(o, i, o[i], type || i);
14634
+ /**
14635
+ * Inserts tokens _before_ another token in a language definition or any other grammar.
14636
+ *
14637
+ * ## Usage
14638
+ *
14639
+ * This helper method makes it easy to modify existing languages. For example, the CSS language definition
14640
+ * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
14641
+ * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
14642
+ * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
14643
+ * this:
14644
+ *
14645
+ * ```js
14646
+ * Prism.languages.markup.style = {
14647
+ * // token
14648
+ * };
14649
+ * ```
14650
+ *
14651
+ * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
14652
+ * before existing tokens. For the CSS example above, you would use it like this:
14653
+ *
14654
+ * ```js
14655
+ * Prism.languages.insertBefore('markup', 'cdata', {
14656
+ * 'style': {
14657
+ * // token
14658
+ * }
14659
+ * });
14660
+ * ```
14661
+ *
14662
+ * ## Special cases
14663
+ *
14664
+ * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
14665
+ * will be ignored.
14666
+ *
14667
+ * This behavior can be used to insert tokens after `before`:
14668
+ *
14669
+ * ```js
14670
+ * Prism.languages.insertBefore('markup', 'comment', {
14671
+ * 'comment': Prism.languages.markup.comment,
14672
+ * // tokens after 'comment'
14673
+ * });
14674
+ * ```
14675
+ *
14676
+ * ## Limitations
14677
+ *
14678
+ * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
14679
+ * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
14680
+ * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
14681
+ * deleting properties which is necessary to insert at arbitrary positions.
14682
+ *
14683
+ * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
14684
+ * Instead, it will create a new object and replace all references to the target object with the new one. This
14685
+ * can be done without temporarily deleting properties, so the iteration order is well-defined.
14686
+ *
14687
+ * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
14688
+ * you hold the target object in a variable, then the value of the variable will not change.
14689
+ *
14690
+ * ```js
14691
+ * var oldMarkup = Prism.languages.markup;
14692
+ * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
14693
+ *
14694
+ * assert(oldMarkup !== Prism.languages.markup);
14695
+ * assert(newMarkup === Prism.languages.markup);
14696
+ * ```
14697
+ *
14698
+ * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
14699
+ * object to be modified.
14700
+ * @param {string} before The key to insert before.
14701
+ * @param {Grammar} insert An object containing the key-value pairs to be inserted.
14702
+ * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
14703
+ * object to be modified.
14704
+ *
14705
+ * Defaults to `Prism.languages`.
14706
+ * @returns {Grammar} The new grammar object.
14707
+ * @public
14708
+ */
14709
+ insertBefore: function (inside, before, insert, root) {
14710
+ root = root || /** @type {any} */ (_.languages);
14711
+ var grammar = root[inside];
14712
+ /** @type {Grammar} */
14713
+ var ret = {};
14714
+
14715
+ for (var token in grammar) {
14716
+ if (grammar.hasOwnProperty(token)) {
14717
+
14718
+ if (token == before) {
14719
+ for (var newToken in insert) {
14720
+ if (insert.hasOwnProperty(newToken)) {
14721
+ ret[newToken] = insert[newToken];
14722
+ }
14723
+ }
14724
+ }
14468
14725
 
14469
- if (_.util.type(o[i]) === 'Object' && !visited[_.util.objId(o[i])]) {
14470
- visited[_.util.objId(o[i])] = true;
14471
- _.languages.DFS(o[i], callback, null, visited);
14726
+ // Do not insert token which also occur in insert. See #1525
14727
+ if (!insert.hasOwnProperty(token)) {
14728
+ ret[token] = grammar[token];
14729
+ }
14472
14730
  }
14473
- else if (_.util.type(o[i]) === 'Array' && !visited[_.util.objId(o[i])]) {
14474
- visited[_.util.objId(o[i])] = true;
14475
- _.languages.DFS(o[i], callback, i, visited);
14731
+ }
14732
+
14733
+ var old = root[inside];
14734
+ root[inside] = ret;
14735
+
14736
+ // Update references in other language definitions
14737
+ _.languages.DFS(_.languages, function (key, value) {
14738
+ if (value === old && key != inside) {
14739
+ this[key] = ret;
14740
+ }
14741
+ });
14742
+
14743
+ return ret;
14744
+ },
14745
+
14746
+ // Traverse a language definition with Depth First Search
14747
+ DFS: function DFS(o, callback, type, visited) {
14748
+ visited = visited || {};
14749
+
14750
+ var objId = _.util.objId;
14751
+
14752
+ for (var i in o) {
14753
+ if (o.hasOwnProperty(i)) {
14754
+ callback.call(o, i, o[i], type || i);
14755
+
14756
+ var property = o[i];
14757
+ var propertyType = _.util.type(property);
14758
+
14759
+ if (propertyType === 'Object' && !visited[objId(property)]) {
14760
+ visited[objId(property)] = true;
14761
+ DFS(property, callback, null, visited);
14762
+ } else if (propertyType === 'Array' && !visited[objId(property)]) {
14763
+ visited[objId(property)] = true;
14764
+ DFS(property, callback, i, visited);
14765
+ }
14476
14766
  }
14477
14767
  }
14478
14768
  }
14479
- }
14480
- },
14481
- plugins: {},
14482
-
14483
- highlightAll: function(async, callback) {
14484
- var elements = document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');
14769
+ },
14485
14770
 
14486
- for (var i=0, element; element = elements[i++];) {
14487
- _.highlightElement(element, async === true, callback);
14488
- }
14489
- },
14771
+ plugins: {},
14490
14772
 
14491
- highlightElement: function(element, async, callback) {
14492
- // Find language
14493
- var language, grammar, parent = element;
14773
+ /**
14774
+ * This is the most high-level function in Prism’s API.
14775
+ * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
14776
+ * each one of them.
14777
+ *
14778
+ * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
14779
+ *
14780
+ * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
14781
+ * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
14782
+ * @memberof Prism
14783
+ * @public
14784
+ */
14785
+ highlightAll: function (async, callback) {
14786
+ _.highlightAllUnder(document, async, callback);
14787
+ },
14494
14788
 
14495
- while (parent && !lang.test(parent.className)) {
14496
- parent = parent.parentNode;
14497
- }
14789
+ /**
14790
+ * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
14791
+ * {@link Prism.highlightElement} on each one of them.
14792
+ *
14793
+ * The following hooks will be run:
14794
+ * 1. `before-highlightall`
14795
+ * 2. `before-all-elements-highlight`
14796
+ * 3. All hooks of {@link Prism.highlightElement} for each element.
14797
+ *
14798
+ * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
14799
+ * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
14800
+ * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
14801
+ * @memberof Prism
14802
+ * @public
14803
+ */
14804
+ highlightAllUnder: function (container, async, callback) {
14805
+ var env = {
14806
+ callback: callback,
14807
+ container: container,
14808
+ selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
14809
+ };
14498
14810
 
14499
- if (parent) {
14500
- language = (parent.className.match(lang) || [,''])[1];
14501
- grammar = _.languages[language];
14502
- }
14811
+ _.hooks.run('before-highlightall', env);
14503
14812
 
14504
- // Set language on the element, if not present
14505
- element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
14813
+ env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
14506
14814
 
14507
- // Set language on the parent, for styling
14508
- parent = element.parentNode;
14815
+ _.hooks.run('before-all-elements-highlight', env);
14509
14816
 
14510
- if (/pre/i.test(parent.nodeName)) {
14511
- parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
14512
- }
14817
+ for (var i = 0, element; (element = env.elements[i++]);) {
14818
+ _.highlightElement(element, async === true, env.callback);
14819
+ }
14820
+ },
14513
14821
 
14514
- var code = element.textContent;
14822
+ /**
14823
+ * Highlights the code inside a single element.
14824
+ *
14825
+ * The following hooks will be run:
14826
+ * 1. `before-sanity-check`
14827
+ * 2. `before-highlight`
14828
+ * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
14829
+ * 4. `before-insert`
14830
+ * 5. `after-highlight`
14831
+ * 6. `complete`
14832
+ *
14833
+ * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
14834
+ * the element's language.
14835
+ *
14836
+ * @param {Element} element The element containing the code.
14837
+ * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
14838
+ * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
14839
+ * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
14840
+ * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
14841
+ *
14842
+ * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
14843
+ * asynchronous highlighting to work. You can build your own bundle on the
14844
+ * [Download page](https://prismjs.com/download.html).
14845
+ * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
14846
+ * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
14847
+ * @memberof Prism
14848
+ * @public
14849
+ */
14850
+ highlightElement: function (element, async, callback) {
14851
+ // Find language
14852
+ var language = _.util.getLanguage(element);
14853
+ var grammar = _.languages[language];
14515
14854
 
14516
- var env = {
14517
- element: element,
14518
- language: language,
14519
- grammar: grammar,
14520
- code: code
14521
- };
14855
+ // Set language on the element, if not present
14856
+ element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
14522
14857
 
14523
- if (!code || !grammar) {
14524
- _.hooks.run('complete', env);
14525
- return;
14526
- }
14858
+ // Set language on the parent, for styling
14859
+ var parent = element.parentElement;
14860
+ if (parent && parent.nodeName.toLowerCase() === 'pre') {
14861
+ parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language;
14862
+ }
14527
14863
 
14528
- _.hooks.run('before-highlight', env);
14864
+ var code = element.textContent;
14529
14865
 
14530
- if (async && _self.Worker) {
14531
- var worker = new Worker(_.filename);
14866
+ var env = {
14867
+ element: element,
14868
+ language: language,
14869
+ grammar: grammar,
14870
+ code: code
14871
+ };
14532
14872
 
14533
- worker.onmessage = function(evt) {
14534
- env.highlightedCode = evt.data;
14873
+ function insertHighlightedCode(highlightedCode) {
14874
+ env.highlightedCode = highlightedCode;
14535
14875
 
14536
14876
  _.hooks.run('before-insert', env);
14537
14877
 
14538
14878
  env.element.innerHTML = env.highlightedCode;
14539
14879
 
14540
- callback && callback.call(env.element);
14541
14880
  _.hooks.run('after-highlight', env);
14542
14881
  _.hooks.run('complete', env);
14882
+ callback && callback.call(env.element);
14883
+ }
14884
+
14885
+ _.hooks.run('before-sanity-check', env);
14886
+
14887
+ // plugins may change/add the parent/element
14888
+ parent = env.element.parentElement;
14889
+ if (parent && parent.nodeName.toLowerCase() === 'pre' && !parent.hasAttribute('tabindex')) {
14890
+ parent.setAttribute('tabindex', '0');
14891
+ }
14892
+
14893
+ if (!env.code) {
14894
+ _.hooks.run('complete', env);
14895
+ callback && callback.call(env.element);
14896
+ return;
14897
+ }
14898
+
14899
+ _.hooks.run('before-highlight', env);
14900
+
14901
+ if (!env.grammar) {
14902
+ insertHighlightedCode(_.util.encode(env.code));
14903
+ return;
14904
+ }
14905
+
14906
+ if (async && _self.Worker) {
14907
+ var worker = new Worker(_.filename);
14908
+
14909
+ worker.onmessage = function (evt) {
14910
+ insertHighlightedCode(evt.data);
14911
+ };
14912
+
14913
+ worker.postMessage(JSON.stringify({
14914
+ language: env.language,
14915
+ code: env.code,
14916
+ immediateClose: true
14917
+ }));
14918
+ } else {
14919
+ insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
14920
+ }
14921
+ },
14922
+
14923
+ /**
14924
+ * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
14925
+ * and the language definitions to use, and returns a string with the HTML produced.
14926
+ *
14927
+ * The following hooks will be run:
14928
+ * 1. `before-tokenize`
14929
+ * 2. `after-tokenize`
14930
+ * 3. `wrap`: On each {@link Token}.
14931
+ *
14932
+ * @param {string} text A string with the code to be highlighted.
14933
+ * @param {Grammar} grammar An object containing the tokens to use.
14934
+ *
14935
+ * Usually a language definition like `Prism.languages.markup`.
14936
+ * @param {string} language The name of the language definition passed to `grammar`.
14937
+ * @returns {string} The highlighted HTML.
14938
+ * @memberof Prism
14939
+ * @public
14940
+ * @example
14941
+ * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
14942
+ */
14943
+ highlight: function (text, grammar, language) {
14944
+ var env = {
14945
+ code: text,
14946
+ grammar: grammar,
14947
+ language: language
14543
14948
  };
14949
+ _.hooks.run('before-tokenize', env);
14950
+ env.tokens = _.tokenize(env.code, env.grammar);
14951
+ _.hooks.run('after-tokenize', env);
14952
+ return Token.stringify(_.util.encode(env.tokens), env.language);
14953
+ },
14544
14954
 
14545
- worker.postMessage(JSON.stringify({
14546
- language: env.language,
14547
- code: env.code,
14548
- immediateClose: true
14549
- }));
14550
- }
14551
- else {
14552
- env.highlightedCode = _.highlight(env.code, env.grammar, env.language);
14955
+ /**
14956
+ * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
14957
+ * and the language definitions to use, and returns an array with the tokenized code.
14958
+ *
14959
+ * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
14960
+ *
14961
+ * This method could be useful in other contexts as well, as a very crude parser.
14962
+ *
14963
+ * @param {string} text A string with the code to be highlighted.
14964
+ * @param {Grammar} grammar An object containing the tokens to use.
14965
+ *
14966
+ * Usually a language definition like `Prism.languages.markup`.
14967
+ * @returns {TokenStream} An array of strings and tokens, a token stream.
14968
+ * @memberof Prism
14969
+ * @public
14970
+ * @example
14971
+ * let code = `var foo = 0;`;
14972
+ * let tokens = Prism.tokenize(code, Prism.languages.javascript);
14973
+ * tokens.forEach(token => {
14974
+ * if (token instanceof Prism.Token && token.type === 'number') {
14975
+ * console.log(`Found numeric literal: ${token.content}`);
14976
+ * }
14977
+ * });
14978
+ */
14979
+ tokenize: function (text, grammar) {
14980
+ var rest = grammar.rest;
14981
+ if (rest) {
14982
+ for (var token in rest) {
14983
+ grammar[token] = rest[token];
14984
+ }
14553
14985
 
14554
- _.hooks.run('before-insert', env);
14986
+ delete grammar.rest;
14987
+ }
14555
14988
 
14556
- env.element.innerHTML = env.highlightedCode;
14989
+ var tokenList = new LinkedList();
14990
+ addAfter(tokenList, tokenList.head, text);
14557
14991
 
14558
- callback && callback.call(element);
14992
+ matchGrammar(text, tokenList, grammar, tokenList.head, 0);
14559
14993
 
14560
- _.hooks.run('after-highlight', env);
14561
- _.hooks.run('complete', env);
14562
- }
14563
- },
14994
+ return toArray(tokenList);
14995
+ },
14996
+
14997
+ /**
14998
+ * @namespace
14999
+ * @memberof Prism
15000
+ * @public
15001
+ */
15002
+ hooks: {
15003
+ all: {},
15004
+
15005
+ /**
15006
+ * Adds the given callback to the list of callbacks for the given hook.
15007
+ *
15008
+ * The callback will be invoked when the hook it is registered for is run.
15009
+ * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
15010
+ *
15011
+ * One callback function can be registered to multiple hooks and the same hook multiple times.
15012
+ *
15013
+ * @param {string} name The name of the hook.
15014
+ * @param {HookCallback} callback The callback function which is given environment variables.
15015
+ * @public
15016
+ */
15017
+ add: function (name, callback) {
15018
+ var hooks = _.hooks.all;
15019
+
15020
+ hooks[name] = hooks[name] || [];
15021
+
15022
+ hooks[name].push(callback);
15023
+ },
15024
+
15025
+ /**
15026
+ * Runs a hook invoking all registered callbacks with the given environment variables.
15027
+ *
15028
+ * Callbacks will be invoked synchronously and in the order in which they were registered.
15029
+ *
15030
+ * @param {string} name The name of the hook.
15031
+ * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
15032
+ * @public
15033
+ */
15034
+ run: function (name, env) {
15035
+ var callbacks = _.hooks.all[name];
15036
+
15037
+ if (!callbacks || !callbacks.length) {
15038
+ return;
15039
+ }
15040
+
15041
+ for (var i = 0, callback; (callback = callbacks[i++]);) {
15042
+ callback(env);
15043
+ }
15044
+ }
15045
+ },
15046
+
15047
+ Token: Token
15048
+ };
15049
+ _self.Prism = _;
14564
15050
 
14565
- highlight: function (text, grammar, language) {
14566
- var tokens = _.tokenize(text, grammar);
14567
- return Token.stringify(_.util.encode(tokens), language);
14568
- },
14569
15051
 
14570
- tokenize: function(text, grammar, language) {
14571
- var Token = _.Token;
15052
+ // Typescript note:
15053
+ // The following can be used to import the Token type in JSDoc:
15054
+ //
15055
+ // @typedef {InstanceType<import("./prism-core")["Token"]>} Token
15056
+
15057
+ /**
15058
+ * Creates a new token.
15059
+ *
15060
+ * @param {string} type See {@link Token#type type}
15061
+ * @param {string | TokenStream} content See {@link Token#content content}
15062
+ * @param {string|string[]} [alias] The alias(es) of the token.
15063
+ * @param {string} [matchedStr=""] A copy of the full string this token was created from.
15064
+ * @class
15065
+ * @global
15066
+ * @public
15067
+ */
15068
+ function Token(type, content, alias, matchedStr) {
15069
+ /**
15070
+ * The type of the token.
15071
+ *
15072
+ * This is usually the key of a pattern in a {@link Grammar}.
15073
+ *
15074
+ * @type {string}
15075
+ * @see GrammarToken
15076
+ * @public
15077
+ */
15078
+ this.type = type;
15079
+ /**
15080
+ * The strings or tokens contained by this token.
15081
+ *
15082
+ * This will be a token stream if the pattern matched also defined an `inside` grammar.
15083
+ *
15084
+ * @type {string | TokenStream}
15085
+ * @public
15086
+ */
15087
+ this.content = content;
15088
+ /**
15089
+ * The alias(es) of the token.
15090
+ *
15091
+ * @type {string|string[]}
15092
+ * @see GrammarToken
15093
+ * @public
15094
+ */
15095
+ this.alias = alias;
15096
+ // Copy of the full string this token was created from
15097
+ this.length = (matchedStr || '').length | 0;
15098
+ }
15099
+
15100
+ /**
15101
+ * A token stream is an array of strings and {@link Token Token} objects.
15102
+ *
15103
+ * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
15104
+ * them.
15105
+ *
15106
+ * 1. No adjacent strings.
15107
+ * 2. No empty strings.
15108
+ *
15109
+ * The only exception here is the token stream that only contains the empty string and nothing else.
15110
+ *
15111
+ * @typedef {Array<string | Token>} TokenStream
15112
+ * @global
15113
+ * @public
15114
+ */
14572
15115
 
14573
- var strarr = [text];
15116
+ /**
15117
+ * Converts the given token or token stream to an HTML representation.
15118
+ *
15119
+ * The following hooks will be run:
15120
+ * 1. `wrap`: On each {@link Token}.
15121
+ *
15122
+ * @param {string | Token | TokenStream} o The token or token stream to be converted.
15123
+ * @param {string} language The name of current language.
15124
+ * @returns {string} The HTML representation of the token or token stream.
15125
+ * @memberof Token
15126
+ * @static
15127
+ */
15128
+ Token.stringify = function stringify(o, language) {
15129
+ if (typeof o == 'string') {
15130
+ return o;
15131
+ }
15132
+ if (Array.isArray(o)) {
15133
+ var s = '';
15134
+ o.forEach(function (e) {
15135
+ s += stringify(e, language);
15136
+ });
15137
+ return s;
15138
+ }
14574
15139
 
14575
- var rest = grammar.rest;
15140
+ var env = {
15141
+ type: o.type,
15142
+ content: stringify(o.content, language),
15143
+ tag: 'span',
15144
+ classes: ['token', o.type],
15145
+ attributes: {},
15146
+ language: language
15147
+ };
14576
15148
 
14577
- if (rest) {
14578
- for (var token in rest) {
14579
- grammar[token] = rest[token];
15149
+ var aliases = o.alias;
15150
+ if (aliases) {
15151
+ if (Array.isArray(aliases)) {
15152
+ Array.prototype.push.apply(env.classes, aliases);
15153
+ } else {
15154
+ env.classes.push(aliases);
14580
15155
  }
15156
+ }
15157
+
15158
+ _.hooks.run('wrap', env);
15159
+
15160
+ var attributes = '';
15161
+ for (var name in env.attributes) {
15162
+ attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
15163
+ }
15164
+
15165
+ return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>';
15166
+ };
14581
15167
 
14582
- delete grammar.rest;
15168
+ /**
15169
+ * @param {RegExp} pattern
15170
+ * @param {number} pos
15171
+ * @param {string} text
15172
+ * @param {boolean} lookbehind
15173
+ * @returns {RegExpExecArray | null}
15174
+ */
15175
+ function matchPattern(pattern, pos, text, lookbehind) {
15176
+ pattern.lastIndex = pos;
15177
+ var match = pattern.exec(text);
15178
+ if (match && lookbehind && match[1]) {
15179
+ // change the match to remove the text matched by the Prism lookbehind group
15180
+ var lookbehindLength = match[1].length;
15181
+ match.index += lookbehindLength;
15182
+ match[0] = match[0].slice(lookbehindLength);
14583
15183
  }
15184
+ return match;
15185
+ }
14584
15186
 
14585
- tokenloop: for (var token in grammar) {
14586
- if(!grammar.hasOwnProperty(token) || !grammar[token]) {
15187
+ /**
15188
+ * @param {string} text
15189
+ * @param {LinkedList<string | Token>} tokenList
15190
+ * @param {any} grammar
15191
+ * @param {LinkedListNode<string | Token>} startNode
15192
+ * @param {number} startPos
15193
+ * @param {RematchOptions} [rematch]
15194
+ * @returns {void}
15195
+ * @private
15196
+ *
15197
+ * @typedef RematchOptions
15198
+ * @property {string} cause
15199
+ * @property {number} reach
15200
+ */
15201
+ function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) {
15202
+ for (var token in grammar) {
15203
+ if (!grammar.hasOwnProperty(token) || !grammar[token]) {
14587
15204
  continue;
14588
15205
  }
14589
15206
 
14590
15207
  var patterns = grammar[token];
14591
- patterns = (_.util.type(patterns) === "Array") ? patterns : [patterns];
15208
+ patterns = Array.isArray(patterns) ? patterns : [patterns];
14592
15209
 
14593
15210
  for (var j = 0; j < patterns.length; ++j) {
14594
- var pattern = patterns[j],
14595
- inside = pattern.inside,
14596
- lookbehind = !!pattern.lookbehind,
14597
- lookbehindLength = 0,
14598
- alias = pattern.alias;
15211
+ if (rematch && rematch.cause == token + ',' + j) {
15212
+ return;
15213
+ }
15214
+
15215
+ var patternObj = patterns[j];
15216
+ var inside = patternObj.inside;
15217
+ var lookbehind = !!patternObj.lookbehind;
15218
+ var greedy = !!patternObj.greedy;
15219
+ var alias = patternObj.alias;
15220
+
15221
+ if (greedy && !patternObj.pattern.global) {
15222
+ // Without the global flag, lastIndex won't work
15223
+ var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
15224
+ patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g');
15225
+ }
14599
15226
 
14600
- pattern = pattern.pattern || pattern;
15227
+ /** @type {RegExp} */
15228
+ var pattern = patternObj.pattern || patternObj;
14601
15229
 
14602
- for (var i=0; i<strarr.length; i++) { // Don’t cache length as it changes during the loop
15230
+ for ( // iterate the token list and keep track of the current token/string position
15231
+ var currentNode = startNode.next, pos = startPos;
15232
+ currentNode !== tokenList.tail;
15233
+ pos += currentNode.value.length, currentNode = currentNode.next
15234
+ ) {
15235
+
15236
+ if (rematch && pos >= rematch.reach) {
15237
+ break;
15238
+ }
14603
15239
 
14604
- var str = strarr[i];
15240
+ var str = currentNode.value;
14605
15241
 
14606
- if (strarr.length > text.length) {
15242
+ if (tokenList.length > text.length) {
14607
15243
  // Something went terribly wrong, ABORT, ABORT!
14608
- break tokenloop;
15244
+ return;
14609
15245
  }
14610
15246
 
14611
15247
  if (str instanceof Token) {
14612
15248
  continue;
14613
15249
  }
14614
15250
 
14615
- pattern.lastIndex = 0;
14616
-
14617
- var match = pattern.exec(str);
15251
+ var removeCount = 1; // this is the to parameter of removeBetween
15252
+ var match;
14618
15253
 
14619
- if (match) {
14620
- if(lookbehind) {
14621
- lookbehindLength = match[1].length;
15254
+ if (greedy) {
15255
+ match = matchPattern(pattern, pos, text, lookbehind);
15256
+ if (!match) {
15257
+ break;
14622
15258
  }
14623
15259
 
14624
- var from = match.index - 1 + lookbehindLength,
14625
- match = match[0].slice(lookbehindLength),
14626
- len = match.length,
14627
- to = from + len,
14628
- before = str.slice(0, from + 1),
14629
- after = str.slice(to + 1);
14630
-
14631
- var args = [i, 1];
15260
+ var from = match.index;
15261
+ var to = match.index + match[0].length;
15262
+ var p = pos;
14632
15263
 
14633
- if (before) {
14634
- args.push(before);
15264
+ // find the node that contains the match
15265
+ p += currentNode.value.length;
15266
+ while (from >= p) {
15267
+ currentNode = currentNode.next;
15268
+ p += currentNode.value.length;
14635
15269
  }
15270
+ // adjust pos (and p)
15271
+ p -= currentNode.value.length;
15272
+ pos = p;
14636
15273
 
14637
- var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias);
15274
+ // the current node is a Token, then the match starts inside another Token, which is invalid
15275
+ if (currentNode.value instanceof Token) {
15276
+ continue;
15277
+ }
14638
15278
 
14639
- args.push(wrapped);
15279
+ // find the last node which is affected by this match
15280
+ for (
15281
+ var k = currentNode;
15282
+ k !== tokenList.tail && (p < to || typeof k.value === 'string');
15283
+ k = k.next
15284
+ ) {
15285
+ removeCount++;
15286
+ p += k.value.length;
15287
+ }
15288
+ removeCount--;
14640
15289
 
14641
- if (after) {
14642
- args.push(after);
15290
+ // replace with the new match
15291
+ str = text.slice(pos, p);
15292
+ match.index -= pos;
15293
+ } else {
15294
+ match = matchPattern(pattern, 0, str, lookbehind);
15295
+ if (!match) {
15296
+ continue;
14643
15297
  }
15298
+ }
15299
+
15300
+ // eslint-disable-next-line no-redeclare
15301
+ var from = match.index;
15302
+ var matchStr = match[0];
15303
+ var before = str.slice(0, from);
15304
+ var after = str.slice(from + matchStr.length);
14644
15305
 
14645
- Array.prototype.splice.apply(strarr, args);
15306
+ var reach = pos + str.length;
15307
+ if (rematch && reach > rematch.reach) {
15308
+ rematch.reach = reach;
14646
15309
  }
14647
- }
14648
- }
14649
- }
14650
15310
 
14651
- return strarr;
14652
- },
15311
+ var removeFrom = currentNode.prev;
14653
15312
 
14654
- hooks: {
14655
- all: {},
15313
+ if (before) {
15314
+ removeFrom = addAfter(tokenList, removeFrom, before);
15315
+ pos += before.length;
15316
+ }
14656
15317
 
14657
- add: function (name, callback) {
14658
- var hooks = _.hooks.all;
15318
+ removeRange(tokenList, removeFrom, removeCount);
14659
15319
 
14660
- hooks[name] = hooks[name] || [];
15320
+ var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr);
15321
+ currentNode = addAfter(tokenList, removeFrom, wrapped);
14661
15322
 
14662
- hooks[name].push(callback);
14663
- },
15323
+ if (after) {
15324
+ addAfter(tokenList, currentNode, after);
15325
+ }
14664
15326
 
14665
- run: function (name, env) {
14666
- var callbacks = _.hooks.all[name];
15327
+ if (removeCount > 1) {
15328
+ // at least one Token object was removed, so we have to do some rematching
15329
+ // this can only happen if the current pattern is greedy
14667
15330
 
14668
- if (!callbacks || !callbacks.length) {
14669
- return;
14670
- }
15331
+ /** @type {RematchOptions} */
15332
+ var nestedRematch = {
15333
+ cause: token + ',' + j,
15334
+ reach: reach
15335
+ };
15336
+ matchGrammar(text, tokenList, grammar, currentNode.prev, pos, nestedRematch);
14671
15337
 
14672
- for (var i=0, callback; callback = callbacks[i++];) {
14673
- callback(env);
15338
+ // the reach might have been extended because of the rematching
15339
+ if (rematch && nestedRematch.reach > rematch.reach) {
15340
+ rematch.reach = nestedRematch.reach;
15341
+ }
15342
+ }
15343
+ }
14674
15344
  }
14675
15345
  }
14676
15346
  }
14677
- };
14678
15347
 
14679
- var Token = _.Token = function(type, content, alias) {
14680
- this.type = type;
14681
- this.content = content;
14682
- this.alias = alias;
14683
- };
15348
+ /**
15349
+ * @typedef LinkedListNode
15350
+ * @property {T} value
15351
+ * @property {LinkedListNode<T> | null} prev The previous node.
15352
+ * @property {LinkedListNode<T> | null} next The next node.
15353
+ * @template T
15354
+ * @private
15355
+ */
14684
15356
 
14685
- Token.stringify = function(o, language, parent) {
14686
- if (typeof o == 'string') {
14687
- return o;
14688
- }
15357
+ /**
15358
+ * @template T
15359
+ * @private
15360
+ */
15361
+ function LinkedList() {
15362
+ /** @type {LinkedListNode<T>} */
15363
+ var head = { value: null, prev: null, next: null };
15364
+ /** @type {LinkedListNode<T>} */
15365
+ var tail = { value: null, prev: head, next: null };
15366
+ head.next = tail;
14689
15367
 
14690
- if (_.util.type(o) === 'Array') {
14691
- return o.map(function(element) {
14692
- return Token.stringify(element, language, o);
14693
- }).join('');
15368
+ /** @type {LinkedListNode<T>} */
15369
+ this.head = head;
15370
+ /** @type {LinkedListNode<T>} */
15371
+ this.tail = tail;
15372
+ this.length = 0;
14694
15373
  }
14695
15374
 
14696
- var env = {
14697
- type: o.type,
14698
- content: Token.stringify(o.content, language, parent),
14699
- tag: 'span',
14700
- classes: ['token', o.type],
14701
- attributes: {},
14702
- language: language,
14703
- parent: parent
14704
- };
15375
+ /**
15376
+ * Adds a new node with the given value to the list.
15377
+ *
15378
+ * @param {LinkedList<T>} list
15379
+ * @param {LinkedListNode<T>} node
15380
+ * @param {T} value
15381
+ * @returns {LinkedListNode<T>} The added node.
15382
+ * @template T
15383
+ */
15384
+ function addAfter(list, node, value) {
15385
+ // assumes that node != list.tail && values.length >= 0
15386
+ var next = node.next;
14705
15387
 
14706
- if (env.type == 'comment') {
14707
- env.attributes['spellcheck'] = 'true';
14708
- }
15388
+ var newNode = { value: value, prev: node, next: next };
15389
+ node.next = newNode;
15390
+ next.prev = newNode;
15391
+ list.length++;
14709
15392
 
14710
- if (o.alias) {
14711
- var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias];
14712
- Array.prototype.push.apply(env.classes, aliases);
15393
+ return newNode;
15394
+ }
15395
+ /**
15396
+ * Removes `count` nodes after the given node. The given node will not be removed.
15397
+ *
15398
+ * @param {LinkedList<T>} list
15399
+ * @param {LinkedListNode<T>} node
15400
+ * @param {number} count
15401
+ * @template T
15402
+ */
15403
+ function removeRange(list, node, count) {
15404
+ var next = node.next;
15405
+ for (var i = 0; i < count && next !== list.tail; i++) {
15406
+ next = next.next;
15407
+ }
15408
+ node.next = next;
15409
+ next.prev = node;
15410
+ list.length -= i;
15411
+ }
15412
+ /**
15413
+ * @param {LinkedList<T>} list
15414
+ * @returns {T[]}
15415
+ * @template T
15416
+ */
15417
+ function toArray(list) {
15418
+ var array = [];
15419
+ var node = list.head.next;
15420
+ while (node !== list.tail) {
15421
+ array.push(node.value);
15422
+ node = node.next;
15423
+ }
15424
+ return array;
14713
15425
  }
14714
15426
 
14715
- _.hooks.run('wrap', env);
14716
-
14717
- var attributes = '';
14718
15427
 
14719
- for (var name in env.attributes) {
14720
- attributes += (attributes ? ' ' : '') + name + '="' + (env.attributes[name] || '') + '"';
14721
- }
15428
+ if (!_self.document) {
15429
+ if (!_self.addEventListener) {
15430
+ // in Node.js
15431
+ return _;
15432
+ }
14722
15433
 
14723
- return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + '</' + env.tag + '>';
15434
+ if (!_.disableWorkerMessageHandler) {
15435
+ // In worker
15436
+ _self.addEventListener('message', function (evt) {
15437
+ var message = JSON.parse(evt.data);
15438
+ var lang = message.language;
15439
+ var code = message.code;
15440
+ var immediateClose = message.immediateClose;
14724
15441
 
14725
- };
15442
+ _self.postMessage(_.highlight(code, _.languages[lang], lang));
15443
+ if (immediateClose) {
15444
+ _self.close();
15445
+ }
15446
+ }, false);
15447
+ }
14726
15448
 
14727
- if (!_self.document) {
14728
- if (!_self.addEventListener) {
14729
- // in Node.js
14730
- return _self.Prism;
15449
+ return _;
14731
15450
  }
14732
- // In worker
14733
- _self.addEventListener('message', function(evt) {
14734
- var message = JSON.parse(evt.data),
14735
- lang = message.language,
14736
- code = message.code,
14737
- immediateClose = message.immediateClose;
14738
15451
 
14739
- _self.postMessage(_.highlight(code, _.languages[lang], lang));
14740
- if (immediateClose) {
14741
- _self.close();
14742
- }
14743
- }, false);
15452
+ // Get current script and highlight
15453
+ var script = _.util.currentScript();
14744
15454
 
14745
- return _self.Prism;
14746
- }
15455
+ if (script) {
15456
+ _.filename = script.src;
14747
15457
 
14748
- //Get current script and highlight
14749
- var script = document.currentScript || [].slice.call(document.getElementsByTagName("script")).pop();
15458
+ if (script.hasAttribute('data-manual')) {
15459
+ _.manual = true;
15460
+ }
15461
+ }
14750
15462
 
14751
- if (script) {
14752
- _.filename = script.src;
15463
+ function highlightAutomaticallyCallback() {
15464
+ if (!_.manual) {
15465
+ _.highlightAll();
15466
+ }
15467
+ }
14753
15468
 
14754
- if (document.addEventListener && !script.hasAttribute('data-manual')) {
14755
- document.addEventListener('DOMContentLoaded', _.highlightAll);
15469
+ if (!_.manual) {
15470
+ // If the document state is "loading", then we'll use DOMContentLoaded.
15471
+ // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
15472
+ // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
15473
+ // might take longer one animation frame to execute which can create a race condition where only some plugins have
15474
+ // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
15475
+ // See https://github.com/PrismJS/prism/issues/2102
15476
+ var readyState = document.readyState;
15477
+ if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
15478
+ document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
15479
+ } else {
15480
+ if (window.requestAnimationFrame) {
15481
+ window.requestAnimationFrame(highlightAutomaticallyCallback);
15482
+ } else {
15483
+ window.setTimeout(highlightAutomaticallyCallback, 16);
15484
+ }
15485
+ }
14756
15486
  }
14757
- }
14758
15487
 
14759
- return _self.Prism;
15488
+ return _;
14760
15489
 
14761
- })();
15490
+ }(_self));
14762
15491
 
14763
15492
  if (typeof module !== 'undefined' && module.exports) {
14764
15493
  module.exports = Prism;
@@ -14769,30 +15498,106 @@ if (typeof global !== 'undefined') {
14769
15498
  global.Prism = Prism;
14770
15499
  }
14771
15500
 
15501
+ // some additional documentation/types
15502
+
15503
+ /**
15504
+ * The expansion of a simple `RegExp` literal to support additional properties.
15505
+ *
15506
+ * @typedef GrammarToken
15507
+ * @property {RegExp} pattern The regular expression of the token.
15508
+ * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
15509
+ * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
15510
+ * @property {boolean} [greedy=false] Whether the token is greedy.
15511
+ * @property {string|string[]} [alias] An optional alias or list of aliases.
15512
+ * @property {Grammar} [inside] The nested grammar of this token.
15513
+ *
15514
+ * The `inside` grammar will be used to tokenize the text value of each token of this kind.
15515
+ *
15516
+ * This can be used to make nested and even recursive language definitions.
15517
+ *
15518
+ * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
15519
+ * each another.
15520
+ * @global
15521
+ * @public
15522
+ */
15523
+
15524
+ /**
15525
+ * @typedef Grammar
15526
+ * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
15527
+ * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
15528
+ * @global
15529
+ * @public
15530
+ */
15531
+
15532
+ /**
15533
+ * A function which will invoked after an element was successfully highlighted.
15534
+ *
15535
+ * @callback HighlightCallback
15536
+ * @param {Element} element The element successfully highlighted.
15537
+ * @returns {void}
15538
+ * @global
15539
+ * @public
15540
+ */
15541
+
15542
+ /**
15543
+ * @callback HookCallback
15544
+ * @param {Object<string, any>} env The environment variables of the hook.
15545
+ * @returns {void}
15546
+ * @global
15547
+ * @public
15548
+ */
15549
+
14772
15550
 
14773
15551
  /* **********************************************
14774
15552
  Begin prism-markup.js
14775
15553
  ********************************************** */
14776
15554
 
14777
15555
  Prism.languages.markup = {
14778
- 'comment': /<!--[\w\W]*?-->/,
14779
- 'prolog': /<\?[\w\W]+?\?>/,
14780
- 'doctype': /<!DOCTYPE[\w\W]+?>/,
14781
- 'cdata': /<!\[CDATA\[[\w\W]*?]]>/i,
15556
+ 'comment': /<!--[\s\S]*?-->/,
15557
+ 'prolog': /<\?[\s\S]+?\?>/,
15558
+ 'doctype': {
15559
+ // https://www.w3.org/TR/xml/#NT-doctypedecl
15560
+ pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
15561
+ greedy: true,
15562
+ inside: {
15563
+ 'internal-subset': {
15564
+ pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
15565
+ lookbehind: true,
15566
+ greedy: true,
15567
+ inside: null // see below
15568
+ },
15569
+ 'string': {
15570
+ pattern: /"[^"]*"|'[^']*'/,
15571
+ greedy: true
15572
+ },
15573
+ 'punctuation': /^<!|>$|[[\]]/,
15574
+ 'doctype-tag': /^DOCTYPE/,
15575
+ 'name': /[^\s<>'"]+/
15576
+ }
15577
+ },
15578
+ 'cdata': /<!\[CDATA\[[\s\S]*?\]\]>/i,
14782
15579
  'tag': {
14783
- pattern: /<\/?(?!\d)[^\s>\/=.$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,
15580
+ pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
15581
+ greedy: true,
14784
15582
  inside: {
14785
15583
  'tag': {
14786
- pattern: /^<\/?[^\s>\/]+/i,
15584
+ pattern: /^<\/?[^\s>\/]+/,
14787
15585
  inside: {
14788
15586
  'punctuation': /^<\/?/,
14789
15587
  'namespace': /^[^\s>\/:]+:/
14790
15588
  }
14791
15589
  },
15590
+ 'special-attr': [],
14792
15591
  'attr-value': {
14793
- pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,
15592
+ pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
14794
15593
  inside: {
14795
- 'punctuation': /[=>"']/
15594
+ 'punctuation': [
15595
+ {
15596
+ pattern: /^=/,
15597
+ alias: 'attr-equals'
15598
+ },
15599
+ /"|'/
15600
+ ]
14796
15601
  }
14797
15602
  },
14798
15603
  'punctuation': /\/?>/,
@@ -14805,75 +15610,193 @@ Prism.languages.markup = {
14805
15610
 
14806
15611
  }
14807
15612
  },
14808
- 'entity': /&#?[\da-z]{1,8};/i
15613
+ 'entity': [
15614
+ {
15615
+ pattern: /&[\da-z]{1,8};/i,
15616
+ alias: 'named-entity'
15617
+ },
15618
+ /&#x?[\da-f]{1,8};/i
15619
+ ]
14809
15620
  };
14810
15621
 
15622
+ Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
15623
+ Prism.languages.markup['entity'];
15624
+ Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
15625
+
14811
15626
  // Plugin to make entity title show the real entity, idea by Roman Komarov
14812
- Prism.hooks.add('wrap', function(env) {
15627
+ Prism.hooks.add('wrap', function (env) {
14813
15628
 
14814
15629
  if (env.type === 'entity') {
14815
15630
  env.attributes['title'] = env.content.replace(/&amp;/, '&');
14816
15631
  }
14817
15632
  });
14818
15633
 
14819
- Prism.languages.xml = Prism.languages.markup;
15634
+ Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
15635
+ /**
15636
+ * Adds an inlined language to markup.
15637
+ *
15638
+ * An example of an inlined language is CSS with `<style>` tags.
15639
+ *
15640
+ * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
15641
+ * case insensitive.
15642
+ * @param {string} lang The language key.
15643
+ * @example
15644
+ * addInlined('style', 'css');
15645
+ */
15646
+ value: function addInlined(tagName, lang) {
15647
+ var includedCdataInside = {};
15648
+ includedCdataInside['language-' + lang] = {
15649
+ pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
15650
+ lookbehind: true,
15651
+ inside: Prism.languages[lang]
15652
+ };
15653
+ includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
15654
+
15655
+ var inside = {
15656
+ 'included-cdata': {
15657
+ pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
15658
+ inside: includedCdataInside
15659
+ }
15660
+ };
15661
+ inside['language-' + lang] = {
15662
+ pattern: /[\s\S]+/,
15663
+ inside: Prism.languages[lang]
15664
+ };
15665
+
15666
+ var def = {};
15667
+ def[tagName] = {
15668
+ pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
15669
+ lookbehind: true,
15670
+ greedy: true,
15671
+ inside: inside
15672
+ };
15673
+
15674
+ Prism.languages.insertBefore('markup', 'cdata', def);
15675
+ }
15676
+ });
15677
+ Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', {
15678
+ /**
15679
+ * Adds an pattern to highlight languages embedded in HTML attributes.
15680
+ *
15681
+ * An example of an inlined language is CSS with `style` attributes.
15682
+ *
15683
+ * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
15684
+ * case insensitive.
15685
+ * @param {string} lang The language key.
15686
+ * @example
15687
+ * addAttribute('style', 'css');
15688
+ */
15689
+ value: function (attrName, lang) {
15690
+ Prism.languages.markup.tag.inside['special-attr'].push({
15691
+ pattern: RegExp(
15692
+ /(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
15693
+ 'i'
15694
+ ),
15695
+ lookbehind: true,
15696
+ inside: {
15697
+ 'attr-name': /^[^\s=]+/,
15698
+ 'attr-value': {
15699
+ pattern: /=[\s\S]+/,
15700
+ inside: {
15701
+ 'value': {
15702
+ pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
15703
+ lookbehind: true,
15704
+ alias: [lang, 'language-' + lang],
15705
+ inside: Prism.languages[lang]
15706
+ },
15707
+ 'punctuation': [
15708
+ {
15709
+ pattern: /^=/,
15710
+ alias: 'attr-equals'
15711
+ },
15712
+ /"|'/
15713
+ ]
15714
+ }
15715
+ }
15716
+ }
15717
+ });
15718
+ }
15719
+ });
15720
+
14820
15721
  Prism.languages.html = Prism.languages.markup;
14821
15722
  Prism.languages.mathml = Prism.languages.markup;
14822
15723
  Prism.languages.svg = Prism.languages.markup;
14823
15724
 
15725
+ Prism.languages.xml = Prism.languages.extend('markup', {});
15726
+ Prism.languages.ssml = Prism.languages.xml;
15727
+ Prism.languages.atom = Prism.languages.xml;
15728
+ Prism.languages.rss = Prism.languages.xml;
15729
+
14824
15730
 
14825
15731
  /* **********************************************
14826
15732
  Begin prism-css.js
14827
15733
  ********************************************** */
14828
15734
 
14829
- Prism.languages.css = {
14830
- 'comment': /\/\*[\w\W]*?\*\//,
14831
- 'atrule': {
14832
- pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i,
14833
- inside: {
14834
- 'rule': /@[\w-]+/
14835
- // See rest below
14836
- }
14837
- },
14838
- 'url': /url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,
14839
- 'selector': /[^\{\}\s][^\{\};]*?(?=\s*\{)/,
14840
- 'string': /("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,
14841
- 'property': /(\b|\B)[\w-]+(?=\s*:)/i,
14842
- 'important': /\B!important\b/i,
14843
- 'function': /[-a-z0-9]+(?=\()/i,
14844
- 'punctuation': /[(){};:]/
14845
- };
15735
+ (function (Prism) {
14846
15736
 
14847
- Prism.languages.css['atrule'].inside.rest = Prism.util.clone(Prism.languages.css);
15737
+ var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
14848
15738
 
14849
- if (Prism.languages.markup) {
14850
- Prism.languages.insertBefore('markup', 'tag', {
14851
- 'style': {
14852
- pattern: /(<style[\w\W]*?>)[\w\W]*?(?=<\/style>)/i,
14853
- lookbehind: true,
14854
- inside: Prism.languages.css,
14855
- alias: 'language-css'
14856
- }
14857
- });
14858
-
14859
- Prism.languages.insertBefore('inside', 'attr-value', {
14860
- 'style-attr': {
14861
- pattern: /\s*style=("|').*?\1/i,
15739
+ Prism.languages.css = {
15740
+ 'comment': /\/\*[\s\S]*?\*\//,
15741
+ 'atrule': {
15742
+ pattern: /@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,
14862
15743
  inside: {
14863
- 'attr-name': {
14864
- pattern: /^\s*style/i,
14865
- inside: Prism.languages.markup.tag.inside
15744
+ 'rule': /^@[\w-]+/,
15745
+ 'selector-function-argument': {
15746
+ pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
15747
+ lookbehind: true,
15748
+ alias: 'selector'
14866
15749
  },
14867
- 'punctuation': /^\s*=\s*['"]|['"]\s*$/,
14868
- 'attr-value': {
14869
- pattern: /.+/i,
14870
- inside: Prism.languages.css
15750
+ 'keyword': {
15751
+ pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
15752
+ lookbehind: true
14871
15753
  }
14872
- },
14873
- alias: 'language-css'
14874
- }
14875
- }, Prism.languages.markup.tag);
14876
- }
15754
+ // See rest below
15755
+ }
15756
+ },
15757
+ 'url': {
15758
+ // https://drafts.csswg.org/css-values-3/#urls
15759
+ pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'),
15760
+ greedy: true,
15761
+ inside: {
15762
+ 'function': /^url/i,
15763
+ 'punctuation': /^\(|\)$/,
15764
+ 'string': {
15765
+ pattern: RegExp('^' + string.source + '$'),
15766
+ alias: 'url'
15767
+ }
15768
+ }
15769
+ },
15770
+ 'selector': {
15771
+ pattern: RegExp('(^|[{}\\s])[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'),
15772
+ lookbehind: true
15773
+ },
15774
+ 'string': {
15775
+ pattern: string,
15776
+ greedy: true
15777
+ },
15778
+ 'property': {
15779
+ pattern: /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
15780
+ lookbehind: true
15781
+ },
15782
+ 'important': /!important\b/i,
15783
+ 'function': {
15784
+ pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
15785
+ lookbehind: true
15786
+ },
15787
+ 'punctuation': /[(){};:,]/
15788
+ };
15789
+
15790
+ Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
15791
+
15792
+ var markup = Prism.languages.markup;
15793
+ if (markup) {
15794
+ markup.tag.addInlined('style', 'css');
15795
+ markup.tag.addAttribute('style', 'css');
15796
+ }
15797
+
15798
+ }(Prism));
15799
+
14877
15800
 
14878
15801
  /* **********************************************
14879
15802
  Begin prism-clike.js
@@ -14882,27 +15805,32 @@ if (Prism.languages.markup) {
14882
15805
  Prism.languages.clike = {
14883
15806
  'comment': [
14884
15807
  {
14885
- pattern: /(^|[^\\])\/\*[\w\W]*?\*\//,
14886
- lookbehind: true
15808
+ pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
15809
+ lookbehind: true,
15810
+ greedy: true
14887
15811
  },
14888
15812
  {
14889
15813
  pattern: /(^|[^\\:])\/\/.*/,
14890
- lookbehind: true
15814
+ lookbehind: true,
15815
+ greedy: true
14891
15816
  }
14892
15817
  ],
14893
- 'string': /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
15818
+ 'string': {
15819
+ pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
15820
+ greedy: true
15821
+ },
14894
15822
  'class-name': {
14895
- pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,
15823
+ pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,
14896
15824
  lookbehind: true,
14897
15825
  inside: {
14898
- punctuation: /(\.|\\)/
15826
+ 'punctuation': /[.\\]/
14899
15827
  }
14900
15828
  },
14901
- 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
14902
- 'boolean': /\b(true|false)\b/,
14903
- 'function': /[a-z0-9_]+(?=\()/i,
14904
- 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,
14905
- 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,
15829
+ 'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
15830
+ 'boolean': /\b(?:true|false)\b/,
15831
+ 'function': /\b\w+(?=\()/,
15832
+ 'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
15833
+ 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
14906
15834
  'punctuation': /[{}[\];(),.:]/
14907
15835
  };
14908
15836
 
@@ -14912,25 +15840,95 @@ Prism.languages.clike = {
14912
15840
  ********************************************** */
14913
15841
 
14914
15842
  Prism.languages.javascript = Prism.languages.extend('clike', {
14915
- 'keyword': /\b(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|var|void|while|with|yield)\b/,
14916
- 'number': /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,
15843
+ 'class-name': [
15844
+ Prism.languages.clike['class-name'],
15845
+ {
15846
+ pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/,
15847
+ lookbehind: true
15848
+ }
15849
+ ],
15850
+ 'keyword': [
15851
+ {
15852
+ pattern: /((?:^|\})\s*)catch\b/,
15853
+ lookbehind: true
15854
+ },
15855
+ {
15856
+ 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/,
15857
+ lookbehind: true
15858
+ },
15859
+ ],
14917
15860
  // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
14918
- 'function': /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i
15861
+ 'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
15862
+ 'number': /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,
15863
+ 'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
14919
15864
  });
14920
15865
 
15866
+ Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/;
15867
+
14921
15868
  Prism.languages.insertBefore('javascript', 'keyword', {
14922
15869
  'regex': {
14923
- pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,
14924
- lookbehind: true
14925
- }
15870
+ // eslint-disable-next-line regexp/no-dupe-characters-character-class
15871
+ pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,
15872
+ lookbehind: true,
15873
+ greedy: true,
15874
+ inside: {
15875
+ 'regex-source': {
15876
+ pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
15877
+ lookbehind: true,
15878
+ alias: 'language-regex',
15879
+ inside: Prism.languages.regex
15880
+ },
15881
+ 'regex-delimiter': /^\/|\/$/,
15882
+ 'regex-flags': /^[a-z]+$/,
15883
+ }
15884
+ },
15885
+ // This must be declared before keyword because we use "function" inside the look-forward
15886
+ 'function-variable': {
15887
+ 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*=>))/,
15888
+ alias: 'function'
15889
+ },
15890
+ 'parameter': [
15891
+ {
15892
+ pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
15893
+ lookbehind: true,
15894
+ inside: Prism.languages.javascript
15895
+ },
15896
+ {
15897
+ pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
15898
+ lookbehind: true,
15899
+ inside: Prism.languages.javascript
15900
+ },
15901
+ {
15902
+ pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
15903
+ lookbehind: true,
15904
+ inside: Prism.languages.javascript
15905
+ },
15906
+ {
15907
+ 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*\{)/,
15908
+ lookbehind: true,
15909
+ inside: Prism.languages.javascript
15910
+ }
15911
+ ],
15912
+ 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
14926
15913
  });
14927
15914
 
14928
- Prism.languages.insertBefore('javascript', 'class-name', {
15915
+ Prism.languages.insertBefore('javascript', 'string', {
15916
+ 'hashbang': {
15917
+ pattern: /^#!.*/,
15918
+ greedy: true,
15919
+ alias: 'comment'
15920
+ },
14929
15921
  'template-string': {
14930
- pattern: /`(?:\\`|\\?[^`])*`/,
15922
+ pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
15923
+ greedy: true,
14931
15924
  inside: {
15925
+ 'template-punctuation': {
15926
+ pattern: /^`|`$/,
15927
+ alias: 'string'
15928
+ },
14932
15929
  'interpolation': {
14933
- pattern: /\$\{[^}]+\}/,
15930
+ pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
15931
+ lookbehind: true,
14934
15932
  inside: {
14935
15933
  'interpolation-punctuation': {
14936
15934
  pattern: /^\$\{|\}$/,
@@ -14945,100 +15943,170 @@ Prism.languages.insertBefore('javascript', 'class-name', {
14945
15943
  });
14946
15944
 
14947
15945
  if (Prism.languages.markup) {
14948
- Prism.languages.insertBefore('markup', 'tag', {
14949
- 'script': {
14950
- pattern: /(<script[\w\W]*?>)[\w\W]*?(?=<\/script>)/i,
14951
- lookbehind: true,
14952
- inside: Prism.languages.javascript,
14953
- alias: 'language-javascript'
14954
- }
14955
- });
15946
+ Prism.languages.markup.tag.addInlined('script', 'javascript');
15947
+
15948
+ // add attribute support for all DOM events.
15949
+ // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
15950
+ Prism.languages.markup.tag.addAttribute(
15951
+ /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,
15952
+ 'javascript'
15953
+ );
14956
15954
  }
14957
15955
 
14958
15956
  Prism.languages.js = Prism.languages.javascript;
14959
15957
 
15958
+
14960
15959
  /* **********************************************
14961
15960
  Begin prism-file-highlight.js
14962
15961
  ********************************************** */
14963
15962
 
14964
15963
  (function () {
14965
- if (typeof self === 'undefined' || !self.Prism || !self.document || !document.querySelector) {
15964
+
15965
+ if (typeof Prism === 'undefined' || typeof document === 'undefined') {
14966
15966
  return;
14967
15967
  }
14968
15968
 
14969
- self.Prism.fileHighlight = function() {
15969
+ // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
15970
+ if (!Element.prototype.matches) {
15971
+ Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
15972
+ }
14970
15973
 
14971
- var Extensions = {
14972
- 'js': 'javascript',
14973
- 'html': 'markup',
14974
- 'svg': 'markup',
14975
- 'xml': 'markup',
14976
- 'py': 'python',
14977
- 'rb': 'ruby',
14978
- 'ps1': 'powershell',
14979
- 'psm1': 'powershell'
14980
- };
15974
+ var LOADING_MESSAGE = 'Loading…';
15975
+ var FAILURE_MESSAGE = function (status, message) {
15976
+ return '✖ Error ' + status + ' while fetching file: ' + message;
15977
+ };
15978
+ var FAILURE_EMPTY_MESSAGE = '✖ Error: File does not exist or is empty';
15979
+
15980
+ var EXTENSIONS = {
15981
+ 'js': 'javascript',
15982
+ 'py': 'python',
15983
+ 'rb': 'ruby',
15984
+ 'ps1': 'powershell',
15985
+ 'psm1': 'powershell',
15986
+ 'sh': 'bash',
15987
+ 'bat': 'batch',
15988
+ 'h': 'c',
15989
+ 'tex': 'latex'
15990
+ };
14981
15991
 
14982
- if(Array.prototype.forEach) { // Check to prevent error in IE8
14983
- Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function (pre) {
14984
- var src = pre.getAttribute('data-src');
15992
+ var STATUS_ATTR = 'data-src-status';
15993
+ var STATUS_LOADING = 'loading';
15994
+ var STATUS_LOADED = 'loaded';
15995
+ var STATUS_FAILED = 'failed';
14985
15996
 
14986
- var language, parent = pre;
14987
- var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i;
14988
- while (parent && !lang.test(parent.className)) {
14989
- parent = parent.parentNode;
14990
- }
15997
+ var SELECTOR = 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])'
15998
+ + ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])';
14991
15999
 
14992
- if (parent) {
14993
- language = (pre.className.match(lang) || [, ''])[1];
14994
- }
16000
+ var lang = /\blang(?:uage)?-([\w-]+)\b/i;
14995
16001
 
14996
- if (!language) {
14997
- var extension = (src.match(/\.(\w+)$/) || [, ''])[1];
14998
- language = Extensions[extension] || extension;
14999
- }
16002
+ /**
16003
+ * Sets the Prism `language-xxxx` or `lang-xxxx` class to the given language.
16004
+ *
16005
+ * @param {HTMLElement} element
16006
+ * @param {string} language
16007
+ * @returns {void}
16008
+ */
16009
+ function setLanguageClass(element, language) {
16010
+ var className = element.className;
16011
+ className = className.replace(lang, ' ') + ' language-' + language;
16012
+ element.className = className.replace(/\s+/g, ' ').trim();
16013
+ }
15000
16014
 
15001
- var code = document.createElement('code');
15002
- code.className = 'language-' + language;
15003
16015
 
15004
- pre.textContent = '';
16016
+ Prism.hooks.add('before-highlightall', function (env) {
16017
+ env.selector += ', ' + SELECTOR;
16018
+ });
15005
16019
 
15006
- code.textContent = 'Loading…';
16020
+ Prism.hooks.add('before-sanity-check', function (env) {
16021
+ var pre = /** @type {HTMLPreElement} */ (env.element);
16022
+ if (pre.matches(SELECTOR)) {
16023
+ env.code = ''; // fast-path the whole thing and go to complete
15007
16024
 
15008
- pre.appendChild(code);
16025
+ pre.setAttribute(STATUS_ATTR, STATUS_LOADING); // mark as loading
15009
16026
 
15010
- var xhr = new XMLHttpRequest();
16027
+ // add code element with loading message
16028
+ var code = pre.appendChild(document.createElement('CODE'));
16029
+ code.textContent = LOADING_MESSAGE;
15011
16030
 
15012
- xhr.open('GET', src, true);
16031
+ var src = pre.getAttribute('data-src');
15013
16032
 
15014
- xhr.onreadystatechange = function () {
15015
- if (xhr.readyState == 4) {
16033
+ var language = env.language;
16034
+ if (language === 'none') {
16035
+ // the language might be 'none' because there is no language set;
16036
+ // in this case, we want to use the extension as the language
16037
+ var extension = (/\.(\w+)$/.exec(src) || [, 'none'])[1];
16038
+ language = EXTENSIONS[extension] || extension;
16039
+ }
15016
16040
 
15017
- if (xhr.status < 400 && xhr.responseText) {
15018
- code.textContent = xhr.responseText;
16041
+ // set language classes
16042
+ setLanguageClass(code, language);
16043
+ setLanguageClass(pre, language);
15019
16044
 
15020
- Prism.highlightElement(code);
15021
- }
15022
- else if (xhr.status >= 400) {
15023
- code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText;
15024
- }
15025
- else {
15026
- code.textContent = '✖ Error: File does not exist or is empty';
16045
+ // preload the language
16046
+ var autoloader = Prism.plugins.autoloader;
16047
+ if (autoloader) {
16048
+ autoloader.loadLanguages(language);
16049
+ }
16050
+
16051
+ // load file
16052
+ var xhr = new XMLHttpRequest();
16053
+ xhr.open('GET', src, true);
16054
+ xhr.onreadystatechange = function () {
16055
+ if (xhr.readyState == 4) {
16056
+ if (xhr.status < 400 && xhr.responseText) {
16057
+ // mark as loaded
16058
+ pre.setAttribute(STATUS_ATTR, STATUS_LOADED);
16059
+
16060
+ // highlight code
16061
+ code.textContent = xhr.responseText;
16062
+ Prism.highlightElement(code);
16063
+
16064
+ } else {
16065
+ // mark as failed
16066
+ pre.setAttribute(STATUS_ATTR, STATUS_FAILED);
16067
+
16068
+ if (xhr.status >= 400) {
16069
+ code.textContent = FAILURE_MESSAGE(xhr.status, xhr.statusText);
16070
+ } else {
16071
+ code.textContent = FAILURE_EMPTY_MESSAGE;
15027
16072
  }
15028
16073
  }
15029
- };
15030
-
15031
- xhr.send(null);
15032
- });
16074
+ }
16075
+ };
16076
+ xhr.send(null);
15033
16077
  }
16078
+ });
16079
+
16080
+ Prism.plugins.fileHighlight = {
16081
+ /**
16082
+ * Executes the File Highlight plugin for all matching `pre` elements under the given container.
16083
+ *
16084
+ * Note: Elements which are already loaded or currently loading will not be touched by this method.
16085
+ *
16086
+ * @param {ParentNode} [container=document]
16087
+ */
16088
+ highlight: function highlight(container) {
16089
+ var elements = (container || document).querySelectorAll(SELECTOR);
15034
16090
 
16091
+ for (var i = 0, element; (element = elements[i++]);) {
16092
+ Prism.highlightElement(element);
16093
+ }
16094
+ }
15035
16095
  };
15036
16096
 
15037
- document.addEventListener('DOMContentLoaded', self.Prism.fileHighlight);
16097
+ var logged = false;
16098
+ /** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */
16099
+ Prism.fileHighlight = function () {
16100
+ if (!logged) {
16101
+ console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.');
16102
+ logged = true;
16103
+ }
16104
+ Prism.plugins.fileHighlight.highlight.apply(this, arguments);
16105
+ };
15038
16106
 
15039
- })();
16107
+ }());
15040
16108
 
15041
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
16109
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
15042
16110
  },{}],19:[function(require,module,exports){
15043
16111
  /**
15044
16112
  * selectize.js (v0.12.1)
@@ -18576,7 +19644,7 @@ Prism.languages.js = Prism.languages.javascript;
18576
19644
  * URI.js - Mutating URLs
18577
19645
  * IPv6 Support
18578
19646
  *
18579
- * Version: 1.17.1
19647
+ * Version: 1.19.6
18580
19648
  *
18581
19649
  * Author: Rodney Rehm
18582
19650
  * Web: http://medialize.github.io/URI.js/
@@ -18589,7 +19657,7 @@ Prism.languages.js = Prism.languages.javascript;
18589
19657
  (function (root, factory) {
18590
19658
  'use strict';
18591
19659
  // https://github.com/umdjs/umd/blob/master/returnExports.js
18592
- if (typeof exports === 'object') {
19660
+ if (typeof module === 'object' && module.exports) {
18593
19661
  // Node
18594
19662
  module.exports = factory();
18595
19663
  } else if (typeof define === 'function' && define.amd) {
@@ -18665,8 +19733,6 @@ Prism.languages.js = Prism.languages.javascript;
18665
19733
  while (segments.length < total) {
18666
19734
  segments.splice(pos, 0, '0000');
18667
19735
  }
18668
-
18669
- length = segments.length;
18670
19736
  }
18671
19737
 
18672
19738
  // strip leading zeros
@@ -18750,7 +19816,7 @@ Prism.languages.js = Prism.languages.javascript;
18750
19816
  if (root.IPv6 === this) {
18751
19817
  root.IPv6 = _IPv6;
18752
19818
  }
18753
-
19819
+
18754
19820
  return this;
18755
19821
  }
18756
19822
 
@@ -18765,7 +19831,7 @@ Prism.languages.js = Prism.languages.javascript;
18765
19831
  * URI.js - Mutating URLs
18766
19832
  * Second Level Domain (SLD) Support
18767
19833
  *
18768
- * Version: 1.17.1
19834
+ * Version: 1.19.6
18769
19835
  *
18770
19836
  * Author: Rodney Rehm
18771
19837
  * Web: http://medialize.github.io/URI.js/
@@ -18778,7 +19844,7 @@ Prism.languages.js = Prism.languages.javascript;
18778
19844
  (function (root, factory) {
18779
19845
  'use strict';
18780
19846
  // https://github.com/umdjs/umd/blob/master/returnExports.js
18781
- if (typeof exports === 'object') {
19847
+ if (typeof module === 'object' && module.exports) {
18782
19848
  // Node
18783
19849
  module.exports = factory();
18784
19850
  } else if (typeof define === 'function' && define.amd) {
@@ -18936,7 +20002,12 @@ Prism.languages.js = Prism.languages.javascript;
18936
20002
  'ye':' co com gov ltd me net org plc ',
18937
20003
  'yu':' ac co edu gov org ',
18938
20004
  'za':' ac agric alt bourse city co cybernet db edu gov grondar iaccess imt inca landesign law mil net ngo nis nom olivetti org pix school tm web ',
18939
- 'zm':' ac co com edu gov net org sch '
20005
+ 'zm':' ac co com edu gov net org sch ',
20006
+ // https://en.wikipedia.org/wiki/CentralNic#Second-level_domains
20007
+ 'com': 'ar br cn de eu gb gr hu jpn kr no qc ru sa se uk us uy za ',
20008
+ 'net': 'gb jp se uk ',
20009
+ 'org': 'ae',
20010
+ 'de': 'com '
18940
20011
  },
18941
20012
  // gorhill 2013-10-25: Using indexOf() instead Regexp(). Significant boost
18942
20013
  // in both performance and memory footprint. No initialization required.
@@ -19006,7 +20077,7 @@ Prism.languages.js = Prism.languages.javascript;
19006
20077
  /*!
19007
20078
  * URI.js - Mutating URLs
19008
20079
  *
19009
- * Version: 1.17.1
20080
+ * Version: 1.19.6
19010
20081
  *
19011
20082
  * Author: Rodney Rehm
19012
20083
  * Web: http://medialize.github.io/URI.js/
@@ -19018,7 +20089,7 @@ Prism.languages.js = Prism.languages.javascript;
19018
20089
  (function (root, factory) {
19019
20090
  'use strict';
19020
20091
  // https://github.com/umdjs/umd/blob/master/returnExports.js
19021
- if (typeof exports === 'object') {
20092
+ if (typeof module === 'object' && module.exports) {
19022
20093
  // Node
19023
20094
  module.exports = factory(require('./punycode'), require('./IPv6'), require('./SecondLevelDomains'));
19024
20095
  } else if (typeof define === 'function' && define.amd) {
@@ -19066,6 +20137,12 @@ Prism.languages.js = Prism.languages.javascript;
19066
20137
  }
19067
20138
  }
19068
20139
 
20140
+ if (url === null) {
20141
+ if (_urlSupplied) {
20142
+ throw new TypeError('null is not a valid argument for URI');
20143
+ }
20144
+ }
20145
+
19069
20146
  this.href(url);
19070
20147
 
19071
20148
  // resolve to base according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#constructor
@@ -19076,7 +20153,11 @@ Prism.languages.js = Prism.languages.javascript;
19076
20153
  return this;
19077
20154
  }
19078
20155
 
19079
- URI.version = '1.17.1';
20156
+ function isInteger(value) {
20157
+ return /^[0-9]+$/.test(value);
20158
+ }
20159
+
20160
+ URI.version = '1.19.6';
19080
20161
 
19081
20162
  var p = URI.prototype;
19082
20163
  var hasOwn = Object.prototype.hasOwnProperty;
@@ -19196,17 +20277,22 @@ Prism.languages.js = Prism.languages.javascript;
19196
20277
  query: null,
19197
20278
  fragment: null,
19198
20279
  // state
20280
+ preventInvalidHostname: URI.preventInvalidHostname,
19199
20281
  duplicateQueryParameters: URI.duplicateQueryParameters,
19200
20282
  escapeQuerySpace: URI.escapeQuerySpace
19201
20283
  };
19202
20284
  };
20285
+ // state: throw on invalid hostname
20286
+ // see https://github.com/medialize/URI.js/pull/345
20287
+ // and https://github.com/medialize/URI.js/issues/354
20288
+ URI.preventInvalidHostname = false;
19203
20289
  // state: allow duplicate query parameters (a=1&a=1)
19204
20290
  URI.duplicateQueryParameters = false;
19205
20291
  // state: replaces + with %20 (space in query strings)
19206
20292
  URI.escapeQuerySpace = true;
19207
20293
  // static properties
19208
20294
  URI.protocol_expression = /^[a-z][a-z0-9.+-]*$/i;
19209
- URI.idn_expression = /[^a-z0-9\.-]/i;
20295
+ URI.idn_expression = /[^a-z0-9\._-]/i;
19210
20296
  URI.punycode_expression = /(xn--)/i;
19211
20297
  // well, 333.444.555.666 matches, but it sure ain't no IPv4 - do we care?
19212
20298
  URI.ip4_expression = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
@@ -19225,7 +20311,9 @@ Prism.languages.js = Prism.languages.javascript;
19225
20311
  // everything up to the next whitespace
19226
20312
  end: /[\s\r\n]|$/,
19227
20313
  // trim trailing punctuation captured by end RegExp
19228
- trim: /[`!()\[\]{};:'".,<>?«»“”„‘’]+$/
20314
+ trim: /[`!()\[\]{};:'".,<>?«»“”„‘’]+$/,
20315
+ // balanced parens inclusion (), [], {}, <>
20316
+ parens: /(\([^\)]*\)|\[[^\]]*\]|\{[^}]*\}|<[^>]*>)/g,
19229
20317
  };
19230
20318
  // http://www.iana.org/assignments/uri-schemes.html
19231
20319
  // http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Well-known_ports
@@ -19237,10 +20325,16 @@ Prism.languages.js = Prism.languages.javascript;
19237
20325
  ws: '80',
19238
20326
  wss: '443'
19239
20327
  };
20328
+ // list of protocols which always require a hostname
20329
+ URI.hostProtocols = [
20330
+ 'http',
20331
+ 'https'
20332
+ ];
20333
+
19240
20334
  // allowed hostname characters according to RFC 3986
19241
20335
  // ALPHA DIGIT "-" "." "_" "~" "!" "$" "&" "'" "(" ")" "*" "+" "," ";" "=" %encoded
19242
- // I've never seen a (non-IDN) hostname other than: ALPHA DIGIT . -
19243
- URI.invalid_hostname_characters = /[^a-zA-Z0-9\.-]/;
20336
+ // I've never seen a (non-IDN) hostname other than: ALPHA DIGIT . - _
20337
+ URI.invalid_hostname_characters = /[^a-zA-Z0-9\.\-:_]/;
19244
20338
  // map DOM Elements to their URI attribute
19245
20339
  URI.domAttributes = {
19246
20340
  'a': 'href',
@@ -19472,7 +20566,9 @@ Prism.languages.js = Prism.languages.javascript;
19472
20566
  URI.parse = function(string, parts) {
19473
20567
  var pos;
19474
20568
  if (!parts) {
19475
- parts = {};
20569
+ parts = {
20570
+ preventInvalidHostname: URI.preventInvalidHostname
20571
+ };
19476
20572
  }
19477
20573
  // [protocol"://"[username[":"password]"@"]hostname[":"port]"/"?][path]["?"querystring]["#"fragment]
19478
20574
 
@@ -19506,7 +20602,7 @@ Prism.languages.js = Prism.languages.javascript;
19506
20602
  if (parts.protocol && !parts.protocol.match(URI.protocol_expression)) {
19507
20603
  // : may be within the path
19508
20604
  parts.protocol = undefined;
19509
- } else if (string.substring(pos + 1, pos + 3) === '//') {
20605
+ } else if (string.substring(pos + 1, pos + 3).replace(/\\/g, '/') === '//') {
19510
20606
  string = string.substring(pos + 3);
19511
20607
 
19512
20608
  // extract "user:pass@host:port"
@@ -19525,6 +20621,10 @@ Prism.languages.js = Prism.languages.javascript;
19525
20621
  return parts;
19526
20622
  };
19527
20623
  URI.parseHost = function(string, parts) {
20624
+ if (!string) {
20625
+ string = '';
20626
+ }
20627
+
19528
20628
  // Copy chrome, IE, opera backslash-handling behavior.
19529
20629
  // Back slashes before the query string get converted to forward slashes
19530
20630
  // See: https://github.com/joyent/node/blob/386fd24f49b0e9d1a8a076592a404168faeecc34/lib/url.js#L115-L124
@@ -19572,6 +20672,14 @@ Prism.languages.js = Prism.languages.javascript;
19572
20672
  string = '/' + string;
19573
20673
  }
19574
20674
 
20675
+ if (parts.preventInvalidHostname) {
20676
+ URI.ensureValidHostname(parts.hostname, parts.protocol);
20677
+ }
20678
+
20679
+ if (parts.port) {
20680
+ URI.ensureValidPort(parts.port);
20681
+ }
20682
+
19575
20683
  return string.substring(pos) || '/';
19576
20684
  };
19577
20685
  URI.parseAuthority = function(string, parts) {
@@ -19580,17 +20688,22 @@ Prism.languages.js = Prism.languages.javascript;
19580
20688
  };
19581
20689
  URI.parseUserinfo = function(string, parts) {
19582
20690
  // extract username:password
20691
+ var _string = string
20692
+ var firstBackSlash = string.indexOf('\\');
20693
+ if (firstBackSlash !== -1) {
20694
+ string = string.replace(/\\/g, '/')
20695
+ }
19583
20696
  var firstSlash = string.indexOf('/');
19584
20697
  var pos = string.lastIndexOf('@', firstSlash > -1 ? firstSlash : string.length - 1);
19585
20698
  var t;
19586
20699
 
19587
- // authority@ must come before /path
20700
+ // authority@ must come before /path or \path
19588
20701
  if (pos > -1 && (firstSlash === -1 || pos < firstSlash)) {
19589
20702
  t = string.substring(0, pos).split(':');
19590
20703
  parts.username = t[0] ? URI.decode(t[0]) : null;
19591
20704
  t.shift();
19592
20705
  parts.password = t[0] ? URI.decode(t.join(':')) : null;
19593
- string = string.substring(pos + 1);
20706
+ string = _string.substring(pos + 1);
19594
20707
  } else {
19595
20708
  parts.username = null;
19596
20709
  parts.password = null;
@@ -19637,6 +20750,7 @@ Prism.languages.js = Prism.languages.javascript;
19637
20750
 
19638
20751
  URI.build = function(parts) {
19639
20752
  var t = '';
20753
+ var requireAbsolutePath = false
19640
20754
 
19641
20755
  if (parts.protocol) {
19642
20756
  t += parts.protocol + ':';
@@ -19644,12 +20758,13 @@ Prism.languages.js = Prism.languages.javascript;
19644
20758
 
19645
20759
  if (!parts.urn && (t || parts.hostname)) {
19646
20760
  t += '//';
20761
+ requireAbsolutePath = true
19647
20762
  }
19648
20763
 
19649
20764
  t += (URI.buildAuthority(parts) || '');
19650
20765
 
19651
20766
  if (typeof parts.path === 'string') {
19652
- if (parts.path.charAt(0) !== '/' && typeof parts.hostname === 'string') {
20767
+ if (parts.path.charAt(0) !== '/' && requireAbsolutePath) {
19653
20768
  t += '/';
19654
20769
  }
19655
20770
 
@@ -19690,11 +20805,13 @@ Prism.languages.js = Prism.languages.javascript;
19690
20805
 
19691
20806
  if (parts.username) {
19692
20807
  t += URI.encode(parts.username);
20808
+ }
19693
20809
 
19694
- if (parts.password) {
19695
- t += ':' + URI.encode(parts.password);
19696
- }
20810
+ if (parts.password) {
20811
+ t += ':' + URI.encode(parts.password);
20812
+ }
19697
20813
 
20814
+ if (t) {
19698
20815
  t += '@';
19699
20816
  }
19700
20817
 
@@ -19710,7 +20827,7 @@ Prism.languages.js = Prism.languages.javascript;
19710
20827
  var t = '';
19711
20828
  var unique, key, i, length;
19712
20829
  for (key in data) {
19713
- if (hasOwn.call(data, key) && key) {
20830
+ if (hasOwn.call(data, key)) {
19714
20831
  if (isArray(data[key])) {
19715
20832
  unique = {};
19716
20833
  for (i = 0, length = data[key].length; i < length; i++) {
@@ -19759,6 +20876,21 @@ Prism.languages.js = Prism.languages.javascript;
19759
20876
  throw new TypeError('URI.addQuery() accepts an object, string as the name parameter');
19760
20877
  }
19761
20878
  };
20879
+
20880
+ URI.setQuery = function(data, name, value) {
20881
+ if (typeof name === 'object') {
20882
+ for (var key in name) {
20883
+ if (hasOwn.call(name, key)) {
20884
+ URI.setQuery(data, key, name[key]);
20885
+ }
20886
+ }
20887
+ } else if (typeof name === 'string') {
20888
+ data[name] = value === undefined ? null : value;
20889
+ } else {
20890
+ throw new TypeError('URI.setQuery() accepts an object, string as the name parameter');
20891
+ }
20892
+ };
20893
+
19762
20894
  URI.removeQuery = function(data, name, value) {
19763
20895
  var i, length, key;
19764
20896
 
@@ -19883,6 +21015,39 @@ Prism.languages.js = Prism.languages.javascript;
19883
21015
  };
19884
21016
 
19885
21017
 
21018
+ URI.joinPaths = function() {
21019
+ var input = [];
21020
+ var segments = [];
21021
+ var nonEmptySegments = 0;
21022
+
21023
+ for (var i = 0; i < arguments.length; i++) {
21024
+ var url = new URI(arguments[i]);
21025
+ input.push(url);
21026
+ var _segments = url.segment();
21027
+ for (var s = 0; s < _segments.length; s++) {
21028
+ if (typeof _segments[s] === 'string') {
21029
+ segments.push(_segments[s]);
21030
+ }
21031
+
21032
+ if (_segments[s]) {
21033
+ nonEmptySegments++;
21034
+ }
21035
+ }
21036
+ }
21037
+
21038
+ if (!segments.length || !nonEmptySegments) {
21039
+ return new URI('');
21040
+ }
21041
+
21042
+ var uri = new URI('').segment(segments);
21043
+
21044
+ if (input[0].path() === '' || input[0].path().slice(0, 1) === '/') {
21045
+ uri.path('/' + uri.path());
21046
+ }
21047
+
21048
+ return uri.normalize();
21049
+ };
21050
+
19886
21051
  URI.commonPath = function(one, two) {
19887
21052
  var length = Math.min(one.length, two.length);
19888
21053
  var pos;
@@ -19912,6 +21077,7 @@ Prism.languages.js = Prism.languages.javascript;
19912
21077
  var _start = options.start || URI.findUri.start;
19913
21078
  var _end = options.end || URI.findUri.end;
19914
21079
  var _trim = options.trim || URI.findUri.trim;
21080
+ var _parens = options.parens || URI.findUri.parens;
19915
21081
  var _attributeOpen = /[a-z0-9-]=["']?$/i;
19916
21082
 
19917
21083
  _start.lastIndex = 0;
@@ -19931,13 +21097,43 @@ Prism.languages.js = Prism.languages.javascript;
19931
21097
  }
19932
21098
 
19933
21099
  var end = start + string.slice(start).search(_end);
19934
- var slice = string.slice(start, end).replace(_trim, '');
21100
+ var slice = string.slice(start, end);
21101
+ // make sure we include well balanced parens
21102
+ var parensEnd = -1;
21103
+ while (true) {
21104
+ var parensMatch = _parens.exec(slice);
21105
+ if (!parensMatch) {
21106
+ break;
21107
+ }
21108
+
21109
+ var parensMatchEnd = parensMatch.index + parensMatch[0].length;
21110
+ parensEnd = Math.max(parensEnd, parensMatchEnd);
21111
+ }
21112
+
21113
+ if (parensEnd > -1) {
21114
+ slice = slice.slice(0, parensEnd) + slice.slice(parensEnd).replace(_trim, '');
21115
+ } else {
21116
+ slice = slice.replace(_trim, '');
21117
+ }
21118
+
21119
+ if (slice.length <= match[0].length) {
21120
+ // the extract only contains the starting marker of a URI,
21121
+ // e.g. "www" or "http://"
21122
+ continue;
21123
+ }
21124
+
19935
21125
  if (options.ignore && options.ignore.test(slice)) {
19936
21126
  continue;
19937
21127
  }
19938
21128
 
19939
21129
  end = start + slice.length;
19940
21130
  var result = callback(slice, start, end, string);
21131
+ if (result === undefined) {
21132
+ _start.lastIndex = end;
21133
+ continue;
21134
+ }
21135
+
21136
+ result = String(result);
19941
21137
  string = string.slice(0, start) + result + string.slice(end);
19942
21138
  _start.lastIndex = start + result.length;
19943
21139
  }
@@ -19946,22 +21142,44 @@ Prism.languages.js = Prism.languages.javascript;
19946
21142
  return string;
19947
21143
  };
19948
21144
 
19949
- URI.ensureValidHostname = function(v) {
21145
+ URI.ensureValidHostname = function(v, protocol) {
19950
21146
  // Theoretically URIs allow percent-encoding in Hostnames (according to RFC 3986)
19951
21147
  // they are not part of DNS and therefore ignored by URI.js
19952
21148
 
19953
- if (v.match(URI.invalid_hostname_characters)) {
21149
+ var hasHostname = !!v; // not null and not an empty string
21150
+ var hasProtocol = !!protocol;
21151
+ var rejectEmptyHostname = false;
21152
+
21153
+ if (hasProtocol) {
21154
+ rejectEmptyHostname = arrayContains(URI.hostProtocols, protocol);
21155
+ }
21156
+
21157
+ if (rejectEmptyHostname && !hasHostname) {
21158
+ throw new TypeError('Hostname cannot be empty, if protocol is ' + protocol);
21159
+ } else if (v && v.match(URI.invalid_hostname_characters)) {
19954
21160
  // test punycode
19955
21161
  if (!punycode) {
19956
- throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-] and Punycode.js is not available');
21162
+ throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-:_] and Punycode.js is not available');
19957
21163
  }
19958
-
19959
21164
  if (punycode.toASCII(v).match(URI.invalid_hostname_characters)) {
19960
- throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
21165
+ throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-:_]');
19961
21166
  }
19962
21167
  }
19963
21168
  };
19964
21169
 
21170
+ URI.ensureValidPort = function (v) {
21171
+ if (!v) {
21172
+ return;
21173
+ }
21174
+
21175
+ var port = Number(v);
21176
+ if (isInteger(port) && (port > 0) && (port < 65536)) {
21177
+ return;
21178
+ }
21179
+
21180
+ throw new TypeError('Port "' + v + '" is not a valid port');
21181
+ };
21182
+
19965
21183
  // noConflict
19966
21184
  URI.noConflict = function(removeAll) {
19967
21185
  if (removeAll) {
@@ -20106,10 +21324,14 @@ Prism.languages.js = Prism.languages.javascript;
20106
21324
  } else if (_URI || _object) {
20107
21325
  var src = _URI ? href._parts : href;
20108
21326
  for (key in src) {
21327
+ if (key === 'query') { continue; }
20109
21328
  if (hasOwn.call(this._parts, key)) {
20110
21329
  this._parts[key] = src[key];
20111
21330
  }
20112
21331
  }
21332
+ if (src.query) {
21333
+ this.query(src.query, false);
21334
+ }
20113
21335
  } else {
20114
21336
  throw new TypeError('invalid input');
20115
21337
  }
@@ -20190,16 +21412,15 @@ Prism.languages.js = Prism.languages.javascript;
20190
21412
  var _hostname = p.hostname;
20191
21413
 
20192
21414
  p.protocol = function(v, build) {
20193
- if (v !== undefined) {
20194
- if (v) {
20195
- // accept trailing ://
20196
- v = v.replace(/:(\/\/)?$/, '');
21415
+ if (v) {
21416
+ // accept trailing ://
21417
+ v = v.replace(/:(\/\/)?$/, '');
20197
21418
 
20198
- if (!v.match(URI.protocol_expression)) {
20199
- throw new TypeError('Protocol "' + v + '" contains characters other than [A-Z0-9.+-] or doesn\'t start with [A-Z]');
20200
- }
21419
+ if (!v.match(URI.protocol_expression)) {
21420
+ throw new TypeError('Protocol "' + v + '" contains characters other than [A-Z0-9.+-] or doesn\'t start with [A-Z]');
20201
21421
  }
20202
21422
  }
21423
+
20203
21424
  return _protocol.call(this, v, build);
20204
21425
  };
20205
21426
  p.scheme = p.protocol;
@@ -20219,9 +21440,7 @@ Prism.languages.js = Prism.languages.javascript;
20219
21440
  v = v.substring(1);
20220
21441
  }
20221
21442
 
20222
- if (v.match(/[^0-9]/)) {
20223
- throw new TypeError('Port "' + v + '" contains characters other than [0-9]');
20224
- }
21443
+ URI.ensureValidPort(v);
20225
21444
  }
20226
21445
  }
20227
21446
  return _port.call(this, v, build);
@@ -20232,14 +21451,18 @@ Prism.languages.js = Prism.languages.javascript;
20232
21451
  }
20233
21452
 
20234
21453
  if (v !== undefined) {
20235
- var x = {};
21454
+ var x = { preventInvalidHostname: this._parts.preventInvalidHostname };
20236
21455
  var res = URI.parseHost(v, x);
20237
21456
  if (res !== '/') {
20238
21457
  throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
20239
21458
  }
20240
21459
 
20241
21460
  v = x.hostname;
21461
+ if (this._parts.preventInvalidHostname) {
21462
+ URI.ensureValidHostname(v, this._parts.protocol);
21463
+ }
20242
21464
  }
21465
+
20243
21466
  return _hostname.call(this, v, build);
20244
21467
  };
20245
21468
 
@@ -20306,12 +21529,8 @@ Prism.languages.js = Prism.languages.javascript;
20306
21529
  }
20307
21530
 
20308
21531
  if (v === undefined) {
20309
- if (!this._parts.username) {
20310
- return '';
20311
- }
20312
-
20313
21532
  var t = URI.buildUserinfo(this._parts);
20314
- return t.substring(0, t.length -1);
21533
+ return t ? t.substring(0, t.length -1) : t;
20315
21534
  } else {
20316
21535
  if (v[v.length-1] !== '@') {
20317
21536
  v += '@';
@@ -20361,8 +21580,12 @@ Prism.languages.js = Prism.languages.javascript;
20361
21580
  v += '.';
20362
21581
  }
20363
21582
 
21583
+ if (v.indexOf(':') !== -1) {
21584
+ throw new TypeError('Domains cannot contain colons');
21585
+ }
21586
+
20364
21587
  if (v) {
20365
- URI.ensureValidHostname(v);
21588
+ URI.ensureValidHostname(v, this._parts.protocol);
20366
21589
  }
20367
21590
 
20368
21591
  this._parts.hostname = this._parts.hostname.replace(replace, v);
@@ -20401,7 +21624,11 @@ Prism.languages.js = Prism.languages.javascript;
20401
21624
  throw new TypeError('cannot set domain empty');
20402
21625
  }
20403
21626
 
20404
- URI.ensureValidHostname(v);
21627
+ if (v.indexOf(':') !== -1) {
21628
+ throw new TypeError('Domains cannot contain colons');
21629
+ }
21630
+
21631
+ URI.ensureValidHostname(v, this._parts.protocol);
20405
21632
 
20406
21633
  if (!this._parts.hostname || this.is('IP')) {
20407
21634
  this._parts.hostname = v;
@@ -20512,7 +21739,7 @@ Prism.languages.js = Prism.languages.javascript;
20512
21739
  return v === undefined ? '' : this;
20513
21740
  }
20514
21741
 
20515
- if (v === undefined || v === true) {
21742
+ if (typeof v !== 'string') {
20516
21743
  if (!this._parts.path || this._parts.path === '/') {
20517
21744
  return '';
20518
21745
  }
@@ -21012,7 +22239,10 @@ Prism.languages.js = Prism.languages.javascript;
21012
22239
  base = new URI(base);
21013
22240
  }
21014
22241
 
21015
- if (!resolved._parts.protocol) {
22242
+ if (resolved._parts.protocol) {
22243
+ // Directly returns even if this._parts.hostname is empty.
22244
+ return resolved;
22245
+ } else {
21016
22246
  resolved._parts.protocol = base._parts.protocol;
21017
22247
  }
21018
22248
 
@@ -21029,15 +22259,17 @@ Prism.languages.js = Prism.languages.javascript;
21029
22259
  if (!resolved._parts.query) {
21030
22260
  resolved._parts.query = base._parts.query;
21031
22261
  }
21032
- } else if (resolved._parts.path.substring(-2) === '..') {
21033
- resolved._parts.path += '/';
21034
- }
22262
+ } else {
22263
+ if (resolved._parts.path.substring(-2) === '..') {
22264
+ resolved._parts.path += '/';
22265
+ }
21035
22266
 
21036
- if (resolved.path().charAt(0) !== '/') {
21037
- basedir = base.directory();
21038
- basedir = basedir ? basedir : base.path().indexOf('/') === 0 ? '/' : '';
21039
- resolved._parts.path = (basedir ? (basedir + '/') : '') + resolved._parts.path;
21040
- resolved.normalizePath();
22267
+ if (resolved.path().charAt(0) !== '/') {
22268
+ basedir = base.directory();
22269
+ basedir = basedir ? basedir : base.path().indexOf('/') === 0 ? '/' : '';
22270
+ resolved._parts.path = (basedir ? (basedir + '/') : '') + resolved._parts.path;
22271
+ resolved.normalizePath();
22272
+ }
21041
22273
  }
21042
22274
 
21043
22275
  resolved.build();
@@ -21170,6 +22402,11 @@ Prism.languages.js = Prism.languages.javascript;
21170
22402
  };
21171
22403
 
21172
22404
  // state
22405
+ p.preventInvalidHostname = function(v) {
22406
+ this._parts.preventInvalidHostname = !!v;
22407
+ return this;
22408
+ };
22409
+
21173
22410
  p.duplicateQueryParameters = function(v) {
21174
22411
  this._parts.duplicateQueryParameters = !!v;
21175
22412
  return this;
@@ -21184,7 +22421,7 @@ Prism.languages.js = Prism.languages.javascript;
21184
22421
  }));
21185
22422
 
21186
22423
  },{"./IPv6":21,"./SecondLevelDomains":22,"./punycode":24}],24:[function(require,module,exports){
21187
- (function (global){
22424
+ (function (global){(function (){
21188
22425
  /*! https://mths.be/punycode v1.4.0 by @mathias */
21189
22426
  ;(function(root) {
21190
22427
 
@@ -21719,5 +22956,5 @@ Prism.languages.js = Prism.languages.javascript;
21719
22956
 
21720
22957
  }(this));
21721
22958
 
21722
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
22959
+ }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
21723
22960
  },{}]},{},[1]);