-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathcodeit-line-numbers.js
125 lines (95 loc) · 3.13 KB
/
codeit-line-numbers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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
(function () {
if (typeof Prism === 'undefined' || typeof document === 'undefined') {
return;
}
/**
* Plugin name which is used as a class name for <pre> which is activating the plugin
*
* @type {string}
*/
var PLUGIN_NAME = 'line-numbers';
/**
* Regular expression used for determining line breaks
*
* @type {RegExp}
*/
var NEW_LINE_EXP = /\n(?!$)/g;
/**
* Global exports
*/
var config = Prism.plugins.lineNumbers = {
/**
* Updates the line numbers of the given element.
*/
update: function (element) {
if (!element.textContent) {
return;
}
// only add line numbers if the element or one of its ancestors has the `line-numbers` class
if (!Prism.util.isActive(element, PLUGIN_NAME)) {
return;
}
var match = element.textContent.match(NEW_LINE_EXP);
var linesNum = match ? match.length + 1 : 1;
var lineNumbersWrapper = element.querySelector('.line-numbers-rows');
// if line numbers don't exist, create element
if (!lineNumbersWrapper) {
lineNumbersWrapper = document.createElement('span');
lineNumbersWrapper.setAttribute('aria-hidden', 'true');
lineNumbersWrapper.setAttribute('contenteditable', 'false');
lineNumbersWrapper.className = 'line-numbers-rows';
element.prepend(lineNumbersWrapper);
}
var lines = [...new Array(linesNum + 1).keys()].splice(1).join('\n');
// change padding of element according
// to number of lines
var lineNumberLength = 1.2; // em
var lineNumberPadding = (13.5 + 13.5); // px
if (linesNum < 100) { // 99 or less
lineNumberLength = 1.2;
} else if (linesNum < 1000) { // 999 or less
lineNumberLength = 1.8;
} else if (linesNum < 10000) { // 9999 or less
lineNumberLength = 2.4;
} else if (linesNum < 100000) { // 99999 or less
lineNumberLength = 3;
} else if (linesNum < 1000000) { // 999999 or less
lineNumberLength = 3.6;
} else if (linesNum < 10000000) { // 9999999 or less
lineNumberLength = 4.2;
} else if (linesNum < 100000000) { // 99999999 or less (10 million)
lineNumberLength = 4.8;
} else if (linesNum < 1000000000) { // 999999999 or less (1 billion)
lineNumberLength = 5.4;
} else if (linesNum < 10000000000) { // 9999999999 or less (10 billion lines)
lineNumberLength = 6;
} else { // all numbers above
lineNumberLength = linesNum.toString().length * 0.6;
}
// change padding of element
element.style.setProperty('--gutter-length', 'calc(' +
lineNumberLength + 'em' +
' + ' +
lineNumberPadding + 'px' +
')');
// add line numbers to HTML
lineNumbersWrapper.setAttribute('line-numbers', lines);
}
};
document.querySelectorAll('.' + PLUGIN_NAME).forEach(el => {
el.on('keydown', (e) => {
if (el.typed(e)) {
window.requestAnimationFrame(() => {
config.update(el);
});
};
});
});
Prism.hooks.add('complete', function (env) {
config.update(env.element);
});
Prism.hooks.add('line-numbers', function (env) {
env.plugins = env.plugins || {};
env.plugins.lineNumbers = true;
});
}());