@@ -24,7 +24,7 @@ var _self = (typeof window !== 'undefined')
24
24
var Prism = ( function ( _self ) {
25
25
26
26
// Private helper vars
27
- var lang = / \b l a n g (?: u a g e ) ? - ( [ \w - ] + ) \b / i;
27
+ var lang = / (?: ^ | \s ) l a n g (?: u a g e ) ? - ( [ \w - ] + ) (? = \s | $ ) / i;
28
28
var uniqueId = 0 ;
29
29
30
30
// The grammar object for plaintext
@@ -54,6 +54,27 @@ var Prism = (function (_self) {
54
54
* @public
55
55
*/
56
56
manual : _self . Prism && _self . Prism . manual ,
57
+ /**
58
+ * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses
59
+ * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your
60
+ * own worker, you don't want it to do this.
61
+ *
62
+ * By setting this value to `true`, Prism will not add its own listeners to the worker.
63
+ *
64
+ * You obviously have to change this value before Prism executes. To do this, you can add an
65
+ * empty Prism object into the global scope before loading the Prism script like this:
66
+ *
67
+ * ```js
68
+ * window.Prism = window.Prism || {};
69
+ * Prism.disableWorkerMessageHandler = true;
70
+ * // Load Prism's script
71
+ * ```
72
+ *
73
+ * @default false
74
+ * @type {boolean }
75
+ * @memberof Prism
76
+ * @public
77
+ */
57
78
disableWorkerMessageHandler : _self . Prism && _self . Prism . disableWorkerMessageHandler ,
58
79
59
80
/**
@@ -168,15 +189,33 @@ var Prism = (function (_self) {
168
189
* @returns {string }
169
190
*/
170
191
getLanguage : function ( element ) {
171
- while ( element && ! lang . test ( element . className ) ) {
192
+ while ( element ) {
193
+ var m = lang . exec ( element . className ) ;
194
+ if ( m ) {
195
+ return m [ 1 ] . toLowerCase ( ) ;
196
+ }
172
197
element = element . parentElement ;
173
198
}
174
- if ( element ) {
175
- return ( element . className . match ( lang ) || [ , 'none' ] ) [ 1 ] . toLowerCase ( ) ;
176
- }
177
199
return 'none' ;
178
200
} ,
179
201
202
+ /**
203
+ * Sets the Prism `language-xxxx` class of the given element.
204
+ *
205
+ * @param {Element } element
206
+ * @param {string } language
207
+ * @returns {void }
208
+ */
209
+ setLanguage : function ( element , language ) {
210
+ // remove all `language-xxxx` classes
211
+ // (this might leave behind a leading space)
212
+ element . className = element . className . replace ( RegExp ( lang , 'gi' ) , '' ) ;
213
+
214
+ // add the new `language-xxxx` class
215
+ // (using `classList` will automatically clean up spaces for us)
216
+ element . classList . add ( 'language-' + language ) ;
217
+ } ,
218
+
180
219
/**
181
220
* Returns the script element that is currently executing.
182
221
*
@@ -531,12 +570,12 @@ var Prism = (function (_self) {
531
570
var grammar = _ . languages [ language ] ;
532
571
533
572
// Set language on the element, if not present
534
- element . className = element . className . replace ( lang , '' ) . replace ( / \s + / g , ' ' ) + ' language-' + language ;
573
+ _ . util . setLanguage ( element , language ) ;
535
574
536
575
// Set language on the parent, for styling
537
576
var parent = element . parentElement ;
538
577
if ( parent && parent . nodeName . toLowerCase ( ) === 'pre' ) {
539
- parent . className = parent . className . replace ( lang , '' ) . replace ( / \s + / g , ' ' ) + ' language-' + language ;
578
+ _ . util . setLanguage ( parent , language ) ;
540
579
}
541
580
542
581
var code = element . textContent ;
@@ -931,7 +970,7 @@ var Prism = (function (_self) {
931
970
932
971
if ( greedy ) {
933
972
match = matchPattern ( pattern , pos , text , lookbehind ) ;
934
- if ( ! match ) {
973
+ if ( ! match || match . index >= text . length ) {
935
974
break ;
936
975
}
937
976
@@ -1507,14 +1546,14 @@ Prism.languages.clike = {
1507
1546
greedy : true
1508
1547
} ,
1509
1548
'class-name' : {
1510
- pattern : / ( \b (?: c l a s s | i n t e r f a c e | e x t e n d s | i m p l e m e n t s | t r a i t | i n s t a n c e o f | n e w ) \s + | \b c a t c h \s + \( ) [ \w . \\ ] + / i,
1549
+ pattern : / ( \b (?: c l a s s | e x t e n d s | i m p l e m e n t s | i n s t a n c e o f | i n t e r f a c e | n e w | t r a i t ) \s + | \b c a t c h \s + \( ) [ \w . \\ ] + / i,
1511
1550
lookbehind : true ,
1512
1551
inside : {
1513
1552
'punctuation' : / [ . \\ ] /
1514
1553
}
1515
1554
} ,
1516
- 'keyword' : / \b (?: i f | e l s e | w h i l e | d o | f o r | r e t u r n | i n | i n s t a n c e o f | f u n c t i o n | n e w | t r y | t h r o w | c a t c h | f i n a l l y | n u l l | b r e a k | c o n t i n u e ) \b / ,
1517
- 'boolean' : / \b (?: t r u e | f a l s e ) \b / ,
1555
+ 'keyword' : / \b (?: b r e a k | c a t c h | c o n t i n u e | d o | e l s e | f i n a l l y | f o r | f u n c t i o n | i f | i n | i n s t a n c e o f | n e w | n u l l | r e t u r n | t h r o w | t r y | w h i l e ) \b / ,
1556
+ 'boolean' : / \b (?: f a l s e | t r u e ) \b / ,
1518
1557
'function' : / \b \w + (? = \( ) / ,
1519
1558
'number' : / \b 0 x [ \d a - f ] + \b | (?: \b \d + (?: \. \d * ) ? | \B \. \d + ) (?: e [ + - ] ? \d + ) ? / i,
1520
1559
'operator' : / [ < > ] = ? | [ ! = ] = ? = ? | - - ? | \+ \+ ? | & & ? | \| \| ? | [ ? * / ~ ^ % ] / ,
@@ -1530,7 +1569,7 @@ Prism.languages.javascript = Prism.languages.extend('clike', {
1530
1569
'class-name' : [
1531
1570
Prism . languages . clike [ 'class-name' ] ,
1532
1571
{
1533
- pattern : / ( ^ | [ ^ $ \w \xA0 - \uFFFF ] ) (? ! \s ) [ _ $ A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * (? = \. (?: p r o t o t y p e | c o n s t r u c t o r ) ) / ,
1572
+ pattern : / ( ^ | [ ^ $ \w \xA0 - \uFFFF ] ) (? ! \s ) [ _ $ A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * (? = \. (?: c o n s t r u c t o r | p r o t o t y p e ) ) / ,
1534
1573
lookbehind : true
1535
1574
}
1536
1575
] ,
@@ -1546,11 +1585,38 @@ Prism.languages.javascript = Prism.languages.extend('clike', {
1546
1585
] ,
1547
1586
// Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
1548
1587
'function' : / # ? (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * (? = \s * (?: \. \s * (?: a p p l y | b i n d | c a l l ) \s * ) ? \( ) / ,
1549
- 'number' : / \b (?: (?: 0 [ x X ] (?: [ \d A - F a - f ] (?: _ [ \d A - F a - f ] ) ? ) + | 0 [ b B ] (?: [ 0 1 ] (?: _ [ 0 1 ] ) ? ) + | 0 [ o O ] (?: [ 0 - 7 ] (?: _ [ 0 - 7 ] ) ? ) + ) n ? | (?: \d (?: _ \d ) ? ) + n | N a N | I n f i n i t y ) \b | (?: \b (?: \d (?: _ \d ) ? ) + \. ? (?: \d (?: _ \d ) ? ) * | \B \. (?: \d (?: _ \d ) ? ) + ) (?: [ E e ] [ + - ] ? (?: \d (?: _ \d ) ? ) + ) ? / ,
1588
+ 'number' : {
1589
+ pattern : RegExp (
1590
+ / ( ^ | [ ^ \w $ ] ) / . source +
1591
+ '(?:' +
1592
+ (
1593
+ // constant
1594
+ / N a N | I n f i n i t y / . source +
1595
+ '|' +
1596
+ // binary integer
1597
+ / 0 [ b B ] [ 0 1 ] + (?: _ [ 0 1 ] + ) * n ? / . source +
1598
+ '|' +
1599
+ // octal integer
1600
+ / 0 [ o O ] [ 0 - 7 ] + (?: _ [ 0 - 7 ] + ) * n ? / . source +
1601
+ '|' +
1602
+ // hexadecimal integer
1603
+ / 0 [ x X ] [ \d A - F a - f ] + (?: _ [ \d A - F a - f ] + ) * n ? / . source +
1604
+ '|' +
1605
+ // decimal bigint
1606
+ / \d + (?: _ \d + ) * n / . source +
1607
+ '|' +
1608
+ // decimal number (integer or float) but no bigint
1609
+ / (?: \d + (?: _ \d + ) * (?: \. (?: \d + (?: _ \d + ) * ) ? ) ? | \. \d + (?: _ \d + ) * ) (?: [ E e ] [ + - ] ? \d + (?: _ \d + ) * ) ? / . source
1610
+ ) +
1611
+ ')' +
1612
+ / (? ! [ \w $ ] ) / . source
1613
+ ) ,
1614
+ lookbehind : true
1615
+ } ,
1550
1616
'operator' : / - - | \+ \+ | \* \* = ? | = > | & & = ? | \| \| = ? | [ ! = ] = = | < < = ? | > > > ? = ? | [ - + * / % & | ^ ! = < > ] = ? | \. { 3 } | \? \? = ? | \? \. ? | [ ~ : ] /
1551
1617
} ) ;
1552
1618
1553
- Prism . languages . javascript [ 'class-name' ] [ 0 ] . pattern = / ( \b (?: c l a s s | i n t e r f a c e | e x t e n d s | i m p l e m e n t s | i n s t a n c e o f | n e w ) \s + ) [ \w . \\ ] + / ;
1619
+ Prism . languages . javascript [ 'class-name' ] [ 0 ] . pattern = / ( \b (?: c l a s s | e x t e n d s | i m p l e m e n t s | i n s t a n c e o f | i n t e r f a c e | n e w ) \s + ) [ \w . \\ ] + / ;
1554
1620
1555
1621
Prism . languages . insertBefore ( 'javascript' , 'keyword' , {
1556
1622
'regex' : {
@@ -1626,9 +1692,23 @@ Prism.languages.insertBefore('javascript', 'string', {
1626
1692
} ,
1627
1693
'string' : / [ \s \S ] + /
1628
1694
}
1695
+ } ,
1696
+ 'string-property' : {
1697
+ pattern : / ( (?: ^ | [ , { ] ) [ \t ] * ) ( [ " ' ] ) (?: \\ (?: \r \n | [ \s \S ] ) | (? ! \2) [ ^ \\ \r \n ] ) * \2(? = \s * : ) / m,
1698
+ lookbehind : true ,
1699
+ greedy : true ,
1700
+ alias : 'property'
1629
1701
}
1630
1702
} ) ;
1631
1703
1704
+ Prism . languages . insertBefore ( 'javascript' , 'operator' , {
1705
+ 'literal-property' : {
1706
+ pattern : / ( (?: ^ | [ , { ] ) [ \t ] * ) (? ! \s ) [ _ $ a - z A - Z \xA0 - \uFFFF ] (?: (? ! \s ) [ $ \w \xA0 - \uFFFF ] ) * (? = \s * : ) / m,
1707
+ lookbehind : true ,
1708
+ alias : 'property'
1709
+ } ,
1710
+ } ) ;
1711
+
1632
1712
if ( Prism . languages . markup ) {
1633
1713
Prism . languages . markup . tag . addInlined ( 'script' , 'javascript' ) ;
1634
1714
@@ -1684,21 +1764,57 @@ Prism.languages.js = Prism.languages.javascript;
1684
1764
var SELECTOR = 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])'
1685
1765
+ ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])' ;
1686
1766
1687
- var lang = / \b l a n g (?: u a g e ) ? - ( [ \w - ] + ) \b / i;
1688
-
1689
1767
/**
1690
- * Sets the Prism `language-xxxx` or `lang-xxxx` class to the given language .
1768
+ * Loads the given file .
1691
1769
*
1692
- * @param {HTMLElement } element
1693
- * @param {string } language
1694
- * @returns { void }
1770
+ * @param {string } src The URL or path of the source file to load.
1771
+ * @param {(result: string) => void } success
1772
+ * @param { (reason: string) => void } error
1695
1773
*/
1696
- function setLanguageClass ( element , language ) {
1697
- var className = element . className ;
1698
- className = className . replace ( lang , ' ' ) + ' language-' + language ;
1699
- element . className = className . replace ( / \s + / g, ' ' ) . trim ( ) ;
1774
+ function loadFile ( src , success , error ) {
1775
+ var xhr = new XMLHttpRequest ( ) ;
1776
+ xhr . open ( 'GET' , src , true ) ;
1777
+ xhr . onreadystatechange = function ( ) {
1778
+ if ( xhr . readyState == 4 ) {
1779
+ if ( xhr . status < 400 && xhr . responseText ) {
1780
+ success ( xhr . responseText ) ;
1781
+ } else {
1782
+ if ( xhr . status >= 400 ) {
1783
+ error ( FAILURE_MESSAGE ( xhr . status , xhr . statusText ) ) ;
1784
+ } else {
1785
+ error ( FAILURE_EMPTY_MESSAGE ) ;
1786
+ }
1787
+ }
1788
+ }
1789
+ } ;
1790
+ xhr . send ( null ) ;
1700
1791
}
1701
1792
1793
+ /**
1794
+ * Parses the given range.
1795
+ *
1796
+ * This returns a range with inclusive ends.
1797
+ *
1798
+ * @param {string | null | undefined } range
1799
+ * @returns {[number, number | undefined] | undefined }
1800
+ */
1801
+ function parseRange ( range ) {
1802
+ var m = / ^ \s * ( \d + ) \s * (?: ( , ) \s * (?: ( \d + ) \s * ) ? ) ? $ / . exec ( range || '' ) ;
1803
+ if ( m ) {
1804
+ var start = Number ( m [ 1 ] ) ;
1805
+ var comma = m [ 2 ] ;
1806
+ var end = m [ 3 ] ;
1807
+
1808
+ if ( ! comma ) {
1809
+ return [ start , start ] ;
1810
+ }
1811
+ if ( ! end ) {
1812
+ return [ start , undefined ] ;
1813
+ }
1814
+ return [ start , Number ( end ) ] ;
1815
+ }
1816
+ return undefined ;
1817
+ }
1702
1818
1703
1819
Prism . hooks . add ( 'before-highlightall' , function ( env ) {
1704
1820
env . selector += ', ' + SELECTOR ;
@@ -1726,8 +1842,8 @@ Prism.languages.js = Prism.languages.javascript;
1726
1842
}
1727
1843
1728
1844
// set language classes
1729
- setLanguageClass ( code , language ) ;
1730
- setLanguageClass ( pre , language ) ;
1845
+ Prism . util . setLanguage ( code , language ) ;
1846
+ Prism . util . setLanguage ( pre , language ) ;
1731
1847
1732
1848
// preload the language
1733
1849
var autoloader = Prism . plugins . autoloader ;
@@ -1736,31 +1852,45 @@ Prism.languages.js = Prism.languages.javascript;
1736
1852
}
1737
1853
1738
1854
// load file
1739
- var xhr = new XMLHttpRequest ( ) ;
1740
- xhr . open ( 'GET' , src , true ) ;
1741
- xhr . onreadystatechange = function ( ) {
1742
- if ( xhr . readyState == 4 ) {
1743
- if ( xhr . status < 400 && xhr . responseText ) {
1744
- // mark as loaded
1745
- pre . setAttribute ( STATUS_ATTR , STATUS_LOADED ) ;
1746
-
1747
- // highlight code
1748
- code . textContent = xhr . responseText ;
1749
- Prism . highlightElement ( code ) ;
1750
-
1751
- } else {
1752
- // mark as failed
1753
- pre . setAttribute ( STATUS_ATTR , STATUS_FAILED ) ;
1754
-
1755
- if ( xhr . status >= 400 ) {
1756
- code . textContent = FAILURE_MESSAGE ( xhr . status , xhr . statusText ) ;
1757
- } else {
1758
- code . textContent = FAILURE_EMPTY_MESSAGE ;
1855
+ loadFile (
1856
+ src ,
1857
+ function ( text ) {
1858
+ // mark as loaded
1859
+ pre . setAttribute ( STATUS_ATTR , STATUS_LOADED ) ;
1860
+
1861
+ // handle data-range
1862
+ var range = parseRange ( pre . getAttribute ( 'data-range' ) ) ;
1863
+ if ( range ) {
1864
+ var lines = text . split ( / \r \n ? | \n / g) ;
1865
+
1866
+ // the range is one-based and inclusive on both ends
1867
+ var start = range [ 0 ] ;
1868
+ var end = range [ 1 ] == null ? lines . length : range [ 1 ] ;
1869
+
1870
+ if ( start < 0 ) { start += lines . length ; }
1871
+ start = Math . max ( 0 , Math . min ( start - 1 , lines . length ) ) ;
1872
+ if ( end < 0 ) { end += lines . length ; }
1873
+ end = Math . max ( 0 , Math . min ( end , lines . length ) ) ;
1874
+
1875
+ text = lines . slice ( start , end ) . join ( '\n' ) ;
1876
+
1877
+ // add data-start for line numbers
1878
+ if ( ! pre . hasAttribute ( 'data-start' ) ) {
1879
+ pre . setAttribute ( 'data-start' , String ( start + 1 ) ) ;
1759
1880
}
1760
1881
}
1882
+
1883
+ // highlight code
1884
+ code . textContent = text ;
1885
+ Prism . highlightElement ( code ) ;
1886
+ } ,
1887
+ function ( error ) {
1888
+ // mark as failed
1889
+ pre . setAttribute ( STATUS_ATTR , STATUS_FAILED ) ;
1890
+
1891
+ code . textContent = error ;
1761
1892
}
1762
- } ;
1763
- xhr . send ( null ) ;
1893
+ ) ;
1764
1894
}
1765
1895
} ) ;
1766
1896
0 commit comments