1
- ( function ( ) {
1
+ ( function ( ) {
2
2
3
- if ( typeof self === 'undefined' || ! self . Prism || ! self . document ) {
4
- return ;
5
- }
6
-
7
- Prism . hooks . add ( 'complete' , function ( env ) {
8
- if ( ! env . code ) {
3
+ if ( typeof self === 'undefined' || ! self . Prism || ! self . document ) {
9
4
return ;
10
5
}
11
6
12
- // works only for <code> wrapped inside <pre> (not inline)
13
- var pre = env . element . parentNode ;
14
- var clsReg = / \s * \b l i n e - n u m b e r s \b \s * / ;
15
- if (
16
- ! pre || ! / p r e / i. test ( pre . nodeName ) ||
7
+ /**
8
+ * Class name for <pre> which is activating the plugin
9
+ * @type {String }
10
+ */
11
+ var PLUGIN_CLASS = 'line-numbers' ;
12
+
13
+ /**
14
+ * Resizes line numbers spans according to height of line of code
15
+ * @param {Element } element <pre> element
16
+ */
17
+ var _resizeElement = function ( element ) {
18
+ var codeStyles = getStyles ( element ) ;
19
+ var whiteSpace = codeStyles [ 'white-space' ] ;
20
+
21
+ if ( whiteSpace === 'pre-wrap' || whiteSpace === 'pre-line' ) {
22
+ var codeElement = element . querySelector ( 'code' ) ;
23
+ var lineNumbersWrapper = element . querySelector ( '.line-numbers-rows' ) ;
24
+ var lineNumberSizer = element . querySelector ( '.line-numbers-sizer' ) ;
25
+ var codeLines = element . textContent . split ( '\n' ) ;
26
+
27
+ if ( ! lineNumberSizer ) {
28
+ lineNumberSizer = document . createElement ( 'span' ) ;
29
+ lineNumberSizer . className = 'line-numbers-sizer' ;
30
+
31
+ codeElement . appendChild ( lineNumberSizer ) ;
32
+ }
33
+
34
+ lineNumberSizer . style . display = 'block' ;
35
+
36
+ codeLines . forEach ( function ( line , lineNumber ) {
37
+ lineNumberSizer . textContent = line || '\n' ;
38
+ var lineSize = lineNumberSizer . getBoundingClientRect ( ) . height ;
39
+ lineNumbersWrapper . children [ lineNumber ] . style . height = lineSize + 'px' ;
40
+ } ) ;
41
+
42
+ lineNumberSizer . textContent = '' ;
43
+ lineNumberSizer . style . display = 'none' ;
44
+ }
45
+ } ;
46
+
47
+ /**
48
+ * Returns style declarations for the element
49
+ * @param {Element } element
50
+ */
51
+ var getStyles = function ( element ) {
52
+ if ( ! element ) {
53
+ return null ;
54
+ }
55
+
56
+ return window . getComputedStyle ? getComputedStyle ( element ) : ( element . currentStyle || null ) ;
57
+ } ;
58
+
59
+ window . addEventListener ( 'resize' , function ( ) {
60
+ Array . prototype . forEach . call ( document . querySelectorAll ( 'pre.' + PLUGIN_CLASS ) , _resizeElement ) ;
61
+ } ) ;
62
+
63
+ Prism . hooks . add ( 'complete' , function ( env ) {
64
+ if ( ! env . code ) {
65
+ return ;
66
+ }
67
+
68
+ // works only for <code> wrapped inside <pre> (not inline)
69
+ var pre = env . element . parentNode ;
70
+ var clsReg = / \s * \b l i n e - n u m b e r s \b \s * / ;
71
+ if (
72
+ ! pre || ! / p r e / i. test ( pre . nodeName ) ||
17
73
// Abort only if nor the <pre> nor the <code> have the class
18
- ( ! clsReg . test ( pre . className ) && ! clsReg . test ( env . element . className ) )
19
- ) {
20
- return ;
21
- }
74
+ ( ! clsReg . test ( pre . className ) && ! clsReg . test ( env . element . className ) )
75
+ ) {
76
+ return ;
77
+ }
22
78
23
- if ( env . element . querySelector ( ".line-numbers-rows" ) ) {
24
- // Abort if line numbers already exists
25
- return ;
26
- }
79
+ if ( env . element . querySelector ( ".line-numbers-rows" ) ) {
80
+ // Abort if line numbers already exists
81
+ return ;
82
+ }
27
83
28
- if ( clsReg . test ( env . element . className ) ) {
29
- // Remove the class "line-numbers" from the <code>
30
- env . element . className = env . element . className . replace ( clsReg , '' ) ;
31
- }
32
- if ( ! clsReg . test ( pre . className ) ) {
33
- // Add the class "line-numbers" to the <pre>
34
- pre . className += ' line-numbers' ;
35
- }
84
+ if ( clsReg . test ( env . element . className ) ) {
85
+ // Remove the class "line-numbers" from the <code>
86
+ env . element . className = env . element . className . replace ( clsReg , '' ) ;
87
+ }
88
+ if ( ! clsReg . test ( pre . className ) ) {
89
+ // Add the class "line-numbers" to the <pre>
90
+ pre . className += ' line-numbers' ;
91
+ }
36
92
37
- var match = env . code . match ( / \n (? ! $ ) / g) ;
38
- var linesNum = match ? match . length + 1 : 1 ;
39
- var lineNumbersWrapper ;
93
+ var match = env . code . match ( / \n (? ! $ ) / g) ;
94
+ var linesNum = match ? match . length + 1 : 1 ;
95
+ var lineNumbersWrapper ;
40
96
41
- var lines = new Array ( linesNum + 1 ) ;
42
- lines = lines . join ( '<span></span>' ) ;
97
+ var lines = new Array ( linesNum + 1 ) ;
98
+ lines = lines . join ( '<span></span>' ) ;
43
99
44
- lineNumbersWrapper = document . createElement ( 'span' ) ;
45
- lineNumbersWrapper . setAttribute ( 'aria-hidden' , 'true' ) ;
46
- lineNumbersWrapper . className = 'line-numbers-rows' ;
47
- lineNumbersWrapper . innerHTML = lines ;
100
+ lineNumbersWrapper = document . createElement ( 'span' ) ;
101
+ lineNumbersWrapper . setAttribute ( 'aria-hidden' , 'true' ) ;
102
+ lineNumbersWrapper . className = 'line-numbers-rows' ;
103
+ lineNumbersWrapper . innerHTML = lines ;
48
104
49
- if ( pre . hasAttribute ( 'data-start' ) ) {
50
- pre . style . counterReset = 'linenumber ' + ( parseInt ( pre . getAttribute ( 'data-start' ) , 10 ) - 1 ) ;
51
- }
105
+ if ( pre . hasAttribute ( 'data-start' ) ) {
106
+ pre . style . counterReset = 'linenumber ' + ( parseInt ( pre . getAttribute ( 'data-start' ) , 10 ) - 1 ) ;
107
+ }
52
108
53
- env . element . appendChild ( lineNumbersWrapper ) ;
109
+ env . element . appendChild ( lineNumbersWrapper ) ;
54
110
55
- } ) ;
111
+ _resizeElement ( pre ) ;
112
+ } ) ;
56
113
57
114
} ( ) ) ;
0 commit comments