Skip to content

Commit 2b54e46

Browse files
committed
Make relevant events on textarea be transferred to code-input element completely
to support all kinds of handler, not just add/removeEventListener Passes hljs.html and prism.html tests in Firefox 140.0.2, Chromium 139.0.7258.138 and GNOME Web (WebKit) 48.5
1 parent e8fe914 commit 2b54e46

File tree

1 file changed

+19
-80
lines changed

1 file changed

+19
-80
lines changed

code-input.js

Lines changed: 19 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,8 @@ var codeInput = {
716716
// Synchronise attributes to textarea
717717
for(let i = 0; i < this.attributes.length; i++) {
718718
let attribute = this.attributes[i].name;
719-
if (codeInput.textareaSyncAttributes.includes(attribute) || attribute.substring(0, 5) == "aria-") {
719+
if (codeInput.textareaSyncAttributes.includes(attribute)
720+
|| attribute.substring(0, 5) == "aria-") {
720721
textarea.setAttribute(attribute, this.getAttribute(attribute));
721722
}
722723
}
@@ -726,6 +727,7 @@ var codeInput = {
726727
// Save element internally
727728
this.textareaElement = textarea;
728729
this.append(textarea);
730+
this.setupTextareaSyncEvents();
729731

730732
// Create result element
731733
let code = document.createElement("code");
@@ -855,7 +857,7 @@ var codeInput = {
855857
if (mutation.attributeName == codeInput.textareaSyncAttributes[i]) {
856858
return this.attributeChangedCallback(mutation.attributeName, mutation.oldValue, super.getAttribute(mutation.attributeName));
857859
}
858-
}
860+
}
859861
if (mutation.attributeName.substring(0, 5) == "aria-") {
860862
return this.attributeChangedCallback(mutation.attributeName, mutation.oldValue, super.getAttribute(mutation.attributeName));
861863
}
@@ -949,91 +951,28 @@ var codeInput = {
949951

950952
}
951953

952-
/* ------------------------------------
953-
* -----------Overrides----------------
954-
* ------------------------------------
955-
* Override/Implement ordinary HTML textarea functionality so that the <code-input>
956-
* element acts just like a <textarea>. */
957-
958-
/**
959-
* @override
960-
*/
961-
addEventListener(type, listener, options = undefined) {
962-
// Save a copy of the callback where `this` refers to the code-input element.
963-
let boundCallback = function (evt) {
964-
if (typeof listener === 'function') {
965-
listener(evt);
966-
} else if (listener && listener.handleEvent) {
967-
listener.handleEvent(evt);
968-
}
969-
}.bind(this);
970-
this.boundEventCallbacks[listener] = boundCallback;
971-
972-
if (codeInput.textareaSyncEvents.includes(type)) {
973-
// Synchronise with textarea
974-
this.boundEventCallbacks[listener] = boundCallback;
975-
976-
if (options === undefined) {
977-
if(this.textareaElement == null) {
978-
this.addEventListener("code-input_load", () => { this.textareaElement.addEventListener(type, boundCallback); });
979-
} else {
980-
this.textareaElement.addEventListener(type, boundCallback);
981-
}
982-
} else {
983-
if(this.textareaElement == null) {
984-
this.addEventListener("code-input_load", () => { this.textareaElement.addEventListener(type, boundCallback, options); });
985-
} else {
986-
this.textareaElement.addEventListener(type, boundCallback, options);
987-
}
988-
}
989-
} else {
990-
// Synchronise with code-input element
991-
if (options === undefined) {
992-
super.addEventListener(type, boundCallback);
993-
} else {
994-
super.addEventListener(type, boundCallback, options);
995-
}
996-
}
997-
}
954+
//-------------------------------------------
955+
//----------- Textarea interface ------------
956+
//-------------------------------------------
957+
// See https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement
958+
// Attributes defined at codeInput.textareaSyncAttributes
959+
// Event listener added to pass to code-input element
998960

999961
/**
1000-
* @override
962+
* Capture all events from textareaSyncEvents triggered on the textarea element
963+
* and pass them to the code-input element.
1001964
*/
1002-
removeEventListener(type, listener, options = undefined) {
1003-
// Save a copy of the callback where `this` refers to the code-input element
1004-
let boundCallback = this.boundEventCallbacks[listener];
1005-
1006-
if (codeInput.textareaSyncEvents.includes(type)) {
1007-
// Synchronise with textarea
1008-
if (options === undefined) {
1009-
if(this.textareaElement == null) {
1010-
this.addEventListener("code-input_load", () => { this.textareaElement.removeEventListener(type, boundCallback); });
1011-
} else {
1012-
this.textareaElement.removeEventListener(type, boundCallback);
965+
setupTextareaSyncEvents() {
966+
for(let i = 0; i < codeInput.textareaSyncEvents.length; i++) {
967+
const evtName = codeInput.textareaSyncEvents[i];
968+
this.textareaElement.addEventListener(evtName, (evt) => {
969+
if(!evt.bubbles) { // Don't duplicate the callback
970+
this.dispatchEvent(new evt.constructor(evt.type, evt)); // Thanks to
1013971
}
1014-
} else {
1015-
if(this.textareaElement == null) {
1016-
this.addEventListener("code-input_load", () => { this.textareaElement.removeEventListener(type, boundCallback, options); });
1017-
} else {
1018-
this.textareaElement.removeEventListener(type, boundCallback, options);
1019-
}
1020-
}
1021-
} else {
1022-
// Synchronise with code-input element
1023-
if (options === undefined) {
1024-
super.removeEventListener(type, boundCallback);
1025-
} else {
1026-
super.removeEventListener(type, boundCallback, options);
1027-
}
972+
});
1028973
}
1029974
}
1030975

1031-
//-------------------------------------------
1032-
//----------- Textarea interface ------------
1033-
//-------------------------------------------
1034-
// See https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement
1035-
// Attributes defined at codeInput.textareaSyncAttributes
1036-
1037976
/**
1038977
* Get the JavaScript property from the internal textarea
1039978
* element, given its name and a defaultValue to return

0 commit comments

Comments
 (0)