@@ -36,37 +36,53 @@ var isLineHeightRounded = (function() {
36
36
} ( ) ) ;
37
37
38
38
function highlightLines ( pre , lines , classes ) {
39
+ lines = typeof lines === 'string' ? lines : pre . getAttribute ( 'data-line' ) ;
40
+
39
41
var ranges = lines . replace ( / \s + / g, '' ) . split ( ',' ) ,
40
42
offset = + pre . getAttribute ( 'data-line-offset' ) || 0 ;
41
43
42
44
var parseMethod = isLineHeightRounded ( ) ? parseInt : parseFloat ;
43
45
var lineHeight = parseMethod ( getComputedStyle ( pre ) . lineHeight ) ;
46
+ var hasLineNumbers = hasClass ( pre , 'line-numbers' ) ;
44
47
45
- for ( var i = 0 , range ; range = ranges [ i ++ ] ; ) {
46
- range = range . split ( '-' ) ;
48
+ for ( var i = 0 , currentRange ; currentRange = ranges [ i ++ ] ; ) {
49
+ var range = currentRange . split ( '-' ) ;
47
50
48
51
var start = + range [ 0 ] ,
49
52
end = + range [ 1 ] || start ;
50
53
51
- var line = document . createElement ( 'div' ) ;
54
+ var line = pre . querySelector ( '.line-highlight[data-range="' + currentRange + '"]' ) || document . createElement ( 'div' ) ;
52
55
53
- line . textContent = Array ( end - start + 2 ) . join ( ' \n' ) ;
54
56
line . setAttribute ( 'aria-hidden' , 'true' ) ;
57
+ line . setAttribute ( 'data-range' , currentRange ) ;
55
58
line . className = ( classes || '' ) + ' line-highlight' ;
56
59
57
60
//if the line-numbers plugin is enabled, then there is no reason for this plugin to display the line numbers
58
- if ( ! hasClass ( pre , 'line-numbers' ) ) {
61
+ if ( hasLineNumbers && Prism . plugins . lineNumbers ) {
62
+ var startNode = Prism . plugins . lineNumbers . getLine ( pre , start ) ;
63
+ var endNode = Prism . plugins . lineNumbers . getLine ( pre , end ) ;
64
+
65
+ if ( startNode ) {
66
+ line . style . top = startNode . offsetTop + 'px' ;
67
+ }
68
+
69
+ if ( endNode ) {
70
+ line . style . height = ( endNode . offsetTop - startNode . offsetTop ) + endNode . offsetHeight + 'px' ;
71
+ }
72
+ } else {
59
73
line . setAttribute ( 'data-start' , start ) ;
60
74
61
75
if ( end > start ) {
62
76
line . setAttribute ( 'data-end' , end ) ;
63
77
}
64
- }
78
+
79
+ line . style . top = ( start - offset - 1 ) * lineHeight + 'px' ;
65
80
66
- line . style . top = ( start - offset - 1 ) * lineHeight + 'px' ;
81
+ line . textContent = new Array ( end - start + 2 ) . join ( ' \n' ) ;
82
+ }
67
83
68
84
//allow this to play nicely with the line-numbers plugin
69
- if ( hasClass ( pre , 'line-numbers' ) ) {
85
+ if ( hasLineNumbers ) {
70
86
//need to attack to pre as when line-numbers is enabled, the code tag is relatively which screws up the positioning
71
87
pre . appendChild ( line ) ;
72
88
} else {
@@ -133,7 +149,7 @@ Prism.hooks.add('before-sanity-check', function(env) {
133
149
}
134
150
} ) ;
135
151
136
- Prism . hooks . add ( 'complete' , function ( env ) {
152
+ Prism . hooks . add ( 'complete' , function completeHook ( env ) {
137
153
var pre = env . element . parentNode ;
138
154
var lines = pre && pre . getAttribute ( 'data-line' ) ;
139
155
@@ -142,11 +158,24 @@ Prism.hooks.add('complete', function(env) {
142
158
}
143
159
144
160
clearTimeout ( fakeTimer ) ;
145
- highlightLines ( pre , lines ) ;
146
161
147
- fakeTimer = setTimeout ( applyHash , 1 ) ;
162
+ var hasLineNumbers = Prism . plugins . lineNumbers ;
163
+ var isLineNumbersLoaded = env . plugins && env . plugins . lineNumbers ;
164
+
165
+ if ( hasLineNumbers && ! isLineNumbersLoaded ) {
166
+ Prism . hooks . add ( 'line-numbers' , completeHook ) ;
167
+ } else {
168
+ highlightLines ( pre , lines ) ;
169
+ fakeTimer = setTimeout ( applyHash , 1 ) ;
170
+ }
148
171
} ) ;
149
172
150
173
window . addEventListener ( 'hashchange' , applyHash ) ;
174
+ window . addEventListener ( 'resize' , function ( ) {
175
+ var preElements = document . querySelectorAll ( 'pre[data-line]' ) ;
176
+ Array . prototype . forEach . call ( preElements , function ( pre ) {
177
+ highlightLines ( pre ) ;
178
+ } ) ;
179
+ } ) ;
151
180
152
- } ) ( ) ;
181
+ } ) ( ) ;
0 commit comments