From 09b9e93f29a7ec7a5282fe9deb2a750d9e48f8f4 Mon Sep 17 00:00:00 2001 From: Michael Best Date: Thu, 28 May 2015 16:42:42 -1000 Subject: [PATCH] Change preferJQueryEvents to useOnlyNativeEvents; fix and expand related tests. --- spec/utilsDomBehaviors.js | 62 +++++++++++++++++++++++++++++---------- src/options.js | 2 +- src/utils.js | 4 +-- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/spec/utilsDomBehaviors.js b/spec/utilsDomBehaviors.js index a3fda6eb1..b6f6499cd 100644 --- a/spec/utilsDomBehaviors.js +++ b/spec/utilsDomBehaviors.js @@ -31,29 +31,59 @@ describe('setTextContent', function () { }); describe('registerEventHandler', function() { - it ('should not use jQuery eventing with preferJQueryEvents option set to false', function() { - var jQueryLoaded = (typeof jQuery !== 'undefined'); + it ('if jQuery is referenced, should use jQuery eventing with useOnlyNativeEvents option set to false', function() { + if (typeof jQuery === 'undefined') { + return; // Nothing to test. Run the specs with jQuery referenced for this to do anything. + } + + this.restoreAfter(ko.options, 'useOnlyNativeEvents'); + var element = document.createElement('DIV'); var eventFired = false; - var jQueryUsed = false; + var jQueryModified = false; // Set the option to true. - ko.options.preferJQueryEvents = false; - - // If jQuery is present, verify jQuery is not used in event binding. - if (jQueryLoaded) { - ko.utils.registerEventHandler(element, 'click', function(eventArgs) { - eventFired = true; - jQueryUsed = !!eventArgs.originalEvent; - }); - } + ko.options.useOnlyNativeEvents = false; - // Trigger the event. + // Verify jQuery is used in event binding. + ko.utils.registerEventHandler(element, 'click', function(eventArgs) { + eventFired = true; + jQueryModified = !!eventArgs.originalEvent; + }); + + // Trigger the event natively (jQuery intercepts and creates new event object, which we can test) + element.click(); + expect(eventFired && jQueryModified).toBe(true); + + // Also trigger an event through ko.utils.triggerEvent to show that it creates a jQuery event directly + eventFired = jQueryModified = false; ko.utils.triggerEvent(element, 'click'); + expect(eventFired && !jQueryModified).toBe(true); + }); - // Reset the option. - ko.options.preferJQueryEvents = true; + it ('should not use jQuery eventing with useOnlyNativeEvents option set to true', function() { + this.restoreAfter(ko.options, 'useOnlyNativeEvents'); - expect(!jQueryLoaded || (eventFired && !jQueryUsed)).toBe(true); + var element = document.createElement('DIV'); + var eventFired = false; + var jQueryModified = false; + + // Set the option to true. + ko.options.useOnlyNativeEvents = true; + + // Verify jQuery is not used in event binding. + ko.utils.registerEventHandler(element, 'click', function(eventArgs) { + eventFired = true; + jQueryModified = !!eventArgs.originalEvent; + }); + + // Trigger the event natively + element.click(); + expect(eventFired && !jQueryModified).toBe(true); + + // Also trigger an event through ko.utils.triggerEvent to show that it triggers a native event + eventFired = jQueryModified = false; + ko.utils.triggerEvent(element, 'click'); + expect(eventFired && !jQueryModified).toBe(true); }); }); diff --git a/src/options.js b/src/options.js index b37c38af3..73b8f91bb 100644 --- a/src/options.js +++ b/src/options.js @@ -1,7 +1,7 @@ // For any options that may affect various areas of Knockout and aren't directly associated with data binding. ko.options = { 'deferUpdates': false, - 'preferJQueryEvents': true + 'useOnlyNativeEvents': false }; //ko.exportSymbol('options', ko.options); // 'options' isn't minified diff --git a/src/utils.js b/src/utils.js index bbf7aee7e..7c117e3a8 100644 --- a/src/utils.js +++ b/src/utils.js @@ -361,7 +361,7 @@ ko.utils = (function () { var wrappedHandler = ko.utils.catchFunctionErrors(handler); var mustUseAttachEvent = ieVersion && eventsThatMustBeRegisteredUsingAttachEvent[eventType]; - if (ko.options['preferJQueryEvents'] && !mustUseAttachEvent && jQueryInstance) { + if (!ko.options['useOnlyNativeEvents'] && !mustUseAttachEvent && jQueryInstance) { jQueryInstance(element)['bind'](eventType, wrappedHandler); } else if (!mustUseAttachEvent && typeof element.addEventListener == "function") element.addEventListener(eventType, wrappedHandler, false); @@ -389,7 +389,7 @@ ko.utils = (function () { // In both cases, we'll use the click method instead. var useClickWorkaround = isClickOnCheckableElement(element, eventType); - if (ko.options['preferJQueryEvents'] && jQueryInstance && !useClickWorkaround) { + if (!ko.options['useOnlyNativeEvents'] && jQueryInstance && !useClickWorkaround) { jQueryInstance(element)['trigger'](eventType); } else if (typeof document.createEvent == "function") { if (typeof element.dispatchEvent == "function") {