UNPKG

jsaction

Version:

Google's event delegation library

92 lines (82 loc) 3.43 kB
/** * @fileoverview Public static API for using jsaction. */ goog.provide('jsaction'); goog.require('goog.asserts'); goog.require('jsaction.EventType'); goog.require('jsaction.dom'); /** * Create a custom event with the specified data. * @param {string} type The type of the action, e.g. 'submit'. * @param {!Object.<string, *>=} opt_data An optional data payload. * @param {!Event=} opt_triggeringEvent The event that triggers this custom * event. This can be accessed from the custom event's action flow like * so: actionFlow.event().detail.triggeringEvent. * @return {!Event} The new custom event. */ jsaction.createCustomEvent = function(type, opt_data, opt_triggeringEvent) { var event; // We use '_type' for the event contract, which lives in a separate // compilation unit, but also include the renamable keys so that event // consumers can access the data directly, e.g. detail.type instead of // detail['type']. var detail = { '_type': type, type: type, data: opt_data, triggeringEvent: opt_triggeringEvent }; try { // We don't use the CustomEvent constructor directly since it isn't // supported in IE 9 or 10 and initCustomEvent below works just fine. event = document.createEvent('CustomEvent'); event.initCustomEvent(jsaction.EventType.CUSTOM, true, false, detail); } catch (e) { // If custom events aren't supported, fall back to custom-named HTMLEvent. // Fallback used by Android Gingerbread, FF4-5. event = document.createEvent('HTMLEvents'); event.initEvent(jsaction.EventType.CUSTOM, true, false); event['detail'] = detail; } return event; }; /** * Fires a custom event with an optional payload. Only intended to be consumed * by jsaction itself. Supported in Firefox 6+, IE 9+, and all Chrome versions. * * TODO(user): Investigate polyfill options. * * @param {!Element} target The target element. * @param {string} type The type of the action, e.g. 'submit'. * @param {!Object.<string, *>=} opt_data An optional data payload. * @param {!Event=} opt_triggeringEvent An optional data for the Event triggered * this custom event. */ jsaction.fireCustomEvent = function( target, type, opt_data, opt_triggeringEvent) { var event = jsaction.createCustomEvent(type, opt_data, opt_triggeringEvent); target.dispatchEvent(event); }; /** * Fires a custom event at descendant elements. For a given descendant of the * target element, a custom event is fired if (1) it has a jsaction handler for * the action type, and (2) the element does not have an ancestor (also a * descendant of the target element) that already handled the event. * Supported wherever fireCustomEvent is supported. * * @param {!Element} target The target element. * @param {string} type The type of the action, e.g. 'submit'. Because of an * implementation detail, type may not be 'click'. * @param {!Object.<string, *>=} opt_data An optional data payload. */ jsaction.broadcastCustomEvent = function(target, type, opt_data) { goog.asserts.assert(type != 'click'); var matched = target.querySelectorAll('[jsaction^="' + type + ':"], ' + '[jsaction*=";' + type + ':"], [jsaction*=" ' + type + ':"]'); for (var i = 0; i < matched.length; ++i) { var match = matched[i]; if (!jsaction.dom.hasAncestorInNodeList(match, matched)) { jsaction.fireCustomEvent(match, type, opt_data); } } };