{
  "version": 3,
  "sources": ["/cdn/shop/t/65/assets/delegate.js?cv=1.24.4"],
  "sourcesContent": ["/*jslint browser:true, node:true*/\n/*global define, Node*/\n\n/**\n * @preserve Create and manage a DOM event delegator.\n *\n * @version 0.1.3\n * @codingstandard ftlabs-jsv2\n * @copyright The Financial Times Limited [All Rights Reserved]\n * @license MIT License (see LICENSE.txt)\n */\n\n;(function(){\n\n\t'use strict';\n\n\t/**\n\t * DOM event delegator\n\t *\n\t * The delegator will listen\n\t * for events that bubble up\n\t * to the root node.\n\t *\n\t * @constructor\n\t * @param {Node|string} root The root node or a selector string matching the root node\n\t */\n\tfunction Delegate(root) {\n\t\tvar self = this;\n\n\t\tif (root) {\n\t\t\tthis.root(root);\n\t\t}\n\n\t\t/**\n\t\t * Maintain a map of listener\n\t\t * lists, keyed by event name.\n\t\t *\n\t\t * @type Object\n\t\t */\n\t\tthis.listenerMap = {};\n\n\t\t/** @type function() */\n\t\tthis.handle = function(event) { Delegate.prototype.handle.call(self, event); };\n\t}\n\n\t/**\n\t * @protected\n\t * @type ?boolean\n\t */\n\tDelegate.tagsCaseSensitive = null;\n\n\t/**\n\t * Start listening for events\n\t * on the provided DOM element\n\t *\n\t * @param  {Node} root The root node or a selector string matching the root node\n\t */\n\tDelegate.prototype.root = function(root) {\n\t\tvar listenerMap = this.listenerMap;\n\t\tvar eventType;\n\n\t\tif (typeof root === 'string') {\n\t\t\troot = document.querySelector(root);\n\t\t}\n\n\t\t// Remove master event listeners\n\t\tif (this.rootElement) {\n\t\t\tfor (eventType in listenerMap) {\n\t\t\t\tif (listenerMap.hasOwnProperty(eventType)) {\n\t\t\t\t\tthis.rootElement.removeEventListener(eventType, this.handle, this.captureForType(eventType));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If no root or root is not\n\t\t// a dom node, then remove internal\n\t\t// root reference and exit here\n\t\tif (!root || !root.addEventListener) {\n\t\t\tif (this.rootElement) {\n\t\t\t\tdelete this.rootElement;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * The root node at which\n\t\t * listeners are attached.\n\t\t *\n\t\t * @type Node\n\t\t */\n\t\tthis.rootElement = root;\n\n\t\t// Set up master event listeners\n\t\tfor (eventType in listenerMap) {\n\t\t\tif (listenerMap.hasOwnProperty(eventType)) {\n\t\t\t\tthis.rootElement.addEventListener(eventType, this.handle, this.captureForType(eventType));\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * @param {string} eventType\n\t * @returns boolean\n\t */\n\tDelegate.prototype.captureForType = function(eventType) {\n\t\treturn eventType === 'error';\n\t};\n\n\t/**\n\t * Attach a handler to one\n\t * event for all elements\n\t * that match the selector,\n\t * now or in the future\n\t *\n\t * The handler function receives\n\t * three arguments: the DOM event\n\t * object, the node that matched\n\t * the selector while the event\n\t * was bubbling and a reference\n\t * to itself. Within the handler,\n\t * 'this' is equal to the second\n\t * argument.\n\t *\n\t * The node that actually received\n\t * the event can be accessed via\n\t * 'event.target'.\n\t *\n\t * @param {string} eventType Listen for these events (in a space-separated list)\n\t * @param {string} selector Only handle events on elements matching this selector\n\t * @param {function()} handler Handler function - event data passed here will be in event.data\n\t * @param {Object} [eventData] Data to pass in event.data\n\t * @returns {Delegate} This method is chainable\n\t */\n\tDelegate.prototype.on = function(eventType, selector, handler, eventData) {\n\t\tvar root, listenerMap, matcher, matcherParam, self = this, /** @const */ SEPARATOR = ' ';\n\n\t\tif (!eventType) {\n\t\t\tthrow new TypeError('Invalid event type: ' + eventType);\n\t\t}\n\n\t\tif (!selector) {\n\t\t\tthrow new TypeError('Invalid selector: ' + selector);\n\t\t}\n\n\t\t// Support a separated list of event types\n\t\tif (eventType.indexOf(SEPARATOR) !== -1) {\n\t\t\teventType.split(SEPARATOR).forEach(function(singleEventType) {\n\t\t\t\tself.on(singleEventType, selector, handler, eventData);\n\t\t\t});\n\n\t\t\treturn this;\n\t\t}\n\n\t\t// Normalise undefined eventData to null\n\t\tif (eventData === undefined) {\n\t\t\teventData = null;\n\t\t}\n\n\t\tif (typeof handler !== 'function') {\n\t\t\tthrow new TypeError('Handler must be a type of Function');\n\t\t}\n\n\t\troot = this.rootElement;\n\t\tlistenerMap = this.listenerMap;\n\n\t\t// Add master handler for type if not created yet\n\t\tif (!listenerMap[eventType]) {\n\t\t\tif (root) {\n\t\t\t\troot.addEventListener(eventType, this.handle, this.captureForType(eventType));\n\t\t\t}\n\t\t\tlistenerMap[eventType] = [];\n\t\t}\n\n\t\t// Compile a matcher for the given selector\n\t\tif (/^[a-z]+$/i.test(selector)) {\n\n\t\t\t// Lazily check whether tag names are case sensitive (as in XML or XHTML documents).\n\t\t\tif (Delegate.tagsCaseSensitive === null) {\n\t\t\t\tDelegate.tagsCaseSensitive = document.createElement('i').tagName === 'i';\n\t\t\t}\n\n\t\t\tif (!Delegate.tagsCaseSensitive) {\n\t\t\t\tmatcherParam = selector.toUpperCase();\n\t\t\t} else {\n\t\t\t\tmatcherParam = selector;\n\t\t\t}\n\n\t\t\tmatcher = this.matchesTag;\n\t\t} else if (/^#[a-z0-9\\-_]+$/i.test(selector)) {\n\t\t\tmatcherParam = selector.slice(1);\n\t\t\tmatcher = this.matchesId;\n\t\t} else {\n\t\t\tmatcherParam = selector;\n\t\t\tmatcher = this.matches;\n\t\t}\n\n\t\t// Add to the list of listeners\n\t\tlistenerMap[eventType].push({\n\t\t\tselector: selector,\n\t\t\teventData: eventData,\n\t\t\thandler: handler,\n\t\t\tmatcher: matcher,\n\t\t\tmatcherParam: matcherParam\n\t\t});\n\n\t\treturn this;\n\t};\n\n\t/**\n\t * Remove an event handler\n\t * for elements that match\n\t * the selector, forever\n\t *\n\t * @param {string} eventType Remove handlers for events matching this type, considering the other parameters\n\t * @param {string} [selector] If this parameter is omitted, only handlers which match the other two will be removed\n\t * @param {function()} [handler] If this parameter is omitted, only handlers which match the previous two will be removed\n\t * @returns {Delegate} This method is chainable\n\t */\n\tDelegate.prototype.off = function(eventType, selector, handler) {\n\t\tvar i, listener, listenerMap, listenerList, singleEventType, self = this, /** @const */ SEPARATOR = ' ';\n\n\t\tlistenerMap = this.listenerMap;\n\t\tif (!eventType) {\n\t\t\tfor (singleEventType in listenerMap) {\n\t\t\t\tif (listenerMap.hasOwnProperty(singleEventType)) {\n\t\t\t\t\tthis.off(singleEventType, selector, handler);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\tlistenerList = listenerMap[eventType];\n\t\tif (!listenerList || !listenerList.length) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Support a separated list of event types\n\t\tif (eventType.indexOf(SEPARATOR) !== -1) {\n\t\t\teventType.split(SEPARATOR).forEach(function(singleEventType) {\n\t\t\t\tself.off(singleEventType, selector, handler);\n\t\t\t});\n\n\t\t\treturn this;\n\t\t}\n\n\t\t// Remove only parameter matches if specified\n\t\tfor (i = listenerList.length - 1; i >= 0; i--) {\n\t\t\tlistener = listenerList[i];\n\n\t\t\tif ((!selector || selector === listener.selector) && (!handler || handler === listener.handler)) {\n\t\t\t\tlistenerList.splice(i, 1);\n\t\t\t}\n\t\t}\n\n\t\t// All listeners removed\n\t\tif (!listenerList.length) {\n\t\t\tdelete listenerMap[eventType];\n\n\t\t\t// Remove the main handler\n\t\t\tif (this.rootElement) {\n\t\t\t\tthis.rootElement.removeEventListener(eventType, this.handle, this.captureForType(eventType));\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n\n\n\t/**\n\t * Handle an arbitrary event.\n\t *\n\t * @param {Event} event\n\t */\n\tDelegate.prototype.handle = function(event) {\n\t\tvar i, l, root, listener, returned, listenerList, target, /** @const */ EVENTIGNORE = 'ftLabsDelegateIgnore';\n\n\t\tif (event[EVENTIGNORE] === true) {\n\t\t\treturn;\n\t\t}\n\n\t\ttarget = event.target;\n\t\tif (target.nodeType === Node.TEXT_NODE) {\n\t\t\ttarget = target.parentNode;\n\t\t}\n\n\t\troot = this.rootElement;\n\t\tlistenerList = this.listenerMap[event.type];\n\n\t\t// Need to continuously check\n\t\t// that the specific list is\n\t\t// still populated in case one\n\t\t// of the callbacks actually\n\t\t// causes the list to be destroyed.\n\t\tl = listenerList.length;\n\t\twhile (target && l) {\n\t\t\tfor (i = 0; i < l; i++) {\n\t\t\t\tlistener = listenerList[i];\n\n\t\t\t\t// Bail from this loop if\n\t\t\t\t// the length changed and\n\t\t\t\t// no more listeners are\n\t\t\t\t// defined between i and l.\n\t\t\t\tif (!listener) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Check for match and fire\n\t\t\t\t// the event if there's one\n\t\t\t\t//\n\t\t\t\t// TODO:MCG:20120117: Need a way\n\t\t\t\t// to check if event#stopImmediateProgagation\n\t\t\t\t// was called. If so, break both loops.\n\t\t\t\tif (listener.matcher.call(target, listener.matcherParam, target)) {\n\t\t\t\t\treturned = this.fire(event, target, listener);\n\t\t\t\t}\n\n\t\t\t\t// Stop propagation to subsequent\n\t\t\t\t// callbacks if the callback returned\n\t\t\t\t// false\n\t\t\t\tif (returned === false) {\n\t\t\t\t\tevent[EVENTIGNORE] = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// TODO:MCG:20120117: Need a way to\n\t\t\t// check if event#stopProgagation\n\t\t\t// was called. If so, break looping\n\t\t\t// through the DOM. Stop if the\n\t\t\t// delegation root has been reached\n\t\t\tif (target === root) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tl = listenerList.length;\n\t\t\ttarget = target.parentElement;\n\t\t}\n\t};\n\n\t/**\n\t * Fire a listener on a target.\n\t *\n\t * @param {Event} event\n\t * @param {Node} target\n\t * @param {Object} listener\n\t * @returns {boolean}\n\t */\n\tDelegate.prototype.fire = function(event, target, listener) {\n\t\tvar returned, oldData;\n\n\t\tif (listener.eventData !== null) {\n\t\t\toldData = event.data;\n\t\t\tevent.data = listener.eventData;\n\t\t\treturned = listener.handler.call(target, event, target);\n\t\t\tevent.data = oldData;\n\t\t} else {\n\t\t\treturned = listener.handler.call(target, event, target);\n\t\t}\n\n\t\treturn returned;\n\t};\n\n\t/**\n\t * Check whether an element matches a generic selector.\n\t *\n\t * @type function()\n\t * @param {string} selector A CSS selector\n\t */\n\tDelegate.prototype.matches = (function(p) {\n\t\treturn (p.matchesSelector || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector);\n\t}(HTMLElement.prototype));\n\n\t/**\n\t * Check whether an element\n\t * matches a tag selector.\n\t *\n\t * Tags are NOT case-sensitive,\n\t * except in XML (and XML-based\n\t * languages such as XHTML).\n\t *\n\t * @param {string} tagName The tag name to test against\n\t * @param {Element} element The element to test with\n\t * @returns boolean\n\t */\n\tDelegate.prototype.matchesTag = function(tagName, element) {\n\t\treturn tagName === element.tagName;\n\t};\n\n\t/**\n\t * Check whether the ID of\n\t * the element in 'this'\n\t * matches the given ID.\n\t *\n\t * IDs are case-sensitive.\n\t *\n\t * @param {string} id The ID to test against\n\t * @param {Element} element The element to test with\n\t * @returns boolean\n\t */\n\tDelegate.prototype.matchesId = function(id, element) {\n\t\treturn id === element.id;\n\t};\n\n\t/**\n\t * Short hand for off()\n\t * and root(), ie both\n\t * with no parameters\n\t *\n\t * @return void\n\t */\n\tDelegate.prototype.destroy = function() {\n\t\tthis.off();\n\t\tthis.root();\n\t};\n\n\t/**\n\t * Expose `Delegate`\n\t */\n\n\tif (typeof module === \"object\") {\n\t  module.exports = function(root) {\n\t\t\treturn new Delegate(root);\n\t  };\n\t  module.exports.Delegate = Delegate;\n\t} else if (typeof define === \"function\" && define.amd) {\n\t  define(function() {\n\t\t\treturn Delegate;\n\t  });\n\t} else {\n\t\twindow.Delegate = Delegate;\n\t}\n\n})();"],
  "mappings": "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",
  "names": ["singleEventType"]
}
