8000 highlightjs-line-numbers: Upgrade to version 2.2.0 · SoftwareHeritage/swh-web@50dc8ec · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 50dc8ec

Browse files
committed
highlightjs-line-numbers: Upgrade to version 2.2.0
This new release fixes multi-line strings and comments highlighting bugs (see wcoder/highlightjs-line-numbers.js#22 and wcoder/highlightjs-line-numbers.js#30).
1 parent c16583c commit 50dc8ec

File tree

2 files changed

+172
-149
lines changed

2 files changed

+172
-149
lines changed

swh/web/static/js/highlightjs-line-numbers/dist/highlightjs-line-numbers.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 171 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,177 @@
1+
// jshint multistr:true
2+
13
(function (w, d) {
2-
'use strict';
3-
4-
var TABLE_NAME = 'hljs-ln',
5-
LINE_NAME = 'hljs-ln-line',
6-
CODE_BLOCK_NAME = 'hljs-ln-code',
7-
NUMBERS_BLOCK_NAME = 'hljs-ln-numbers',
8-
NUMBER_LINE_NAME = 'hljs-ln-n',
9-
DATA_ATTR_NAME = 'data-line-number';
10-
11-
// string format
12-
// https://wcoder.github.io/notes/string-format-for-string-formating-in-javascript
13-
var format = function (str, args) {
14-
return str.replace(/\{(\d+)\}/g, function(m, n){
15-
return args[n] ? args[n] : m;
16-
});
17-
};
18-
19-
if (w.hljs) {
20-
w.hljs.initLineNumbersOnLoad = initLineNumbersOnLoad;
21-
w.hljs.lineNumbersBlock = lineNumbersBlock;
22-
23-
addStyles();
24-
} else {
25-
w.console.error('highlight.js not detected!');
26-
}
27-
28-
function addStyles () {
29-
var css = d.createElement('style');
30-
css.type = 'text/css';
31-
css.innerHTML = format(
32-
'.{0}{border-collapse:collapse}\
33-
.{0} td{padding:0}\
34-
.{1}:before{content:attr({2})}',
35-
[
36-
TABLE_NAME,
37-
NUMBER_LINE_NAME,
38-
DATA_ATTR_NAME
39-
]);
40-
d.getElementsByTagName('head')[0].appendChild(css);
41-
}
42-
43-
function initLineNumbersOnLoad (options) {
44-
if (d.readyState === 'complete') {
45-
documentReady(options);
46-
} else {
47-
w.addEventListener('DOMContentLoaded', function () {
48-
documentReady(options);
49-
});
50-
}
51-
}
52-
53-
function documentReady (options) {
54-
try {
55-
var blocks = d.querySelectorAll('code.hljs');
56-
57-
for (var i in blocks) {
58-
if (blocks.hasOwnProperty(i)) {
59-
lineNumbersBlock(blocks[i], options);
60-
}
61-
}
62-
} catch (e) {
63-
w.console.error('LineNumbers error: ', e);
64-
}
65-
}
66-
67-
function lineNumbersBlock (element, options) {
68-
if (typeof element !== 'object') return;
69-
70-
// define options or set default
71-
options = options || {
72-
singleLine: false
73-
};
74-
75-
// convert options
76-
var firstLineIndex = !!options.singleLine ? 0 : 1;
77-
78-
var text = changeMultilineComments(element);
79-
var lines = getLines(text);
80-
81-
if (lines.length > firstLineIndex) {
82-
var html = '';
83-
84-
for (var i = 0, l = lines.length; i < l; i++) {
85-
html += format(
86-
'<tr>\
87-
<td class="{0}">\
88-
<div class="{1} {2}" {3}="{5}"></div>\
89-
</td>\
90-
<td class="{4}">\
91-
<div class="{1}">{6}</div>\
92-
</td>\
93-
</tr>',
94-
[
95-
NUMBERS_BLOCK_NAME,
96-
LINE_NAME,
97-
NUMBER_LINE_NAME,
98-
DATA_ATTR_NAME,
99-
CODE_BLOCK_NAME,
100-
i + 1,
101-
lines[i].length > 0 ? lines[i] : ' '
102-
]);
103-
}
104-
105-
element.innerHTML = format('<table class="{0}">{1}</table>', [ TABLE_NAME, html ]);
106-
}
107-
}
108-
109-
function duplicateMultilineTag(element){
110-
var result = '';
111-
var lines = element.innerText.split(/\r\n|\r|\n/g);
112-
for(var i = 0; i<lines.length; i++){
113-
element.innerText = lines[i];
114-
result += element.outerHTML;
115-
if(i < lines.length -1)
116-
result += '\n';
117-
}
118-
return result;
119-
}
120-
121-
function escapeHtml(unsafe) {
122-
return unsafe.replace(/&/g, "&amp;")
123-
.replace(/</g, "&lt;")
124-
.replace(/>/g, "&gt;")
125-
.replace(/"/g, "&quot;")
126-
.replace(/'/g, "&#039;");
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;
127113
}
128114

129-
function changeMultilineComments(element) {
130-
var result = '';
131-
var children = element.childNodes;
132-
for(var child in children) {
133-
if(children.hasOwnProperty(child)) {
134-
if(children[child].className === "hljs-comment" ||
135-
children[child].className === "hljs-string") {
136-
result += duplicateMultilineTag(children[child]);
137-
}
138-
else if(children[child].childNodes.length) {
139-
result += children[child].outerHTML;
140-
}
141-
else {
142-
result += escapeHtml(children[child].textContent);
143-
}
144-
}
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+
}
145133
}
146-
return result;
147-
}
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;
148142

149-
function getLines(text) {
150-
if (text.length === 0) return [];
151-
return text.split(/\r\n|\r|\n/g);
152-
}
143+
if ( ! /hljs-/.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+
}
153176

154-
}(window, document));
177+
}(window, document));

0 commit comments

Comments
 (0)
0