|
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