|
3 | 3 | // Based on a CSS-Tricks Post
|
4 | 4 |
|
5 | 5 | var codeInput = {
|
6 |
| - observedAttributes: [ |
| 6 | + observedAttributes: [ // Doesn't include events, as they are transferred by overriding {add/remove}EventListener |
7 | 7 | "value",
|
8 | 8 | "name",
|
9 | 9 | "placeholder",
|
10 | 10 | "lang",
|
11 |
| - "template", |
12 |
| - "onchange", |
13 |
| - "onselectionchange" |
| 11 | + "template" |
14 | 12 | ],
|
15 | 13 | // Attributes to monitor - needs to be global and static
|
16 | 14 |
|
@@ -50,7 +48,7 @@ var codeInput = {
|
50 | 48 | super(); // Element
|
51 | 49 | }
|
52 | 50 |
|
53 |
| - last_events = {}; // Last events applied; removed when changed so can be added to textarea, etc. |
| 51 | + bound_callbacks = {}; // Callback without this context > Callback with forced codeInput elem this |
54 | 52 |
|
55 | 53 | /* Run this event in all plugins with a optional list of arguments */
|
56 | 54 | plugin_evt(id, args) {
|
@@ -178,12 +176,6 @@ var codeInput = {
|
178 | 176 |
|
179 | 177 | this.plugin_evt("afterElementsAdded");
|
180 | 178 |
|
181 |
| - // Events |
182 |
| - textarea = this.querySelector("textarea"); |
183 |
| - // Add event listeners, bound so `this` can be referenced |
184 |
| - this.transfer_event("change", this.querySelector("textarea"), null, this.onchange); |
185 |
| - this.transfer_event("selectionchange", this.querySelector("textarea"), null, this.onselectionchange); |
186 |
| - |
187 | 179 | /* Add code from value attribute - useful for loading from backend */
|
188 | 180 | this.update(value, this);
|
189 | 181 | }
|
@@ -261,29 +253,57 @@ var codeInput = {
|
261 | 253 | this.update(this.value);
|
262 | 254 |
|
263 | 255 | break;
|
264 |
| - |
265 |
| - // Events |
266 |
| - case "onchange": |
267 |
| - this.transfer_event("change", this.querySelector("textarea"), oldValue, newValue); |
268 |
| - break; |
269 |
| - case "onselectionchange": |
270 |
| - this.transfer_event("selectionchange", this.querySelector("textarea"), oldValue, newValue); |
271 |
| - break; |
272 | 256 | }
|
273 | 257 | }
|
274 | 258 |
|
275 | 259 | }
|
276 | 260 |
|
277 |
| - /* Transfer an event by name from this to an inner element. */ |
278 |
| - transfer_event(evt_name, transfer_to, oldValue, newValue) { |
279 |
| - // Doesn't exist |
280 |
| - if(oldValue) { |
281 |
| - transfer_to.removeEventListener(evt_name, this.last_events[evt_name]); |
| 261 | + // /* Transfer an event by name from this to an inner element. */ |
| 262 | + // transfer_event(evt_name, transfer_to, oldValue, newValue) { |
| 263 | + // if(oldValue) { // Remove old listener |
| 264 | + // transfer_to.removeEventListener(evt_name, this.last_events[evt_name]); |
| 265 | + // } |
| 266 | + // if(newValue) { |
| 267 | + // this.last_events[evt_name] = this[`on${evt_name}`].bind(this); |
| 268 | + // transfer_to.addEventListener(evt_name, this.last_events[evt_name]); |
| 269 | + // this.removeEventListener(evt_name, newValue); |
| 270 | + // } |
| 271 | + // } |
| 272 | + |
| 273 | + /* Override addEventListener so event listener added to necessary child. Returns callback bound to code-input element as `this` */ |
| 274 | + addEventListener(evt_name, callback, thirdParameter=null) { |
| 275 | + let boundCallback = callback.bind(this); |
| 276 | + this.bound_callbacks[callback] = boundCallback; |
| 277 | + if(evt_name == "change") { |
| 278 | + if(thirdParameter === null) { |
| 279 | + this.querySelector("textarea").addEventListener("change", boundCallback); |
| 280 | + } else { |
| 281 | + this.querySelector("textarea").addEventListener("change", boundCallback, thirdParameter); |
| 282 | + } |
| 283 | + } else if(evt_name == "selectionchange") { |
| 284 | + if(thirdParameter === null) { |
| 285 | + this.querySelector("textarea").addEventListener("selectionchange", boundCallback); |
| 286 | + } else { |
| 287 | + this.querySelector("textarea").addEventListener("selectionchange", boundCallback, thirdParameter); |
| 288 | + } |
282 | 289 | }
|
283 |
| - if(newValue) { |
284 |
| - this.last_events[evt_name] = this.onchange.bind(this); |
285 |
| - transfer_to.addEventListener(evt_name, this.last_events[evt_name]); |
286 |
| - this[`on${evt_name}`] = undefined; // Prevent duplicate |
| 290 | + } |
| 291 | + |
| 292 | + /* Override removeEventListener so event listener removed from necessary child */ |
| 293 | + removeEventListener(evt_name, callback, thirdParameter=null) { |
| 294 | + let boundCallback = this.bound_callbacks[callback]; |
| 295 | + if(evt_name == "change") { |
| 296 | + if(thirdParameter === null) { |
| 297 | + this.querySelector("textarea").removeEventListener("change", boundCallback); |
| 298 | + } else { |
| 299 | + this.querySelector("textarea").removeEventListener("change", boundCallback, thirdParameter); |
| 300 | + } |
| 301 | + } else if(evt_name == "selectionchange") { |
| 302 | + if(thirdParameter === null) { |
| 303 | + this.querySelector("textarea").removeEventListener("selectionchange", boundCallback); |
| 304 | + } else { |
| 305 | + this.querySelector("textarea").removeEventListener("selectionchange", boundCallback, thirdParameter); |
| 306 | + } |
287 | 307 | }
|
288 | 308 | }
|
289 | 309 |
|
|
0 commit comments