diff --git a/code-input.js b/code-input.js index 4c9bb67..b0458bc 100644 --- a/code-input.js +++ b/code-input.js @@ -864,26 +864,32 @@ var codeInput = { */ addEventListener(type, listener, options = undefined) { // Save a copy of the callback where `this` refers to the code-input element. - // This callback is modified to only run when the handleEventsFromTextarea is set. - let boundCallback = function(evt) { listener(evt); }.bind(this); + let boundCallback = function (evt) { + if (typeof listener === 'function') { + listener(evt); + } else if (listener && listener.handleEvent) { + listener.handleEvent(evt); + } + }.bind(this); this.boundEventCallbacks[listener] = boundCallback; if (codeInput.textareaSyncEvents.includes(type)) { // Synchronise with textarea, only when handleEventsFromTextarea is true - let boundCallback = function(evt) { if(this.handleEventsFromTextarea) listener(evt); }.bind(this); - this.boundEventCallbacks[listener] = boundCallback; + // This callback is modified to only run when the handleEventsFromTextarea is set. + let conditionalBoundCallback = function(evt) { if(this.handleEventsFromTextarea) boundCallback(evt); }.bind(this); + this.boundEventCallbacks[listener] = conditionalBoundCallback; if (options === undefined) { if(this.textareaElement == null) { this.addEventListener("code-input_load", () => { this.textareaElement.addEventListener(type, boundCallback); }); } else { - this.textareaElement.addEventListener(type, boundCallback); + this.textareaElement.addEventListener(type, conditionalBoundCallback); } } else { if(this.textareaElement == null) { this.addEventListener("code-input_load", () => { this.textareaElement.addEventListener(type, boundCallback, options); }); } else { - this.textareaElement.addEventListener(type, boundCallback, options); + this.textareaElement.addEventListener(type, conditionalBoundCallback, options); } } } else { @@ -1041,4 +1047,4 @@ var codeInput = { } } -customElements.define("code-input", codeInput.CodeInput); \ No newline at end of file +customElements.define("code-input", codeInput.CodeInput); diff --git a/tests/tester.js b/tests/tester.js index cf33f5b..82b0f06 100644 --- a/tests/tester.js +++ b/tests/tester.js @@ -210,17 +210,21 @@ console.log("I've got another line!", 2 < 3, "should be true.");`); console.log("I've got another line!", 2 < 3, "should be true."); `); // Extra newline so line numbers visible if enabled - // Event Tests + // Event Listener Tests + // Function type listeners let numTimesInputCalled = 0; let numTimesChangeCalled = 0; - codeInputElement.addEventListener("input", (evt) => { + + let inputListener = (evt) => { if(!evt.isTrusted) { // To prevent duplicate calling due to allowInputEvents hack numTimesInputCalled++; } - }); - codeInputElement.addEventListener("change", () => { + }; + codeInputElement.addEventListener("input", inputListener); + let changeListener = () => { numTimesChangeCalled++; - }); + }; + codeInputElement.addEventListener("change", changeListener); let inputDeletedListenerCalled = false; let deletedListener = () => { @@ -235,9 +239,41 @@ console.log("I've got another line!", 2 < 3, "should be true."); textarea.blur(); // Unfocus textarea - calls change event textarea.focus(); - assertEqual("Core", "Input Event Listener Called Right Number of Times", numTimesInputCalled, 6); - assertEqual("Core", "Change Event Listener Called Right Number of Times", numTimesChangeCalled, 1); - testAssertion("Core", "Input Event Removed Listener Not Called", !inputDeletedListenerCalled, "(code-input element).removeEventListener did not work."); + assertEqual("Core", "Function Event Listeners: Input Called Right Number of Times", numTimesInputCalled, 6); + assertEqual("Core", "Function Event Listeners: Change Called Right Number of Times", numTimesChangeCalled, 1); + testAssertion("Core", "Function Event Listeners: Input Removed Listener Not Called", !inputDeletedListenerCalled, "(code-input element).removeEventListener did not work."); + + codeInputElement.removeEventListener("input", inputListener); + codeInputElement.removeEventListener("change", changeListener); + + // Repeat for Object type listeners + numTimesInputCalled = 0; + numTimesChangeCalled = 0; + codeInputElement.addEventListener("input", {handleEvent: (evt) => { + if(!evt.isTrusted) { // To prevent duplicate calling due to allowInputEvents hack + numTimesInputCalled++; + } + }}); + codeInputElement.addEventListener("change", {handleEvent: () => { + numTimesChangeCalled++; + }}); + + inputDeletedListenerCalled = false; + deletedListener = {handleEvent: () => { + inputDeletedListenerCalled = true; + }}; + codeInputElement.addEventListener("input", deletedListener); + codeInputElement.removeEventListener("input", deletedListener); + + // Make listeners be called + textarea.focus(); // Focus textarea + addText(textarea, " // Hi"); + textarea.blur(); // Unfocus textarea - calls change event + textarea.focus(); + + assertEqual("Core", "Object Event Listeners: Input Called Right Number of Times", numTimesInputCalled, 6); + assertEqual("Core", "Object Event Listeners: Change Called Right Number of Times", numTimesChangeCalled, 1); + testAssertion("Core", "Object Event Listeners: Input Removed Listener Not Called", !inputDeletedListenerCalled, "(code-input element).removeEventListener did not work."); // Changing language should be correct if(!isHLJS) {