1 | (function () {
|
2 |
|
3 | if (typeof self === 'undefined' || !self.Prism || !self.document || !document.querySelector) {
|
4 | return;
|
5 | }
|
6 |
|
7 | function $$(expr, con) {
|
8 | return Array.prototype.slice.call((con || document).querySelectorAll(expr));
|
9 | }
|
10 |
|
11 | function hasClass(element, className) {
|
12 | className = " " + className + " ";
|
13 | return (" " + element.className + " ").replace(/[\n\t]/g, " ").indexOf(className) > -1
|
14 | }
|
15 |
|
16 | function callFunction(func) {
|
17 | func();
|
18 | }
|
19 |
|
20 |
|
21 |
|
22 | var isLineHeightRounded = (function () {
|
23 | var res;
|
24 | return function () {
|
25 | if (typeof res === 'undefined') {
|
26 | var d = document.createElement('div');
|
27 | d.style.fontSize = '13px';
|
28 | d.style.lineHeight = '1.5';
|
29 | d.style.padding = 0;
|
30 | d.style.border = 0;
|
31 | d.innerHTML = ' <br /> ';
|
32 | document.body.appendChild(d);
|
33 |
|
34 |
|
35 | res = d.offsetHeight === 38;
|
36 | document.body.removeChild(d);
|
37 | }
|
38 | return res;
|
39 | }
|
40 | }());
|
41 |
|
42 | |
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 | function highlightLines(pre, lines, classes) {
|
54 | lines = typeof lines === 'string' ? lines : pre.getAttribute('data-line');
|
55 |
|
56 | var ranges = lines.replace(/\s+/g, '').split(',');
|
57 | var offset = +pre.getAttribute('data-line-offset') || 0;
|
58 |
|
59 | var parseMethod = isLineHeightRounded() ? parseInt : parseFloat;
|
60 | var lineHeight = parseMethod(getComputedStyle(pre).lineHeight);
|
61 | var hasLineNumbers = hasClass(pre, 'line-numbers');
|
62 | var parentElement = hasLineNumbers ? pre : pre.querySelector('code') || pre;
|
63 | var mutateActions = ([]);
|
64 |
|
65 | ranges.forEach(function (currentRange) {
|
66 | var range = currentRange.split('-');
|
67 |
|
68 | var start = +range[0];
|
69 | var end = +range[1] || start;
|
70 |
|
71 | var line = pre.querySelector('.line-highlight[data-range="' + currentRange + '"]') || document.createElement('div');
|
72 |
|
73 | mutateActions.push(function () {
|
74 | line.setAttribute('aria-hidden', 'true');
|
75 | line.setAttribute('data-range', currentRange);
|
76 | line.className = (classes || '') + ' line-highlight';
|
77 | });
|
78 |
|
79 |
|
80 | if (hasLineNumbers && Prism.plugins.lineNumbers) {
|
81 | var startNode = Prism.plugins.lineNumbers.getLine(pre, start);
|
82 | var endNode = Prism.plugins.lineNumbers.getLine(pre, end);
|
83 |
|
84 | if (startNode) {
|
85 | var top = startNode.offsetTop + 'px';
|
86 | mutateActions.push(function () {
|
87 | line.style.top = top;
|
88 | });
|
89 | }
|
90 |
|
91 | if (endNode) {
|
92 | var height = (endNode.offsetTop - startNode.offsetTop) + endNode.offsetHeight + 'px';
|
93 | mutateActions.push(function () {
|
94 | line.style.height = height;
|
95 | });
|
96 | }
|
97 | } else {
|
98 | mutateActions.push(function () {
|
99 | line.setAttribute('data-start', start);
|
100 |
|
101 | if (end > start) {
|
102 | line.setAttribute('data-end', end);
|
103 | }
|
104 |
|
105 | line.style.top = (start - offset - 1) * lineHeight + 'px';
|
106 |
|
107 | line.textContent = new Array(end - start + 2).join(' \n');
|
108 | });
|
109 | }
|
110 |
|
111 | mutateActions.push(function () {
|
112 |
|
113 |
|
114 | parentElement.appendChild(line);
|
115 | });
|
116 | });
|
117 |
|
118 | return function () {
|
119 | mutateActions.forEach(callFunction);
|
120 | };
|
121 | }
|
122 |
|
123 | function applyHash() {
|
124 | var hash = location.hash.slice(1);
|
125 |
|
126 |
|
127 | $$('.temporary.line-highlight').forEach(function (line) {
|
128 | line.parentNode.removeChild(line);
|
129 | });
|
130 |
|
131 | var range = (hash.match(/\.([\d,-]+)$/) || [, ''])[1];
|
132 |
|
133 | if (!range || document.getElementById(hash)) {
|
134 | return;
|
135 | }
|
136 |
|
137 | var id = hash.slice(0, hash.lastIndexOf('.')),
|
138 | pre = document.getElementById(id);
|
139 |
|
140 | if (!pre) {
|
141 | return;
|
142 | }
|
143 |
|
144 | if (!pre.hasAttribute('data-line')) {
|
145 | pre.setAttribute('data-line', '');
|
146 | }
|
147 |
|
148 | var mutateDom = highlightLines(pre, range, 'temporary ');
|
149 | mutateDom();
|
150 |
|
151 | document.querySelector('.temporary.line-highlight').scrollIntoView();
|
152 | }
|
153 |
|
154 | var fakeTimer = 0;
|
155 |
|
156 | Prism.hooks.add('before-sanity-check', function (env) {
|
157 | var pre = env.element.parentNode;
|
158 | var lines = pre && pre.getAttribute('data-line');
|
159 |
|
160 | if (!pre || !lines || !/pre/i.test(pre.nodeName)) {
|
161 | return;
|
162 | }
|
163 |
|
164 | |
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 | var num = 0;
|
172 | $$('.line-highlight', pre).forEach(function (line) {
|
173 | num += line.textContent.length;
|
174 | line.parentNode.removeChild(line);
|
175 | });
|
176 |
|
177 | if (num && /^( \n)+$/.test(env.code.slice(-num))) {
|
178 | env.code = env.code.slice(0, -num);
|
179 | }
|
180 | });
|
181 |
|
182 | Prism.hooks.add('complete', function completeHook(env) {
|
183 | var pre = env.element.parentNode;
|
184 | var lines = pre && pre.getAttribute('data-line');
|
185 |
|
186 | if (!pre || !lines || !/pre/i.test(pre.nodeName)) {
|
187 | return;
|
188 | }
|
189 |
|
190 | clearTimeout(fakeTimer);
|
191 |
|
192 | var hasLineNumbers = Prism.plugins.lineNumbers;
|
193 | var isLineNumbersLoaded = env.plugins && env.plugins.lineNumbers;
|
194 |
|
195 | if (hasClass(pre, 'line-numbers') && hasLineNumbers && !isLineNumbersLoaded) {
|
196 | Prism.hooks.add('line-numbers', completeHook);
|
197 | } else {
|
198 | var mutateDom = highlightLines(pre, lines);
|
199 | mutateDom();
|
200 | fakeTimer = setTimeout(applyHash, 1);
|
201 | }
|
202 | });
|
203 |
|
204 | window.addEventListener('hashchange', applyHash);
|
205 | window.addEventListener('resize', function () {
|
206 | var actions = [];
|
207 | $$('pre[data-line]').forEach(function (pre) {
|
208 | actions.push(highlightLines(pre));
|
209 | });
|
210 | actions.forEach(callFunction);
|
211 | });
|
212 |
|
213 | })();
|