11// jshint multistr:true
22
33( function ( w , d ) {
4- 'use strict' ;
5-
6- var TABLE_NAME = 'hljs-ln' ,
7- LINE_NAME = 'hljs-ln-line' ,
8- CODE_BLOCK_NAME = 'hljs-ln-code' ,
9- NUMBERS_BLOCK_NAME = 'hljs-ln-numbers' ,
10- NUMBER_LINE_NAME = 'hljs-ln-n' ,
11- DATA_ATTR_NAME = 'data-line-number' ,
12- BREAK_LINE_REGEXP = / \r \n | \r | \n / g;
13-
14- if ( w . hljs ) {
15- w . hljs . initLineNumbersOnLoad = initLineNumbersOnLoad ;
16- w . hljs . lineNumbersBlock = lineNumbersBlock ;
17-
18- addStyles ( ) ;
19- } else {
20- w . console . error ( 'highlight.js not detected!' ) ;
21- }
22-
23- function addStyles ( ) {
24- var css = d . createElement ( 'style' ) ;
25- css . type = 'text/css' ;
26- css . innerHTML = format (
27- '.{0}{border-collapse:collapse}\
28- .{0} td{padding:0}\
29- .{1}:before{content:attr({2})}',
30- [
31- TABLE_NAME ,
32- NUMBER_LINE_NAME ,
33- DATA_ATTR_NAME
34- ] ) ;
35- d . getElementsByTagName ( 'head' ) [ 0 ] . appendChild ( css ) ;
36- }
37-
38- function initLineNumbersOnLoad ( options ) {
39- if ( d . readyState === 'complete' ) {
40- documentReady ( options ) ;
41- } else {
42- w . addEventListener ( 'DOMContentLoaded' , function ( ) {
43- documentReady ( options ) ;
44- } ) ;
45- }
46- }
47-
48- function documentReady ( options ) {
49- try {
50- var blocks = d . querySelectorAll ( 'code.hljs' ) ;
51-
52- for ( var i in blocks ) {
53- if ( blocks . hasOwnProperty ( i ) ) {
54- lineNumbersBlock ( blocks [ i ] , options ) ;
55- }
56- }
57- } catch ( e ) {
58- w . console . error ( 'LineNumbers error: ' , e ) ;
59- }
60- }
61-
62- function lineNumbersBlock ( element , options ) {
63- if ( typeof element !== 'object' ) return ;
64-
65- // define options or set default
66- options = options || {
67- singleLine : false
68- } ;
69-
70- // convert options
71- var firstLineIndex = ! ! options . singleLine ? 0 : 1 ;
72-
73- async ( function ( ) {
74-
75- duplicateMultilineNodes ( element ) ;
76-
77- element . innerHTML = addLineNumbersBlockFor ( element . innerHTML , firstLineIndex ) ;
78- } ) ;
79- }
80-
81- function addLineNumbersBlockFor ( inputHtml , firstLineIndex ) {
82-
83- var lines = getLines ( inputHtml ) ;
84-
85- if ( lines . length > firstLineIndex ) {
86- var html = '' ;
87-
88- for ( var i = 0 , l = lines . length ; i < l ; i ++ ) {
89- html += format (
90- '<tr>\
91- <td class="{0}">\
92- <div class="{1} {2}" {3}="{5}"></div>\
93- </td>\
94- <td class="{4}">\
95- <div class="{1}">{6}</div>\
96- </td>\
97- </tr>',
98- [
99- NUMBERS_BLOCK_NAME ,
100- LINE_NAME ,
101- NUMBER_LINE_NAME ,
102- DATA_ATTR_NAME ,
103- CODE_BLOCK_NAME ,
104- i + 1 ,
105- lines [ i ] . length > 0 ? lines [ i ] : ' '
106- ] ) ;
107- }
108-
109- return format ( '<table class="{0}">{1}</table>' , [ TABLE_NAME , html ] ) ;
110- }
111-
112- return inputHtml ;
113- }
114-
115- /**
116- * Recursive method for fix multi-line elements implementation in highlight.js
117- * Doing deep passage on child nodes.
118- * @param {HTMLElement } element
119- */
120- function duplicateMultilineNodes ( element ) {
121- var nodes = element . childNodes ;
122- for ( var node in nodes ) {
123- if ( nodes . hasOwnProperty ( node ) ) {
124- var child = nodes [ node ] ;
125- if ( getLinesCount ( child . textContent ) > 0 ) {
126- if ( child . childNodes . length > 0 ) {
127- duplicateMultilineNodes ( child ) ;
128- } else {
129- duplicateMultilineNode ( child ) ;
130- }
131- }
132- }
133- }
134- }
135-
136- /**
137- * Method for fix multi-line elements implementation in highlight.js
138- * @param {HTMLElement } element
139- */
140- function duplicateMultilineNode ( element ) {
141- var className = element . parentNode . className ;
142-
143- if ( ! / h l j s - / . test ( className ) ) return ;
144-
145- var lines = getLines ( element . textContent ) ;
146-
147- for ( var i = 0 , result = '' ; i < lines . length ; i ++ ) {
148- result += format ( '<span class="{0}">{1}</span>\n' , [ className , lines [ i ] ] ) ;
149- }
150- element . parentNode . innerHTML = result . trim ( ) ;
151- }
152-
153- function getLines ( text ) {
154- if ( text . length === 0 ) return [ ] ;
155- return text . split ( BREAK_LINE_REGEXP ) ;
156- }
157-
158- function getLinesCount ( text ) {
159- return ( text . trim ( ) . match ( BREAK_LINE_REGEXP ) || [ ] ) . length ;
160- }
161-
162- function async ( func ) {
163- w . setTimeout ( func , 0 ) ;
164- }
165-
166- /**
167- * {@link https://wcoder.github.io/notes/string-format-for-string-formating-in-javascript }
168- * @param {string } format
169- * @param {array } args
170- */
171- function format ( format , args ) {
172- return format . replace ( / \{ ( \d + ) \} / g, function ( m , n ) {
173- return args [ n ] ? args [ n ] : m ;
174- } ) ;
175- }
176-
177- } ( window , document ) ) ;
4+ 'use strict' ;
5+
6+ var TABLE_NAME = 'hljs-ln' ,
7+ LINE_NAME = 'hljs-ln-line' ,
8+ CODE_BLOCK_NAME = 'hljs-ln-code' ,
9+ NUMBERS_BLOCK_NAME = 'hljs-ln-numbers' ,
10+ NUMBER_LINE_NAME = 'hljs-ln-n' ,
11+ DATA_ATTR_NAME = 'data-line-number' ,
12+ BREAK_LINE_REGEXP = / \r \n | \r | \n / g;
13+
14+ if ( w . hljs ) {
15+ w . hljs . initLineNumbersOnLoad = initLineNumbersOnLoad ;
16+ w . hljs . lineNumbersBlock = lineNumbersBlock ;
17+
18+ addStyles ( ) ;
19+ } else {
20+ w . console . error ( 'highlight.js not detected!' ) ;
21+ }
22+
23+ function addStyles ( ) {
24+ var css = d . createElement ( 'style' ) ;
25+ css . type = 'text/css' ;
26+ css . innerHTML = format (
27+ '.{0}{border-collapse:collapse}\
28+ .{0} td{padding:0}\
29+ .{1}:before{content:attr({2})}',
30+ [
31+ TABLE_NAME ,
32+ NUMBER_LINE_NAME ,
33+ DATA_ATTR_NAME
34+ ] ) ;
35+ d . getElementsByTagName ( 'head' ) [ 0 ] . appendChild ( css ) ;
36+ }
37+
38+ function initLineNumbersOnLoad ( options ) {
39+ if ( d . readyState === 'complete' ) {
40+ documentReady ( options ) ;
41+ } else {
42+ w . addEventListener ( 'DOMContentLoaded' , function ( ) {
43+ documentReady ( options ) ;
44+ } ) ;
45+ }
46+ }
47+
48+ function documentReady ( options ) {
49+ try {
50+ var blocks = d . querySelectorAll ( 'code.hljs' ) ;
51+
52+ for ( var i in blocks ) {
53+ if ( blocks . hasOwnProperty ( i ) ) {
54+ lineNumbersBlock ( blocks [ i ] , options ) ;
55+ }
56+ }
57+ } catch ( e ) {
58+ w . console . error ( 'LineNumbers error: ' , e ) ;
59+ }
60+ }
61+
62+ function lineNumbersBlock ( element , options ) {
63+ if ( typeof element !== 'object' ) return ;
64+
65+ // define options or set default
66+ options = options || {
67+ singleLine : false
68+ } ;
69+
70+ // convert options
71+ var firstLineIndex = ! ! options . singleLine ? 0 : 1 ;
72+
73+ async ( function ( ) {
74+
75+ duplicateMultilineNodes ( element ) ;
76+
77+ element . innerHTML = addLineNumbersBlockFor ( element . innerHTML , firstLineIndex ) ;
78+ } ) ;
79+ }
80+
81+ function addLineNumbersBlockFor ( inputHtml , firstLineIndex ) {
82+
83+ var lines = getLines ( inputHtml ) ;
84+
85+ if ( lines . length > firstLineIndex ) {
86+ var html = '' ;
87+
88+ for ( var i = 0 , l = lines . length ; i < l ; i ++ ) {
89+ html += format (
90+ '<tr>\
91+ <td class="{0}">\
92+ <div class="{1} {2}" {3}="{5}"></div>\
93+ </td>\
94+ <td class="{4}">\
95+ <div class="{1}">{6}</div>\
96+ </td>\
97+ </tr>',
98+ [
99+ NUMBERS_BLOCK_NAME ,
100+ LINE_NAME ,
101+ NUMBER_LINE_NAME ,
102+ DATA_ATTR_NAME ,
103+ CODE_BLOCK_NAME ,
104+ i + 1 ,
105+ lines [ i ] . length > 0 ? lines [ i ] : ' '
106+ ] ) ;
107+ }
108+
109+ return format ( '<table class="{0}">{1}</table>' , [ TABLE_NAME , html ] ) ;
110+ }
111+
112+ return inputHtml ;
113+ }
114+
115+ /**
116+ * Recursive method for fix multi-line elements implementation in highlight.js
117+ * Doing deep passage on child nodes.
118+ * @param {HTMLElement } element
119+ */
120+ function duplicateMultilineNodes ( element ) {
121+ var nodes = element . childNodes ;
122+ for ( var node in nodes ) {
123+ if ( nodes . hasOwnProperty ( node ) ) {
124+ var child = nodes [ node ] ;
125+ if ( getLinesCount ( child . textContent ) > 0 ) {
126+ if ( child . childNodes . length > 0 ) {
127+ duplicateMultilineNodes ( child ) ;
128+ } else {
129+ duplicateMultilineNode ( child ) ;
130+ }
131+ }
132+ }
133+ }
134+ }
135+
136+ /**
137+ * Method for fix multi-line elements implementation in highlight.js
138+ * @param {HTMLElement } element
139+ */
140+ function duplicateMultilineNode ( element ) {
141+ var className = element . parentNode . className ;
142+
143+ if ( ! / h l j s - / . test ( className ) ) return ;
144+
145+ var lines = getLines ( element . textContent ) ;
146+
147+ for ( var i = 0 , result = '' ; i < lines . length ; i ++ ) {
148+ result += format ( '<span class="{0}">{1}</span>\n' , [ className , lines [ i ] ] ) ;
149+ }
150+ element . parentNode . innerHTML = result . trim ( ) ;
151+ }
152+
153+ function getLines ( text ) {
154+ if ( text . length === 0 ) return [ ] ;
155+ return text . split ( BREAK_LINE_REGEXP ) ;
156+ }
157+
158+ function getLinesCount ( text ) {
159+ return ( text . trim ( ) . match ( BREAK_LINE_REGEXP ) || [ ] ) . length ;
160+ }
161+
162+ function async ( func ) {
163+ w . setTimeout ( func , 0 ) ;
164+ }
165+
166+ /**
167+ * {@link https://wcoder.github.io/notes/string-format-for-string-formating-in-javascript }
168+ * @param {string } format
169+ * @param {array } args
170+ */
171+ function format ( format , args ) {
172+ return format . replace ( / \{ ( \d + ) \} / g, function ( m , n ) {
173+ return args [ n ] ? args [ n ] : m ;
174+ } ) ;
175+ }
176+
177+ } ( window , document ) ) ;
0 commit comments