From 79e08f032dfac30fd663b8a510242eee4795da57 Mon Sep 17 00:00:00 2001 From: Chasen Le Hara Date: Mon, 12 Mar 2018 12:29:57 -0700 Subject: [PATCH] Add helper for listening to jQuery events This helper can be used when another module registers $.event.special events and you need to listen to those events with can-dom-events. --- can-dom-events-test.js | 1 + helpers/add-jquery-events-test.js | 36 +++++++++++++++++ helpers/add-jquery-events.js | 65 +++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 helpers/add-jquery-events-test.js create mode 100644 helpers/add-jquery-events.js diff --git a/can-dom-events-test.js b/can-dom-events-test.js index 33a510c..1629b09 100644 --- a/can-dom-events-test.js +++ b/can-dom-events-test.js @@ -163,4 +163,5 @@ unit.test('domEvents.addDelegateListener handles document correctly', function ( require('./helpers/make-event-registry-test'); require('./helpers/add-event-compat-test'); require('./helpers/add-event-jquery-test'); +require('./helpers/add-jquery-events-test'); require('./helpers/util-test'); diff --git a/helpers/add-jquery-events-test.js b/helpers/add-jquery-events-test.js new file mode 100644 index 0000000..2a6010e --- /dev/null +++ b/helpers/add-jquery-events-test.js @@ -0,0 +1,36 @@ +var unit = require('steal-qunit'); +var $ = require('jquery'); +var addEvents = require('./add-jquery-events'); +var domEvents = require('../can-dom-events'); + +unit.module('add-jquery-events'); + +unit.test('should work with the jQuery', function (assert) { + assert.expect(1 + 3); + + var divElement = document.createElement('div'); + + var eventType = 'draginit'; + var handler = function (event) { + assert.equal(event.target, divElement, 'div should be the target'); + assert.equal(event.type, eventType, 'event type should match custom event type'); + assert.equal(event.handleObj.handler, handler, 'callback should be the passed handler'); + }; + + // Set up the special event + $.event.special[eventType] = { + add: function() { + assert.ok(true, 'add handler should be called'); + } + }; + + // Bridge can-dom-events + jQuery + var removeEvents = addEvents($); + + // Listen to and trigger the event; handler should run + domEvents.addEventListener(divElement, eventType, handler); + $(divElement).trigger(eventType); + + // Clean up after ourselves :) + removeEvents(); +}); diff --git a/helpers/add-jquery-events.js b/helpers/add-jquery-events.js new file mode 100644 index 0000000..5ebb8b9 --- /dev/null +++ b/helpers/add-jquery-events.js @@ -0,0 +1,65 @@ +'use strict'; + +var domEvents = require('../can-dom-events'); +var namespace = require('can-namespace'); + +/** + * @function can-dom-events/helpers/add-jquery-events ./helpers/add-jquery-events + * @parent can-dom-events.helpers + * @description Add jQuery’s special events to the global registry. + * @signature `addJQueryEvents(jQuery)` + * @param {jQuery} jQuery Your instance of jQuery. + * @return {function} The callback to remove the jQuery events from the registry. + * + * @body + * + * ```js + * const $ = require("jquery"); + * const addJQueryEvents = require("can-dom-events/helpers/add-jquery-events"); + * const domEvents = require("can-dom-events"); + * // Require another module that registers itself with jQuery.event.special, + * // e.g. jQuery++ registers events such as draginit, dragmove, etc. + * + * const removeJQueryEvents = addJQueryEvents($); + * + * // Listen for an event in code; this might also be accomplished through a + * // can-stache-binding such as
  • + * domEvents.addEventListener(listItemElement, "draginit", function listener() { + * // Will fire after a jQuery draginit event has been fired + * }); + * + * // Some other code that fires a jQuery event; this will probably be in the + * // package you’re using… + * $(listItemElement).trigger("draginit"); + * + * // Later in your code… ready to stop listening for those jQuery events? Call + * // the function returned by addJQueryEvents() + * removeJQueryEvents(); + * ``` + */ +module.exports = namespace.addJQueryEvents = function addJQueryEvents(jQuery) { + var jQueryEvents = jQuery.event.special; + var removeEvents = []; + + for (var eventType in jQueryEvents) { + if (!domEvents._eventRegistry.has(eventType)) { + var eventDefinition = { + defaultEventType: eventType, + addEventListener: function (target, eventType, handler) { + $(target).on(eventType, handler); + }, + removeEventListener: function (target, eventType, handler) { + $(target).off(eventType, handler); + } + }; + var removeEvent = domEvents.addEvent(eventDefinition); + removeEvents.push(removeEvent); + } + } + + return function removeJQueryEvents() { + removeEvents.forEach(function(removeEvent) { + removeEvent(); + }); + }; +};