|
4 | 4 | return;
|
5 | 5 | }
|
6 | 6 |
|
7 |
| - var MATCH_ALL_CLASS = /(?:^|\s)match-braces(?:\s|$)/; |
8 |
| - |
9 |
| - var BRACE_HOVER_CLASS = /(?:^|\s)brace-hover(?:\s|$)/; |
10 |
| - var BRACE_SELECTED_CLASS = /(?:^|\s)brace-selected(?:\s|$)/; |
11 |
| - |
12 |
| - var NO_BRACE_HOVER_CLASS = /(?:^|\s)no-brace-hover(?:\s|$)/; |
13 |
| - var NO_BRACE_SELECT_CLASS = /(?:^|\s)no-brace-select(?:\s|$)/; |
14 |
| - |
15 | 7 | var PARTNER = {
|
16 | 8 | '(': ')',
|
17 | 9 | '[': ']',
|
18 | 10 | '{': '}',
|
19 | 11 | };
|
20 | 12 |
|
| 13 | + // The names for brace types. |
| 14 | + // These names have two purposes: 1) they can be used for styling and 2) they are used to pair braces. Only braces |
| 15 | + // of the same type are paired. |
21 | 16 | var NAMES = {
|
22 | 17 | '(': 'brace-round',
|
23 | 18 | '[': 'brace-square',
|
24 | 19 | '{': 'brace-curly',
|
25 | 20 | };
|
26 | 21 |
|
| 22 | + // A map for brace aliases. |
| 23 | + // This is useful for when some braces have a prefix/suffix as part of the punctuation token. |
| 24 | + var BRACE_ALIAS_MAP = { |
| 25 | + '${': '{', // JS template punctuation (e.g. `foo ${bar + 1}`) |
| 26 | + }; |
| 27 | + |
27 | 28 | var LEVEL_WARP = 12;
|
28 | 29 |
|
29 | 30 | var pairIdCounter = 0;
|
|
45 | 46 | * @this {HTMLElement}
|
46 | 47 | */
|
47 | 48 | function hoverBrace() {
|
48 |
| - for (var parent = this.parentElement; parent; parent = parent.parentElement) { |
49 |
| - if (NO_BRACE_HOVER_CLASS.test(parent.className)) { |
50 |
| - return; |
51 |
| - } |
| 49 | + if (!Prism.util.isActive(this, 'brace-hover', true)) { |
| 50 | + return; |
52 | 51 | }
|
53 | 52 |
|
54 |
| - [this, getPartnerBrace(this)].forEach(function (ele) { |
55 |
| - ele.className = (ele.className.replace(BRACE_HOVER_CLASS, ' ') + ' brace-hover').replace(/\s+/g, ' '); |
| 53 | + [this, getPartnerBrace(this)].forEach(function (e) { |
| 54 | + e.classList.add('brace-hover'); |
56 | 55 | });
|
57 | 56 | }
|
58 | 57 | /**
|
59 | 58 | * @this {HTMLElement}
|
60 | 59 | */
|
61 | 60 | function leaveBrace() {
|
62 |
| - [this, getPartnerBrace(this)].forEach(function (ele) { |
63 |
| - ele.className = ele.className.replace(BRACE_HOVER_CLASS, ' '); |
| 61 | + [this, getPartnerBrace(this)].forEach(function (e) { |
| 62 | + e.classList.remove('brace-hover'); |
64 | 63 | });
|
65 | 64 | }
|
66 | 65 | /**
|
67 | 66 | * @this {HTMLElement}
|
68 | 67 | */
|
69 | 68 | function clickBrace() {
|
70 |
| - for (var parent = this.parentElement; parent; parent = parent.parentElement) { |
71 |
| - if (NO_BRACE_SELECT_CLASS.test(parent.className)) { |
72 |
| - return; |
73 |
| - } |
| 69 | + if (!Prism.util.isActive(this, 'brace-select', true)) { |
| 70 | + return; |
74 | 71 | }
|
75 | 72 |
|
76 |
| - [this, getPartnerBrace(this)].forEach(function (ele) { |
77 |
| - ele.className = (ele.className.replace(BRACE_SELECTED_CLASS, ' ') + ' brace-selected').replace(/\s+/g, ' '); |
| 73 | + [this, getPartnerBrace(this)].forEach(function (e) { |
| 74 | + e.classList.add('brace-selected'); |
78 | 75 | });
|
79 | 76 | }
|
80 | 77 |
|
|
91 | 88 | // find the braces to match
|
92 | 89 | /** @type {string[]} */
|
93 | 90 | var toMatch = [];
|
94 |
| - for (var ele = code; ele; ele = ele.parentElement) { |
95 |
| - if (MATCH_ALL_CLASS.test(ele.className)) { |
96 |
| - toMatch.push('(', '[', '{'); |
97 |
| - break; |
98 |
| - } |
| 91 | + if (Prism.util.isActive(code, 'match-braces')) { |
| 92 | + toMatch.push('(', '[', '{'); |
99 | 93 | }
|
100 | 94 |
|
101 | 95 | if (toMatch.length == 0) {
|
|
108 | 102 | pre.addEventListener('mousedown', function removeBraceSelected() {
|
109 | 103 | // the code element might have been replaced
|
110 | 104 | var code = pre.querySelector('code');
|
111 |
| - Array.prototype.slice.call(code.querySelectorAll('.brace-selected')).forEach(function (element) { |
112 |
| - element.className = element.className.replace(BRACE_SELECTED_CLASS, ' '); |
| 105 | + Array.prototype.slice.call(code.querySelectorAll('.brace-selected')).forEach(function (e) { |
| 106 | + e.classList.remove('brace-selected'); |
113 | 107 | });
|
114 | 108 | });
|
115 | 109 | Object.defineProperty(pre, '__listenerAdded', { value: true });
|
|
134 | 128 | var element = punctuation[i];
|
135 | 129 | if (element.childElementCount == 0) {
|
136 | 130 | var text = element.textContent;
|
| 131 | + text = BRACE_ALIAS_MAP[text] || text; |
137 | 132 | if (text === open) {
|
138 | 133 | allBraces.push({ index: i, open: true, element: element });
|
139 |
| - element.className += ' ' + name; |
140 |
| - element.className += ' brace-open'; |
| 134 | + element.classList.add(name); |
| 135 | + element.classList.add('brace-open'); |
141 | 136 | openStack.push(i);
|
142 | 137 | } else if (text === close) {
|
143 | 138 | allBraces.push({ index: i, open: false, element: element });
|
144 |
| - element.className += ' ' + name; |
145 |
| - element.className += ' brace-close'; |
| 139 | + element.classList.add(name); |
| 140 | + element.classList.add('brace-close'); |
146 | 141 | if (openStack.length) {
|
147 | 142 | pairs.push([i, openStack.pop()]);
|
148 | 143 | }
|
|
153 | 148 | pairs.forEach(function (pair) {
|
154 | 149 | var pairId = 'pair-' + (pairIdCounter++) + '-';
|
155 | 150 |
|
156 |
| - var openEle = punctuation[pair[0]]; |
157 |
| - var closeEle = punctuation[pair[1]]; |
| 151 | + var opening = punctuation[pair[0]]; |
| 152 | + var closing = punctuation[pair[1]]; |
158 | 153 |
|
159 |
| - openEle.id = pairId + 'open'; |
160 |
| - closeEle.id = pairId + 'close'; |
| 154 | + opening.id = pairId + 'open'; |
| 155 | + closing.id = pairId + 'close'; |
161 | 156 |
|
162 |
| - [openEle, closeEle].forEach(function (ele) { |
163 |
| - ele.addEventListener('mouseenter', hoverBrace); |
164 |
| - ele.addEventListener('mouseleave', leaveBrace); |
165 |
| - ele.addEventListener('click', clickBrace); |
| 157 | + [opening, closing].forEach(function (e) { |
| 158 | + e.addEventListener('mouseenter', hoverBrace); |
| 159 | + e.addEventListener('mouseleave', leaveBrace); |
| 160 | + e.addEventListener('click', clickBrace); |
166 | 161 | });
|
167 | 162 | });
|
168 | 163 | });
|
|
171 | 166 | allBraces.sort(function (a, b) { return a.index - b.index; });
|
172 | 167 | allBraces.forEach(function (brace) {
|
173 | 168 | if (brace.open) {
|
174 |
| - brace.element.className += ' brace-level-' + (level % LEVEL_WARP + 1); |
| 169 | + brace.element.classList.add('brace-level-' + (level % LEVEL_WARP + 1)); |
175 | 170 | level++;
|
176 | 171 | } else {
|
177 | 172 | level = Math.max(0, level - 1);
|
178 |
| - brace.element.className += ' brace-level-' + (level % LEVEL_WARP + 1); |
| 173 | + brace.element.classList.add('brace-level-' + (level % LEVEL_WARP + 1)); |
179 | 174 | }
|
180 | 175 | });
|
181 |
| - |
182 | 176 | });
|
183 | 177 |
|
184 | 178 | }());
|
0 commit comments