bajo-spatial 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/BajoSpatial.html +1 -1
- package/docs/data/search.json +1 -1
- package/docs/global.html +1 -1
- package/docs/index.js.html +57 -17
- package/docs/scripts/core.js +477 -476
- package/docs/scripts/resize.js +36 -36
- package/docs/scripts/search.js +105 -105
- package/docs/scripts/third-party/fuse.js +1 -1
- package/docs/scripts/third-party/hljs-line-num-original.js +285 -282
- package/docs/scripts/third-party/hljs-line-num.js +1 -1
- package/docs/scripts/third-party/hljs-original.js +1202 -1195
- package/docs/scripts/third-party/hljs.js +1 -1
- package/docs/scripts/third-party/popper.js +1 -1
- package/docs/scripts/third-party/tippy.js +1 -1
- package/docs/scripts/third-party/tocbot.js +509 -508
- package/index.js +44 -4
- package/package.json +4 -2
- package/test/bajo-spatial.test.js +181 -0
- package/wiki/CHANGES.md +5 -0
|
@@ -1,366 +1,369 @@
|
|
|
1
1
|
// jshint multistr:true
|
|
2
2
|
|
|
3
3
|
(function (w, d) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function isHljsLnCodeDescendant (domElt) {
|
|
25
|
-
let curElt = domElt
|
|
26
|
-
while (curElt) {
|
|
27
|
-
if (curElt.className && curElt.className.indexOf('hljs-ln-code') !== -1) {
|
|
28
|
-
return true
|
|
29
|
-
}
|
|
30
|
-
curElt = curElt.parentNode
|
|
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
|
+
w.hljs.lineNumbersValue = lineNumbersValue;
|
|
18
|
+
|
|
19
|
+
addStyles();
|
|
20
|
+
} else {
|
|
21
|
+
w.console.error('highlight.js not detected!');
|
|
31
22
|
}
|
|
32
|
-
return false
|
|
33
|
-
}
|
|
34
23
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// Due to hljs-ln wrapping the lines of code inside a <table> element,
|
|
45
|
-
// itself wrapped inside a <pre> element, window.getSelection().toString()
|
|
46
|
-
// does not contain any line breaks. So we need to get them back using the
|
|
47
|
-
// rendered code in the DOM as reference.
|
|
48
|
-
function edgeGetSelectedCodeLines (selection) {
|
|
49
|
-
// current selected text without line breaks
|
|
50
|
-
const selectionText = selection.toString()
|
|
51
|
-
|
|
52
|
-
// get the <td> element wrapping the first line of selected code
|
|
53
|
-
let tdAnchor = selection.anchorNode
|
|
54
|
-
while (tdAnchor.nodeName !== 'TD') {
|
|
55
|
-
tdAnchor = tdAnchor.parentNode
|
|
24
|
+
function isHljsLnCodeDescendant(domElt) {
|
|
25
|
+
var curElt = domElt;
|
|
26
|
+
while (curElt) {
|
|
27
|
+
if (curElt.className && curElt.className.indexOf('hljs-ln-code') !== -1) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
curElt = curElt.parentNode;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
56
33
|
}
|
|
57
34
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
35
|
+
function getHljsLnTable(hljsLnDomElt) {
|
|
36
|
+
var curElt = hljsLnDomElt;
|
|
37
|
+
while (curElt.nodeName !== 'TABLE') {
|
|
38
|
+
curElt = curElt.parentNode;
|
|
39
|
+
}
|
|
40
|
+
return curElt;
|
|
62
41
|
}
|
|
63
42
|
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
)
|
|
130
|
-
e.preventDefault()
|
|
43
|
+
// Function to workaround a copy issue with Microsoft Edge.
|
|
44
|
+
// Due to hljs-ln wrapping the lines of code inside a <table> element,
|
|
45
|
+
// itself wrapped inside a <pre> element, window.getSelection().toString()
|
|
46
|
+
// does not contain any line breaks. So we need to get them back using the
|
|
47
|
+
// rendered code in the DOM as reference.
|
|
48
|
+
function edgeGetSelectedCodeLines(selection) {
|
|
49
|
+
// current selected text without line breaks
|
|
50
|
+
var selectionText = selection.toString();
|
|
51
|
+
|
|
52
|
+
// get the <td> element wrapping the first line of selected code
|
|
53
|
+
var tdAnchor = selection.anchorNode;
|
|
54
|
+
while (tdAnchor.nodeName !== 'TD') {
|
|
55
|
+
tdAnchor = tdAnchor.parentNode;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// get the <td> element wrapping the last line of selected code
|
|
59
|
+
var tdFocus = selection.focusNode;
|
|
60
|
+
while (tdFocus.nodeName !== 'TD') {
|
|
61
|
+
tdFocus = tdFocus.parentNode;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// extract line numbers
|
|
65
|
+
var firstLineNumber = parseInt(tdAnchor.dataset.lineNumber);
|
|
66
|
+
var lastLineNumber = parseInt(tdFocus.dataset.lineNumber);
|
|
67
|
+
|
|
68
|
+
// multi-lines copied case
|
|
69
|
+
if (firstLineNumber != lastLineNumber) {
|
|
70
|
+
|
|
71
|
+
var firstLineText = tdAnchor.textContent;
|
|
72
|
+
var lastLineText = tdFocus.textContent;
|
|
73
|
+
|
|
74
|
+
// if the selection was made backward, swap values
|
|
75
|
+
if (firstLineNumber > lastLineNumber) {
|
|
76
|
+
var tmp = firstLineNumber;
|
|
77
|
+
firstLineNumber = lastLineNumber;
|
|
78
|
+
lastLineNumber = tmp;
|
|
79
|
+
tmp = firstLineText;
|
|
80
|
+
firstLineText = lastLineText;
|
|
81
|
+
lastLineText = tmp;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// discard not copied characters in first line
|
|
85
|
+
while (selectionText.indexOf(firstLineText) !== 0) {
|
|
86
|
+
firstLineText = firstLineText.slice(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// discard not copied characters in last line
|
|
90
|
+
while (selectionText.lastIndexOf(lastLineText) === -1) {
|
|
91
|
+
lastLineText = lastLineText.slice(0, -1);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// reconstruct and return the real copied text
|
|
95
|
+
var selectedText = firstLineText;
|
|
96
|
+
var hljsLnTable = getHljsLnTable(tdAnchor);
|
|
97
|
+
for (var i = firstLineNumber + 1 ; i < lastLineNumber ; ++i) {
|
|
98
|
+
var codeLineSel = format('.{0}[{1}="{2}"]', [CODE_BLOCK_NAME, DATA_ATTR_NAME, i]);
|
|
99
|
+
var codeLineElt = hljsLnTable.querySelector(codeLineSel);
|
|
100
|
+
selectedText += '\n' + codeLineElt.textContent;
|
|
101
|
+
}
|
|
102
|
+
selectedText += '\n' + lastLineText;
|
|
103
|
+
return selectedText;
|
|
104
|
+
// single copied line case
|
|
105
|
+
} else {
|
|
106
|
+
return selectionText;
|
|
107
|
+
}
|
|
131
108
|
}
|
|
132
|
-
})
|
|
133
109
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
110
|
+
// ensure consistent code copy/paste behavior across all browsers
|
|
111
|
+
// (see https://github.com/wcoder/highlightjs-line-numbers.js/issues/51)
|
|
112
|
+
document.addEventListener('copy', function(e) {
|
|
113
|
+
// get current selection
|
|
114
|
+
var selection = window.getSelection();
|
|
115
|
+
// override behavior when one wants to copy line of codes
|
|
116
|
+
if (isHljsLnCodeDescendant(selection.anchorNode)) {
|
|
117
|
+
var selectionText;
|
|
118
|
+
// workaround an issue with Microsoft Edge as copied line breaks
|
|
119
|
+
// are removed otherwise from the selection string
|
|
120
|
+
if (window.navigator.userAgent.indexOf('Edge') !== -1) {
|
|
121
|
+
selectionText = edgeGetSelectedCodeLines(selection);
|
|
122
|
+
} else {
|
|
123
|
+
// other browsers can directly use the selection string
|
|
124
|
+
selectionText = selection.toString();
|
|
125
|
+
}
|
|
126
|
+
e.clipboardData.setData(
|
|
127
|
+
'text/plain',
|
|
128
|
+
selectionText
|
|
129
|
+
.replace(/(^\t)/gm, '')
|
|
130
|
+
);
|
|
131
|
+
e.preventDefault();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
function addStyles () {
|
|
136
|
+
var css = d.createElement('style');
|
|
137
|
+
css.type = 'text/css';
|
|
138
|
+
css.innerHTML = format(
|
|
139
|
+
'.{0}{border-collapse:collapse}' +
|
|
139
140
|
'.{0} td{padding:0}' +
|
|
140
141
|
'.{1}:before{content:attr({2})}',
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function initLineNumbersOnLoad (options) {
|
|
150
|
-
if (d.readyState === 'interactive' || d.readyState === 'complete') {
|
|
151
|
-
documentReady(options)
|
|
152
|
-
} else {
|
|
153
|
-
w.addEventListener('DOMContentLoaded', function () {
|
|
154
|
-
documentReady(options)
|
|
155
|
-
})
|
|
142
|
+
[
|
|
143
|
+
TABLE_NAME,
|
|
144
|
+
NUMBER_LINE_NAME,
|
|
145
|
+
DATA_ATTR_NAME
|
|
146
|
+
]);
|
|
147
|
+
d.getElementsByTagName('head')[0].appendChild(css);
|
|
156
148
|
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function documentReady (options) {
|
|
160
|
-
try {
|
|
161
|
-
const blocks = d.querySelectorAll('code.hljs,code.nohighlight')
|
|
162
149
|
|
|
163
|
-
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
150
|
+
function initLineNumbersOnLoad (options) {
|
|
151
|
+
if (d.readyState === 'interactive' || d.readyState === 'complete') {
|
|
152
|
+
documentReady(options);
|
|
153
|
+
} else {
|
|
154
|
+
w.addEventListener('DOMContentLoaded', function () {
|
|
155
|
+
documentReady(options);
|
|
156
|
+
});
|
|
168
157
|
}
|
|
169
|
-
}
|
|
170
|
-
} catch (e) {
|
|
171
|
-
w.console.error('LineNumbers error: ', e)
|
|
172
158
|
}
|
|
173
|
-
}
|
|
174
159
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
160
|
+
function documentReady (options) {
|
|
161
|
+
try {
|
|
162
|
+
var blocks = d.querySelectorAll('code.hljs,code.nohighlight');
|
|
163
|
+
|
|
164
|
+
for (var i in blocks) {
|
|
165
|
+
if (blocks.hasOwnProperty(i)) {
|
|
166
|
+
if (!isPluginDisabledForBlock(blocks[i])) {
|
|
167
|
+
lineNumbersBlock(blocks[i], options);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
} catch (e) {
|
|
172
|
+
w.console.error('LineNumbers error: ', e);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
178
175
|
|
|
179
|
-
|
|
180
|
-
|
|
176
|
+
function isPluginDisabledForBlock(element) {
|
|
177
|
+
return element.classList.contains('nohljsln');
|
|
178
|
+
}
|
|
181
179
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
})
|
|
185
|
-
}
|
|
180
|
+
function lineNumbersBlock (element, options) {
|
|
181
|
+
if (typeof element !== 'object') return;
|
|
186
182
|
|
|
187
|
-
|
|
188
|
-
|
|
183
|
+
async(function () {
|
|
184
|
+
element.innerHTML = lineNumbersInternal(element, options);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
189
187
|
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
function lineNumbersValue (value, options) {
|
|
189
|
+
if (typeof value !== 'string') return;
|
|
192
190
|
|
|
193
|
-
|
|
194
|
-
|
|
191
|
+
var element = document.createElement('code')
|
|
192
|
+
element.innerHTML = value
|
|
195
193
|
|
|
196
|
-
|
|
197
|
-
|
|
194
|
+
return lineNumbersInternal(element, options);
|
|
195
|
+
}
|
|
198
196
|
|
|
199
|
-
|
|
197
|
+
function lineNumbersInternal (element, options) {
|
|
200
198
|
|
|
201
|
-
|
|
202
|
-
}
|
|
199
|
+
var internalOptions = mapOptions(element, options);
|
|
203
200
|
|
|
204
|
-
|
|
205
|
-
const lines = getLines(inputHtml)
|
|
201
|
+
duplicateMultilineNodes(element);
|
|
206
202
|
|
|
207
|
-
|
|
208
|
-
if (lines[lines.length - 1].trim() === '') {
|
|
209
|
-
lines.pop()
|
|
203
|
+
return addLineNumbersBlockFor(element.innerHTML, internalOptions);
|
|
210
204
|
}
|
|
211
205
|
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
function addLineNumbersBlockFor (inputHtml, options) {
|
|
207
|
+
var lines = getLines(inputHtml);
|
|
208
|
+
|
|
209
|
+
// if last line contains only carriage return remove it
|
|
210
|
+
if (lines[lines.length-1].trim() === '') {
|
|
211
|
+
lines.pop();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (lines.length > 1 || options.singleLine) {
|
|
215
|
+
var html = '';
|
|
214
216
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
217
|
+
for (var i = 0, l = lines.length; i < l; i++) {
|
|
218
|
+
html += format(
|
|
219
|
+
'<tr>' +
|
|
218
220
|
'<td class="{0} {1}" {3}="{5}">' +
|
|
219
221
|
'</td>' +
|
|
220
222
|
'<td class="{0} {4}" {3}="{5}">' +
|
|
221
223
|
'{6}' +
|
|
222
224
|
'</td>' +
|
|
223
225
|
'</tr>',
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
226
|
+
[
|
|
227
|
+
LINE_NAME,
|
|
228
|
+
NUMBERS_BLOCK_NAME,
|
|
229
|
+
NUMBER_LINE_NAME,
|
|
230
|
+
DATA_ATTR_NAME,
|
|
231
|
+
CODE_BLOCK_NAME,
|
|
232
|
+
i + options.startFrom,
|
|
233
|
+
lines[i].length > 0 ? lines[i] : ' '
|
|
234
|
+
]);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return format('<table class="{0}">{1}</table>', [ TABLE_NAME, html ]);
|
|
238
|
+
}
|
|
237
239
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
+
return inputHtml;
|
|
241
|
+
}
|
|
240
242
|
|
|
241
|
-
|
|
243
|
+
/**
|
|
242
244
|
* @param {HTMLElement} element Code block.
|
|
243
245
|
* @param {Object} options External API options.
|
|
244
246
|
* @returns {Object} Internal API options.
|
|
245
247
|
*/
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
248
|
+
function mapOptions (element, options) {
|
|
249
|
+
options = options || {};
|
|
250
|
+
return {
|
|
251
|
+
singleLine: getSingleLineOption(options),
|
|
252
|
+
startFrom: getStartFromOption(element, options)
|
|
253
|
+
};
|
|
251
254
|
}
|
|
252
|
-
}
|
|
253
255
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
256
|
+
function getSingleLineOption (options) {
|
|
257
|
+
var defaultValue = false;
|
|
258
|
+
if (!!options.singleLine) {
|
|
259
|
+
return options.singleLine;
|
|
260
|
+
}
|
|
261
|
+
return defaultValue;
|
|
258
262
|
}
|
|
259
|
-
return defaultValue
|
|
260
|
-
}
|
|
261
263
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
264
|
+
function getStartFromOption (element, options) {
|
|
265
|
+
var defaultValue = 1;
|
|
266
|
+
var startFrom = defaultValue;
|
|
265
267
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
268
|
+
if (isFinite(options.startFrom)) {
|
|
269
|
+
startFrom = options.startFrom;
|
|
270
|
+
}
|
|
269
271
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
// can be overridden because local option is priority
|
|
273
|
+
var value = getAttribute(element, 'data-ln-start-from');
|
|
274
|
+
if (value !== null) {
|
|
275
|
+
startFrom = toNumber(value, defaultValue);
|
|
276
|
+
}
|
|
275
277
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
+
return startFrom;
|
|
279
|
+
}
|
|
278
280
|
|
|
279
|
-
|
|
281
|
+
/**
|
|
280
282
|
* Recursive method for fix multi-line elements implementation in highlight.js
|
|
281
283
|
* Doing deep passage on child nodes.
|
|
282
284
|
* @param {HTMLElement} element
|
|
283
285
|
*/
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
286
|
+
function duplicateMultilineNodes (element) {
|
|
287
|
+
var nodes = element.childNodes;
|
|
288
|
+
for (var node in nodes) {
|
|
289
|
+
if (nodes.hasOwnProperty(node)) {
|
|
290
|
+
var child = nodes[node];
|
|
291
|
+
if (getLinesCount(child.textContent) > 0) {
|
|
292
|
+
if (child.childNodes.length > 0) {
|
|
293
|
+
duplicateMultilineNodes(child);
|
|
294
|
+
} else {
|
|
295
|
+
duplicateMultilineNode(child.parentNode);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
295
299
|
}
|
|
296
|
-
}
|
|
297
300
|
}
|
|
298
|
-
}
|
|
299
301
|
|
|
300
|
-
|
|
302
|
+
/**
|
|
301
303
|
* Method for fix multi-line elements implementation in highlight.js
|
|
302
304
|
* @param {HTMLElement} element
|
|
303
305
|
*/
|
|
304
|
-
|
|
305
|
-
|
|
306
|
+
function duplicateMultilineNode (element) {
|
|
307
|
+
var className = element.className;
|
|
306
308
|
|
|
307
|
-
|
|
309
|
+
if ( ! /hljs-/.test(className)) return;
|
|
308
310
|
|
|
309
|
-
|
|
311
|
+
var lines = getLines(element.innerHTML);
|
|
310
312
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
313
|
+
for (var i = 0, result = ''; i < lines.length; i++) {
|
|
314
|
+
var lineText = lines[i].length > 0 ? lines[i] : ' ';
|
|
315
|
+
result += format('<span class="{0}">{1}</span>\n', [ className, lineText ]);
|
|
316
|
+
}
|
|
315
317
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
+
element.innerHTML = result.trim();
|
|
319
|
+
}
|
|
318
320
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
321
|
+
function getLines (text) {
|
|
322
|
+
if (text.length === 0) return [];
|
|
323
|
+
return text.split(BREAK_LINE_REGEXP);
|
|
324
|
+
}
|
|
323
325
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
326
|
+
function getLinesCount (text) {
|
|
327
|
+
return (text.trim().match(BREAK_LINE_REGEXP) || []).length;
|
|
328
|
+
}
|
|
327
329
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
330
|
+
///
|
|
331
|
+
/// HELPERS
|
|
332
|
+
///
|
|
331
333
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
334
|
+
function async (func) {
|
|
335
|
+
w.setTimeout(func, 0);
|
|
336
|
+
}
|
|
335
337
|
|
|
336
|
-
|
|
338
|
+
/**
|
|
337
339
|
* {@link https://wcoder.github.io/notes/string-format-for-string-formating-in-javascript}
|
|
338
340
|
* @param {string} format
|
|
339
341
|
* @param {array} args
|
|
340
342
|
*/
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
343
|
+
function format (format, args) {
|
|
344
|
+
return format.replace(/\{(\d+)\}/g, function(m, n){
|
|
345
|
+
return args[n] !== undefined ? args[n] : m;
|
|
346
|
+
});
|
|
347
|
+
}
|
|
346
348
|
|
|
347
|
-
|
|
349
|
+
/**
|
|
348
350
|
* @param {HTMLElement} element Code block.
|
|
349
351
|
* @param {String} attrName Attribute name.
|
|
350
352
|
* @returns {String} Attribute value or empty.
|
|
351
353
|
*/
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
354
|
+
function getAttribute (element, attrName) {
|
|
355
|
+
return element.hasAttribute(attrName) ? element.getAttribute(attrName) : null;
|
|
356
|
+
}
|
|
355
357
|
|
|
356
|
-
|
|
358
|
+
/**
|
|
357
359
|
* @param {String} str Source string.
|
|
358
360
|
* @param {Number} fallback Fallback value.
|
|
359
361
|
* @returns Parsed number or fallback value.
|
|
360
362
|
*/
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
363
|
+
function toNumber (str, fallback) {
|
|
364
|
+
if (!str) return fallback;
|
|
365
|
+
var number = Number(str);
|
|
366
|
+
return isFinite(number) ? number : fallback;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
}(window, document));
|