diff --git a/bower.json b/bower.json
index abb1b41..9048ece 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
{
"name": "senna",
- "version": "1.2.0",
+ "version": "1.3.0",
"description": "A blazing-fast Single Page Application engine",
"homepage": "http://sennajs.com",
"authors": [
diff --git a/build/amd/metal-dom/src/DomDelegatedEventHandle.js b/build/amd/metal-dom/src/DomDelegatedEventHandle.js
new file mode 100644
index 0000000..f4a9f96
--- /dev/null
+++ b/build/amd/metal-dom/src/DomDelegatedEventHandle.js
@@ -0,0 +1,90 @@
+define(['exports', 'metal/src/metal', './metalData', 'metal-events/src/events'], function (exports, _metal, _metalData, _events) {
+ 'use strict';
+
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+
+ var _metalData2 = _interopRequireDefault(_metalData);
+
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : {
+ default: obj
+ };
+ }
+
+ function _classCallCheck(instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+ }
+
+ function _possibleConstructorReturn(self, call) {
+ if (!self) {
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+ }
+
+ return call && (typeof call === "object" || typeof call === "function") ? call : self;
+ }
+
+ function _inherits(subClass, superClass) {
+ if (typeof superClass !== "function" && superClass !== null) {
+ throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
+ }
+
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
+ constructor: {
+ value: subClass,
+ enumerable: false,
+ writable: true,
+ configurable: true
+ }
+ });
+ if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
+ }
+
+ var DomDelegatedEventHandle = function (_EventHandle) {
+ _inherits(DomDelegatedEventHandle, _EventHandle);
+
+ /**
+ * The constructor for `DomDelegatedEventHandle`.
+ * @param {!Event} emitter Element the event was subscribed to.
+ * @param {string} event The name of the event that was subscribed to.
+ * @param {!Function} listener The listener subscribed to the event.
+ * @param {string=} opt_selector An optional selector used when delegating
+ * the event.
+ * @constructor
+ */
+
+ function DomDelegatedEventHandle(emitter, event, listener, opt_selector) {
+ _classCallCheck(this, DomDelegatedEventHandle);
+
+ var _this = _possibleConstructorReturn(this, _EventHandle.call(this, emitter, event, listener));
+
+ _this.selector_ = opt_selector;
+ return _this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+
+
+ DomDelegatedEventHandle.prototype.removeListener = function removeListener() {
+ var data = _metalData2.default.get(this.emitter_);
+ var selector = this.selector_;
+ var arr = _metal.core.isString(selector) ? data.delegating[this.event_].selectors : data.listeners;
+ var key = _metal.core.isString(selector) ? selector : this.event_;
+
+ _metal.array.remove(arr[key] || [], this.listener_);
+ if (arr[key] && arr[key].length === 0) {
+ delete arr[key];
+ }
+ };
+
+ return DomDelegatedEventHandle;
+ }(_events.EventHandle);
+
+ exports.default = DomDelegatedEventHandle;
+});
+//# sourceMappingURL=DomDelegatedEventHandle.js.map
\ No newline at end of file
diff --git a/build/amd/metal-dom/src/DomDelegatedEventHandle.js.map b/build/amd/metal-dom/src/DomDelegatedEventHandle.js.map
new file mode 100644
index 0000000..78418ce
--- /dev/null
+++ b/build/amd/metal-dom/src/DomDelegatedEventHandle.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["DomDelegatedEventHandle.js"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAWM,uB;;;;;;;;;;;;;AAUL,mCAAY,OAAZ,EAAqB,KAArB,EAA4B,QAA5B,EAAsC,YAAtC,EAAoD;AAAA;;AAAA,gDACnD,wBAAM,OAAN,EAAe,KAAf,EAAsB,QAAtB,CADmD;;AAEnD,SAAK,SAAL,GAAiB,YAAjB;AAFmD;AAGnD;;;;;;;oCAKD,c,6BAAiB;AAChB,OAAI,OAAO,oBAAU,GAAV,CAAc,KAAK,QAAnB,CAAX;AACA,OAAI,WAAW,KAAK,SAApB;AACA,OAAI,MAAM,YAAK,QAAL,CAAc,QAAd,IAA0B,KAAK,UAAL,CAAgB,KAAK,MAArB,EAA6B,SAAvD,GAAmE,KAAK,SAAlF;AACA,OAAI,MAAM,YAAK,QAAL,CAAc,QAAd,IAA0B,QAA1B,GAAqC,KAAK,MAApD;;AAEA,gBAAM,MAAN,CAAa,IAAI,GAAJ,KAAY,EAAzB,EAA6B,KAAK,SAAlC;AACA,OAAI,IAAI,GAAJ,KAAY,IAAI,GAAJ,EAAS,MAAT,KAAoB,CAApC,EAAuC;AACtC,WAAO,IAAI,GAAJ,CAAP;AACA;AACD,G;;;;;mBAGa,uB","file":"node_modules/metal-dom/src/DomDelegatedEventHandle.js","sourcesContent":["'use strict';\n\nimport { array, core } from 'metal';\nimport metalData from './metalData';\nimport { EventHandle } from 'metal-events';\n\n/**\n * This is a special EventHandle, that is responsible for dom delegated events\n * (only the ones that receive a target element, not a selector string).\n * @extends {EventHandle}\n */\nclass DomDelegatedEventHandle extends EventHandle {\n\t/**\n\t * The constructor for `DomDelegatedEventHandle`.\n\t * @param {!Event} emitter Element the event was subscribed to.\n\t * @param {string} event The name of the event that was subscribed to.\n\t * @param {!Function} listener The listener subscribed to the event.\n\t * @param {string=} opt_selector An optional selector used when delegating\n\t * the event.\n\t * @constructor\n\t */\n\tconstructor(emitter, event, listener, opt_selector) {\n\t\tsuper(emitter, event, listener);\n\t\tthis.selector_ = opt_selector;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tremoveListener() {\n\t\tvar data = metalData.get(this.emitter_);\n\t\tvar selector = this.selector_;\n\t\tvar arr = core.isString(selector) ? data.delegating[this.event_].selectors : data.listeners;\n\t\tvar key = core.isString(selector) ? selector : this.event_;\n\n\t\tarray.remove(arr[key] || [], this.listener_);\n\t\tif (arr[key] && arr[key].length === 0) {\n\t\t\tdelete arr[key];\n\t\t}\n\t}\n}\n\nexport default DomDelegatedEventHandle;\n"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/build/amd/metal-dom/src/dom.js b/build/amd/metal-dom/src/dom.js
index 6ab0d7a..f1dfe7d 100644
--- a/build/amd/metal-dom/src/dom.js
+++ b/build/amd/metal-dom/src/dom.js
@@ -1,10 +1,14 @@
-define(['exports', 'metal/src/metal', './DomEventHandle'], function (exports, _metal, _DomEventHandle) {
+define(['exports', 'metal/src/metal', './metalData', './DomDelegatedEventHandle', './DomEventHandle'], function (exports, _metal, _metalData, _DomDelegatedEventHandle, _DomEventHandle) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
+ var _metalData2 = _interopRequireDefault(_metalData);
+
+ var _DomDelegatedEventHandle2 = _interopRequireDefault(_DomDelegatedEventHandle);
+
var _DomEventHandle2 = _interopRequireDefault(_DomEventHandle);
function _interopRequireDefault(obj) {
@@ -19,6 +23,13 @@ define(['exports', 'metal/src/metal', './DomEventHandle'], function (exports, _m
}
}
+ var NEXT_TARGET = '__metal_next_target__';
+ var USE_CAPTURE = {
+ blur: true,
+ focus: true,
+ scroll: true
+ };
+
var dom = function () {
function dom() {
_classCallCheck(this, dom);
@@ -63,6 +74,33 @@ define(['exports', 'metal/src/metal', './DomEventHandle'], function (exports, _m
}
};
+ dom.addElementListener_ = function addElementListener_(element, eventName, listener) {
+ var data = _metalData2.default.get(element);
+ dom.addToArr_(data.listeners, eventName, listener);
+ };
+
+ dom.addSelectorListener_ = function addSelectorListener_(element, eventName, selector, listener) {
+ var data = _metalData2.default.get(element);
+ dom.addToArr_(data.delegating[eventName].selectors, selector, listener);
+ };
+
+ dom.addToArr_ = function addToArr_(arr, key, value) {
+ if (!arr[key]) {
+ arr[key] = [];
+ }
+ arr[key].push(value);
+ };
+
+ dom.attachDelegateEvent_ = function attachDelegateEvent_(element, eventName) {
+ var data = _metalData2.default.get(element);
+ if (!data.delegating[eventName]) {
+ data.delegating[eventName] = {
+ handle: dom.on(element, eventName, dom.handleDelegateEvent_, !!USE_CAPTURE[eventName]),
+ selectors: {}
+ };
+ }
+ };
+
dom.closest = function closest(element, selector) {
while (element && !dom.match(element, selector)) {
element = element.parentNode;
@@ -106,13 +144,27 @@ define(['exports', 'metal/src/metal', './DomEventHandle'], function (exports, _m
}
};
- dom.delegate = function delegate(element, eventName, selector, callback) {
+ dom.delegate = function delegate(element, eventName, selectorOrTarget, callback, opt_default) {
var customConfig = dom.customEvents[eventName];
if (customConfig && customConfig.delegate) {
eventName = customConfig.originalEvent;
callback = customConfig.handler.bind(customConfig, callback);
}
- return dom.on(element, eventName, dom.handleDelegateEvent_.bind(null, selector, callback));
+
+ if (opt_default) {
+ // Wrap callback so we don't set property directly on it.
+ callback = callback.bind();
+ callback.defaultListener_ = true;
+ }
+
+ dom.attachDelegateEvent_(element, eventName);
+ if (_metal.core.isString(selectorOrTarget)) {
+ dom.addSelectorListener_(element, eventName, selectorOrTarget, callback);
+ } else {
+ dom.addElementListener_(selectorOrTarget, eventName, callback);
+ }
+
+ return new _DomDelegatedEventHandle2.default(_metal.core.isString(selectorOrTarget) ? element : selectorOrTarget, eventName, callback, _metal.core.isString(selectorOrTarget) ? selectorOrTarget : null);
};
dom.enterDocument = function enterDocument(node) {
@@ -125,25 +177,28 @@ define(['exports', 'metal/src/metal', './DomEventHandle'], function (exports, _m
}
};
- dom.handleDelegateEvent_ = function handleDelegateEvent_(selector, callback, event) {
+ dom.handleDelegateEvent_ = function handleDelegateEvent_(event) {
dom.normalizeDelegateEvent_(event);
+ var currElement = _metal.core.isDef(event[NEXT_TARGET]) ? event[NEXT_TARGET] : event.target;
+ var ret = true;
+ var container = event.currentTarget;
+ var limit = event.currentTarget.parentNode;
+ var defFns = [];
+
+ while (currElement && currElement !== limit && !event.stopped) {
+ event.delegateTarget = currElement;
+ ret &= dom.triggerMatchedListeners_(container, currElement, event, defFns);
+ currElement = currElement.parentNode;
+ }
- var currentElement = event.target;
- var returnValue = true;
-
- while (currentElement && !event.stopped) {
- if (_metal.core.isString(selector) && dom.match(currentElement, selector)) {
- event.delegateTarget = currentElement;
- returnValue &= callback(event);
- }
- if (currentElement === event.currentTarget) {
- break;
- }
- currentElement = currentElement.parentNode;
+ for (var i = 0; i < defFns.length && !event.defaultPrevented; i++) {
+ event.delegateTarget = defFns[i].element;
+ ret &= defFns[i].fn(event);
}
- event.delegateTarget = null;
- return returnValue;
+ event.delegateTarget = null;
+ event[NEXT_TARGET] = limit;
+ return ret;
};
dom.hasClass = function hasClass(element, className) {
@@ -282,6 +337,7 @@ define(['exports', 'metal/src/metal', './DomEventHandle'], function (exports, _m
dom.stopImmediatePropagation_ = function stopImmediatePropagation_() {
this.stopped = true;
+ this.stoppedImmediate = true;
Event.prototype.stopImmediatePropagation.call(this);
};
@@ -362,6 +418,39 @@ define(['exports', 'metal/src/metal', './DomEventHandle'], function (exports, _m
element.dispatchEvent(eventObj);
};
+ dom.triggerListeners_ = function triggerListeners_(listeners, event, element, defaultFns) {
+ var ret = true;
+ listeners = listeners || [];
+ for (var i = 0; i < listeners.length && !event.stoppedImmediate; i++) {
+ if (listeners[i].defaultListener_) {
+ defaultFns.push({
+ element: element,
+ fn: listeners[i]
+ });
+ } else {
+ ret &= listeners[i](event);
+ }
+ }
+ return ret;
+ };
+
+ dom.triggerMatchedListeners_ = function triggerMatchedListeners_(container, element, event, defaultFns) {
+ var data = _metalData2.default.get(element);
+ var listeners = data.listeners[event.type];
+ var ret = dom.triggerListeners_(listeners, event, element, defaultFns);
+
+ var selectorsMap = _metalData2.default.get(container).delegating[event.type].selectors;
+ var selectors = Object.keys(selectorsMap);
+ for (var i = 0; i < selectors.length && !event.stoppedImmediate; i++) {
+ if (dom.match(element, selectors[i])) {
+ listeners = selectorsMap[selectors[i]];
+ ret &= dom.triggerListeners_(listeners, event, element, defaultFns);
+ }
+ }
+
+ return ret;
+ };
+
return dom;
}();
diff --git a/build/amd/metal-dom/src/dom.js.map b/build/amd/metal-dom/src/dom.js.map
index a700b3e..b5a6e50 100644
--- a/build/amd/metal-dom/src/dom.js.map
+++ b/build/amd/metal-dom/src/dom.js.map
@@ -1 +1 @@
-{"version":3,"sources":["dom.js"],"names":[],"mappings":"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","file":"node_modules/metal-dom/src/dom.js","sourcesContent":["'use strict';\n\nimport { core, object } from 'metal';\nimport DomEventHandle from './DomEventHandle';\n\nclass dom {\n\t/**\n\t * Adds the requested CSS classes to an element.\n\t * @param {!Element} element The element to add CSS classes to.\n\t * @param {string} classes CSS classes to add.\n\t */\n\tstatic addClasses(element, classes) {\n\t\tif (!core.isObject(element) || !core.isString(classes)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ('classList' in element) {\n\t\t\tdom.addClassesWithNative_(element, classes);\n\t\t} else {\n\t\t\tdom.addClassesWithoutNative_(element, classes);\n\t\t}\n\t}\n\n\t/**\n\t * Adds the requested CSS classes to an element using classList.\n\t * @param {!Element} element The element to add CSS classes to.\n\t * @param {string} classes CSS classes to add.\n\t * @protected\n\t */\n\tstatic addClassesWithNative_(element, classes) {\n\t\tclasses.split(' ').forEach(function(className) {\n\t\t\tif (className) {\n\t\t\t\telement.classList.add(className);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Adds the requested CSS classes to an element without using classList.\n\t * @param {!Element} element The element to add CSS classes to.\n\t * @param {string} classes CSS classes to add.\n\t * @protected\n\t */\n\tstatic addClassesWithoutNative_(element, classes) {\n\t\tvar elementClassName = ' ' + element.className + ' ';\n\t\tvar classesToAppend = '';\n\n\t\tclasses = classes.split(' ');\n\n\t\tfor (var i = 0; i < classes.length; i++) {\n\t\t\tvar className = classes[i];\n\n\t\t\tif (elementClassName.indexOf(' ' + className + ' ') === -1) {\n\t\t\t\tclassesToAppend += ' ' + className;\n\t\t\t}\n\t\t}\n\n\t\tif (classesToAppend) {\n\t\t\telement.className = element.className + classesToAppend;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the closest element up the tree from the given element (including\n\t * itself) that matches the specified selector, or null if none match.\n\t * @param {Element} element\n\t * @param {string} selector\n\t * @return {Element}\n\t */\n\tstatic closest(element, selector) {\n\t\twhile (element && !dom.match(element, selector)) {\n\t\t\telement = element.parentNode;\n\t\t}\n\t\treturn element;\n\t}\n\n\t/**\n\t * Appends a child node with text or other nodes to a parent node. If\n\t * child is a HTML string it will be automatically converted to a document\n\t * fragment before appending it to the parent.\n\t * @param {!Element} parent The node to append nodes to.\n\t * @param {!(Element|NodeList|string)} child The thing to append to the parent.\n\t * @return {!Element} The appended child.\n\t */\n\tstatic append(parent, child) {\n\t\tif (core.isString(child)) {\n\t\t\tchild = dom.buildFragment(child);\n\t\t}\n\t\tif (child instanceof NodeList) {\n\t\t\tvar childArr = Array.prototype.slice.call(child);\n\t\t\tfor (var i = 0; i < childArr.length; i++) {\n\t\t\t\tparent.appendChild(childArr[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tparent.appendChild(child);\n\t\t}\n\t\treturn child;\n\t}\n\n\t/**\n\t * Helper for converting a HTML string into a document fragment.\n\t * @param {string} htmlString The HTML string to convert.\n\t * @return {!Element} The resulting document fragment.\n\t */\n\tstatic buildFragment(htmlString) {\n\t\tvar tempDiv = document.createElement('div');\n\t\ttempDiv.innerHTML = ' ' + htmlString;\n\t\ttempDiv.removeChild(tempDiv.firstChild);\n\n\t\tvar fragment = document.createDocumentFragment();\n\t\twhile (tempDiv.firstChild) {\n\t\t\tfragment.appendChild(tempDiv.firstChild);\n\t\t}\n\t\treturn fragment;\n\t}\n\n\t/**\n\t * Checks if the first element contains the second one.\n\t * @param {!Element} element1\n\t * @param {!Element} element2\n\t * @return {boolean}\n\t */\n\tstatic contains(element1, element2) {\n\t\tif (core.isDocument(element1)) {\n\t\t\t// document.contains is not defined on IE9, so call it on documentElement instead.\n\t\t\treturn element1.documentElement.contains(element2);\n\t\t} else {\n\t\t\treturn element1.contains(element2);\n\t\t}\n\t}\n\n\t/**\n\t * Listens to the specified event on the given DOM element, but only calls the\n\t * callback with the event when it triggered by elements that match the given\n\t * selector.\n\t * @param {!Element} element The container DOM element to listen to the event on.\n\t * @param {string} eventName The name of the event to listen to.\n\t * @param {string} selector The selector that matches the child elements that\n\t * the event should be triggered for.\n\t * @param {!function(!Object)} callback Function to be called when the event is\n\t * triggered. It will receive the normalized event object.\n\t * @return {!DomEventHandle} Can be used to remove the listener.\n\t */\n\tstatic delegate(element, eventName, selector, callback) {\n\t\tvar customConfig = dom.customEvents[eventName];\n\t\tif (customConfig && customConfig.delegate) {\n\t\t\teventName = customConfig.originalEvent;\n\t\t\tcallback = customConfig.handler.bind(customConfig, callback);\n\t\t}\n\t\treturn dom.on(\n\t\t\telement,\n\t\t\teventName,\n\t\t\tdom.handleDelegateEvent_.bind(null, selector, callback)\n\t\t);\n\t}\n\n\t/**\n\t * Inserts node in document as last element.\n\t * @param {Element} node Element to remove children from.\n\t */\n\tstatic enterDocument(node) {\n\t\tnode && dom.append(document.body, node);\n\t}\n\n\t/**\n\t * Removes node from document.\n\t * @param {Element} node Element to remove children from.\n\t */\n\tstatic exitDocument(node) {\n\t\tif (node && node.parentNode) {\n\t\t\tnode.parentNode.removeChild(node);\n\t\t}\n\t}\n\n\t/**\n\t * This is called when an event is triggered by a delegate listener (see\n\t * `dom.delegate` for more details).\n\t * @param {string} selector The selector or element that matches the child\n\t * elements that the event should be triggered for.\n\t * @param {!function(!Object)} callback Function to be called when the event\n\t * is triggered. It will receive the normalized event object.\n\t * @param {!Event} event The event payload.\n\t * @return {boolean} False if at least one of the triggered callbacks returns\n\t * false, or true otherwise.\n\t */\n\tstatic handleDelegateEvent_(selector, callback, event) {\n\t\tdom.normalizeDelegateEvent_(event);\n\n\t\tvar currentElement = event.target;\n\t\tvar returnValue = true;\n\n\t\twhile (currentElement && !event.stopped) {\n\t\t\tif (core.isString(selector) && dom.match(currentElement, selector)) {\n\t\t\t\tevent.delegateTarget = currentElement;\n\t\t\t\treturnValue &= callback(event);\n\t\t\t}\n\t\t\tif (currentElement === event.currentTarget) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcurrentElement = currentElement.parentNode;\n\t\t}\n\t\tevent.delegateTarget = null;\n\n\t\treturn returnValue;\n\t}\n\n\t/**\n\t * Checks if the given element has the requested css class.\n\t * @param {!Element} element\n\t * @param {string} className\n\t * @return {boolean}\n\t */\n\tstatic hasClass(element, className) {\n\t\tif ('classList' in element) {\n\t\t\treturn dom.hasClassWithNative_(element, className);\n\t\t} else {\n\t\t\treturn dom.hasClassWithoutNative_(element, className);\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given element has the requested css class using classList.\n\t * @param {!Element} element\n\t * @param {string} className\n\t * @return {boolean}\n\t * @protected\n\t */\n\tstatic hasClassWithNative_(element, className) {\n\t\treturn element.classList.contains(className);\n\t}\n\n\t/**\n\t * Checks if the given element has the requested css class without using classList.\n\t * @param {!Element} element\n\t * @param {string} className\n\t * @return {boolean}\n\t * @protected\n\t */\n\tstatic hasClassWithoutNative_(element, className) {\n\t\treturn (' ' + element.className + ' ').indexOf(' ' + className + ' ') >= 0;\n\t}\n\n\t/**\n\t * Checks if the given element is empty or not.\n\t * @param {!Element} element\n\t * @return {boolean}\n\t */\n\tstatic isEmpty(element) {\n\t\treturn element.childNodes.length === 0;\n\t}\n\n\t/**\n\t * Check if an element matches a given selector.\n\t * @param {Element} element\n\t * @param {string} selector\n\t * @return {boolean}\n\t */\n\tstatic match(element, selector) {\n\t\tif (!element || element.nodeType !== 1) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar p = Element.prototype;\n\t\tvar m = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector;\n\t\tif (m) {\n\t\t\treturn m.call(element, selector);\n\t\t}\n\n\t\treturn dom.matchFallback_(element, selector);\n\t}\n\n\t/**\n\t * Check if an element matches a given selector, using an internal implementation\n\t * instead of calling existing javascript functions.\n\t * @param {Element} element\n\t * @param {string} selector\n\t * @return {boolean}\n\t * @protected\n\t */\n\tstatic matchFallback_(element, selector) {\n\t\tvar nodes = document.querySelectorAll(selector, element.parentNode);\n\t\tfor (var i = 0; i < nodes.length; ++i) {\n\t\t\tif (nodes[i] === element) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Returns the next sibling of the given element that matches the specified\n\t * selector, or null if there is none.\n\t * @param {!Element} element\n\t * @param {?string} selector\n\t */\n\tstatic next(element, selector) {\n\t\tdo {\n\t\t\telement = element.nextSibling;\n\t\t\tif (element && dom.match(element, selector)) {\n\t\t\t\treturn element;\n\t\t\t}\n\t\t} while (element);\n\t\treturn null;\n\t}\n\n\t/**\n\t * Normalizes the event payload for delegate listeners.\n\t * @param {!Event} event\n\t */\n\tstatic normalizeDelegateEvent_(event) {\n\t\tevent.stopPropagation = dom.stopPropagation_;\n\t\tevent.stopImmediatePropagation = dom.stopImmediatePropagation_;\n\t}\n\n\t/**\n\t * Listens to the specified event on the given DOM element. This function normalizes\n\t * DOM event payloads and functions so they'll work the same way on all supported\n\t * browsers.\n\t * @param {!Element|string} element The DOM element to listen to the event on, or\n\t * a selector that should be delegated on the entire document.\n\t * @param {string} eventName The name of the event to listen to.\n\t * @param {!function(!Object)} callback Function to be called when the event is\n\t * triggered. It will receive the normalized event object.\n\t * @param {boolean} opt_capture Flag indicating if listener should be triggered\n\t * during capture phase, instead of during the bubbling phase. Defaults to false.\n\t * @return {!DomEventHandle} Can be used to remove the listener.\n\t */\n\tstatic on(element, eventName, callback, opt_capture) {\n\t\tif (core.isString(element)) {\n\t\t\treturn dom.delegate(document, eventName, element, callback);\n\t\t}\n\t\tvar customConfig = dom.customEvents[eventName];\n\t\tif (customConfig && customConfig.event) {\n\t\t\teventName = customConfig.originalEvent;\n\t\t\tcallback = customConfig.handler.bind(customConfig, callback);\n\t\t}\n\t\telement.addEventListener(eventName, callback, opt_capture);\n\t\treturn new DomEventHandle(element, eventName, callback, opt_capture);\n\t}\n\n\t/**\n\t * Listens to the specified event on the given DOM element once. This\n\t * function normalizes DOM event payloads and functions so they'll work the\n\t * same way on all supported browsers.\n\t * @param {!Element} element The DOM element to listen to the event on.\n\t * @param {string} eventName The name of the event to listen to.\n\t * @param {!function(!Object)} callback Function to be called when the event\n\t * is triggered. It will receive the normalized event object.\n\t * @return {!DomEventHandle} Can be used to remove the listener.\n\t */\n\tstatic once(element, eventName, callback) {\n\t\tvar domEventHandle = this.on(element, eventName, function() {\n\t\t\tdomEventHandle.removeListener();\n\t\t\treturn callback.apply(this, arguments);\n\t\t});\n\t\treturn domEventHandle;\n\t}\n\n\t/**\n\t * Gets the first parent from the given element that matches the specified\n\t * selector, or null if none match.\n\t * @param {!Element} element\n\t * @param {string} selector\n\t * @return {Element}\n\t */\n\tstatic parent(element, selector) {\n\t\treturn dom.closest(element.parentNode, selector);\n\t}\n\n\t/**\n\t * Registers a custom event.\n\t * @param {string} eventName The name of the custom event.\n\t * @param {!Object} customConfig An object with information about how the event\n\t * should be handled.\n\t */\n\tstatic registerCustomEvent(eventName, customConfig) {\n\t\tdom.customEvents[eventName] = customConfig;\n\t}\n\n\t/**\n\t * Removes all the child nodes on a DOM node.\n\t * @param {Element} node Element to remove children from.\n\t */\n\tstatic removeChildren(node) {\n\t\tvar child;\n\t\twhile ((child = node.firstChild)) {\n\t\t\tnode.removeChild(child);\n\t\t}\n\t}\n\n\t/**\n\t * Removes the requested CSS classes from an element.\n\t * @param {!Element} element The element to remove CSS classes from.\n\t * @param {string} classes CSS classes to remove.\n\t */\n\tstatic removeClasses(element, classes) {\n\t\tif (!core.isObject(element) || !core.isString(classes)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ('classList' in element) {\n\t\t\tdom.removeClassesWithNative_(element, classes);\n\t\t} else {\n\t\t\tdom.removeClassesWithoutNative_(element, classes);\n\t\t}\n\t}\n\n\t/**\n\t * Removes the requested CSS classes from an element using classList.\n\t * @param {!Element} element The element to remove CSS classes from.\n\t * @param {string} classes CSS classes to remove.\n\t * @protected\n\t */\n\tstatic removeClassesWithNative_(element, classes) {\n\t\tclasses.split(' ').forEach(function(className) {\n\t\t\tif (className) {\n\t\t\t\telement.classList.remove(className);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Removes the requested CSS classes from an element without using classList.\n\t * @param {!Element} element The element to remove CSS classes from.\n\t * @param {string} classes CSS classes to remove.\n\t * @protected\n\t */\n\tstatic removeClassesWithoutNative_(element, classes) {\n\t\tvar elementClassName = ' ' + element.className + ' ';\n\n\t\tclasses = classes.split(' ');\n\n\t\tfor (var i = 0; i < classes.length; i++) {\n\t\t\telementClassName = elementClassName.replace(' ' + classes[i] + ' ', ' ');\n\t\t}\n\n\t\telement.className = elementClassName.trim();\n\t}\n\n\t/**\n\t * Replaces the first element with the second.\n\t * @param {Element} element1\n\t * @param {Element} element2\n\t */\n\tstatic replace(element1, element2) {\n\t\tif (element1 && element2 && element1 !== element2 && element1.parentNode) {\n\t\t\telement1.parentNode.insertBefore(element2, element1);\n\t\t\telement1.parentNode.removeChild(element1);\n\t\t}\n\t}\n\n\t/**\n\t * The function that replaces `stopImmediatePropagation_` for events.\n\t * @protected\n\t */\n\tstatic stopImmediatePropagation_() {\n\t\tthis.stopped = true;\n\t\tEvent.prototype.stopImmediatePropagation.call(this);\n\t}\n\n\t/**\n\t * The function that replaces `stopPropagation` for events.\n\t * @protected\n\t */\n\tstatic stopPropagation_() {\n\t\tthis.stopped = true;\n\t\tEvent.prototype.stopPropagation.call(this);\n\t}\n\n\t/**\n\t * Checks if the given element supports the given event type.\n\t * @param {!Element|string} element The DOM element or element tag name to check.\n\t * @param {string} eventName The name of the event to check.\n\t * @return {boolean}\n\t */\n\tstatic supportsEvent(element, eventName) {\n\t\tif (dom.customEvents[eventName]) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (core.isString(element)) {\n\t\t\tif (!elementsByTag[element]) {\n\t\t\t\telementsByTag[element] = document.createElement(element);\n\t\t\t}\n\t\t\telement = elementsByTag[element];\n\t\t}\n\t\treturn 'on' + eventName in element;\n\t}\n\n\t/**\n\t * Converts the given argument to a DOM element. Strings are assumed to\n\t * be selectors, and so a matched element will be returned. If the arg\n\t * is already a DOM element it will be the return value.\n\t * @param {string|Element|Document} selectorOrElement\n\t * @return {Element} The converted element, or null if none was found.\n\t */\n\tstatic toElement(selectorOrElement) {\n\t\tif (core.isElement(selectorOrElement) || core.isDocument(selectorOrElement)) {\n\t\t\treturn selectorOrElement;\n\t\t} else if (core.isString(selectorOrElement)) {\n\t\t\tif (selectorOrElement[0] === '#' && selectorOrElement.indexOf(' ') === -1) {\n\t\t\t\treturn document.getElementById(selectorOrElement.substr(1));\n\t\t\t} else {\n\t\t\t\treturn document.querySelector(selectorOrElement);\n\t\t\t}\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Adds or removes one or more classes from an element. If any of the classes\n\t * is present, it will be removed from the element, or added otherwise.\n\t * @param {!Element} element The element which classes will be toggled.\n\t * @param {string} classes The classes which have to added or removed from the element.\n\t */\n\tstatic toggleClasses(element, classes) {\n\t\tif (!core.isObject(element) || !core.isString(classes)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ('classList' in element) {\n\t\t\tdom.toggleClassesWithNative_(element, classes);\n\t\t} else {\n\t\t\tdom.toggleClassesWithoutNative_(element, classes);\n\t\t}\n\t}\n\n\t/**\n\t * Adds or removes one or more classes from an element using classList.\n\t * If any of the classes is present, it will be removed from the element,\n\t * or added otherwise.\n\t * @param {!Element} element The element which classes will be toggled.\n\t * @param {string} classes The classes which have to added or removed from the element.\n\t */\n\tstatic toggleClassesWithNative_(element, classes) {\n\t\tclasses.split(' ').forEach(function(className) {\n\t\t\telement.classList.toggle(className);\n\t\t});\n\t}\n\n\t/**\n\t * Adds or removes one or more classes from an element without using classList.\n\t * If any of the classes is present, it will be removed from the element,\n\t * or added otherwise.\n\t * @param {!Element} element The element which classes will be toggled.\n\t * @param {string} classes The classes which have to added or removed from the element.\n\t */\n\tstatic toggleClassesWithoutNative_(element, classes) {\n\t\tvar elementClassName = ' ' + element.className + ' ';\n\n\t\tclasses = classes.split(' ');\n\n\t\tfor (var i = 0; i < classes.length; i++) {\n\t\t\tvar className = ' ' + classes[i] + ' ';\n\t\t\tvar classIndex = elementClassName.indexOf(className);\n\n\t\t\tif (classIndex === -1) {\n\t\t\t\telementClassName = elementClassName + classes[i] + ' ';\n\t\t\t} else {\n\t\t\t\telementClassName = elementClassName.substring(0, classIndex) + ' ' +\n\t\t\t\t\telementClassName.substring(classIndex + className.length);\n\t\t\t}\n\t\t}\n\n\t\telement.className = elementClassName.trim();\n\t}\n\n\t/**\n\t * Triggers the specified event on the given element.\n\t * NOTE: This should mostly be used for testing, not on real code.\n\t * @param {!Element} element The node that should trigger the event.\n\t * @param {string} eventName The name of the event to be triggred.\n\t * @param {Object=} opt_eventObj An object with data that should be on the\n\t * triggered event's payload.\n\t */\n\tstatic triggerEvent(element, eventName, opt_eventObj) {\n\t\tvar eventObj = document.createEvent('HTMLEvents');\n\t\teventObj.initEvent(eventName, true, true);\n\t\tobject.mixin(eventObj, opt_eventObj);\n\t\telement.dispatchEvent(eventObj);\n\t}\n}\n\nvar elementsByTag = {};\ndom.customEvents = {};\n\nexport default dom;\n"],"sourceRoot":"/source/"}
\ No newline at end of file
+{"version":3,"sources":["dom.js"],"names":[],"mappings":"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","file":"node_modules/metal-dom/src/dom.js","sourcesContent":["'use strict';\n\nimport { core, object } from 'metal';\nimport metalData from './metalData';\nimport DomDelegatedEventHandle from './DomDelegatedEventHandle';\nimport DomEventHandle from './DomEventHandle';\n\nconst NEXT_TARGET = '__metal_next_target__';\nconst USE_CAPTURE = {\n\tblur: true,\n\tfocus: true,\n\tscroll: true\n};\n\nclass dom {\n\t/**\n\t * Adds the requested CSS classes to an element.\n\t * @param {!Element} element The element to add CSS classes to.\n\t * @param {string} classes CSS classes to add.\n\t */\n\tstatic addClasses(element, classes) {\n\t\tif (!core.isObject(element) || !core.isString(classes)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ('classList' in element) {\n\t\t\tdom.addClassesWithNative_(element, classes);\n\t\t} else {\n\t\t\tdom.addClassesWithoutNative_(element, classes);\n\t\t}\n\t}\n\n\t/**\n\t * Adds the requested CSS classes to an element using classList.\n\t * @param {!Element} element The element to add CSS classes to.\n\t * @param {string} classes CSS classes to add.\n\t * @protected\n\t */\n\tstatic addClassesWithNative_(element, classes) {\n\t\tclasses.split(' ').forEach(function(className) {\n\t\t\tif (className) {\n\t\t\t\telement.classList.add(className);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Adds the requested CSS classes to an element without using classList.\n\t * @param {!Element} element The element to add CSS classes to.\n\t * @param {string} classes CSS classes to add.\n\t * @protected\n\t */\n\tstatic addClassesWithoutNative_(element, classes) {\n\t\tvar elementClassName = ' ' + element.className + ' ';\n\t\tvar classesToAppend = '';\n\n\t\tclasses = classes.split(' ');\n\n\t\tfor (var i = 0; i < classes.length; i++) {\n\t\t\tvar className = classes[i];\n\n\t\t\tif (elementClassName.indexOf(' ' + className + ' ') === -1) {\n\t\t\t\tclassesToAppend += ' ' + className;\n\t\t\t}\n\t\t}\n\n\t\tif (classesToAppend) {\n\t\t\telement.className = element.className + classesToAppend;\n\t\t}\n\t}\n\n\t/**\n\t * Adds an event listener to the given element, to be triggered via delegate.\n\t * @param {!Element} element\n\t * @param {string} eventName\n\t * @param {!function()} listener\n\t * @protected\n\t */\n\tstatic addElementListener_(element, eventName, listener) {\n\t\tvar data = metalData.get(element);\n\t\tdom.addToArr_(data.listeners, eventName, listener);\n\t}\n\n\t/**\n\t * Adds an event listener to the given element, to be triggered via delegate\n\t * selectors.\n\t * @param {!Element} element\n\t * @param {string} eventName\n\t * @param {string} selector\n\t * @param {!function()} listener\n\t * @protected\n\t */\n\tstatic addSelectorListener_(element, eventName, selector, listener) {\n\t\tvar data = metalData.get(element);\n\t\tdom.addToArr_(data.delegating[eventName].selectors, selector, listener);\n\t}\n\n\t/**\n\t * Adds a value to an array inside an object, creating it first if it doesn't\n\t * yet exist.\n\t * @param {!Array} arr\n\t * @param {string} key\n\t * @param {*} value\n\t * @protected\n\t */\n\tstatic addToArr_(arr, key, value) {\n\t\tif (!arr[key]) {\n\t\t\tarr[key] = [];\n\t\t}\n\t\tarr[key].push(value);\n\t}\n\n\t/**\n\t * Attaches a delegate listener, unless there's already one attached.\n\t * @param {!Element} element\n\t * @param {string} eventName\n\t * @protected\n\t */\n\tstatic attachDelegateEvent_(element, eventName) {\n\t\tvar data = metalData.get(element);\n\t\tif (!data.delegating[eventName]) {\n\t\t\tdata.delegating[eventName] = {\n\t\t\t\thandle: dom.on(\n\t\t\t\t\telement,\n\t\t\t\t\teventName,\n\t\t\t\t\tdom.handleDelegateEvent_,\n\t\t\t\t\t!!USE_CAPTURE[eventName]\n\t\t\t\t),\n\t\t\t\tselectors: {}\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Gets the closest element up the tree from the given element (including\n\t * itself) that matches the specified selector, or null if none match.\n\t * @param {Element} element\n\t * @param {string} selector\n\t * @return {Element}\n\t */\n\tstatic closest(element, selector) {\n\t\twhile (element && !dom.match(element, selector)) {\n\t\t\telement = element.parentNode;\n\t\t}\n\t\treturn element;\n\t}\n\n\t/**\n\t * Appends a child node with text or other nodes to a parent node. If\n\t * child is a HTML string it will be automatically converted to a document\n\t * fragment before appending it to the parent.\n\t * @param {!Element} parent The node to append nodes to.\n\t * @param {!(Element|NodeList|string)} child The thing to append to the parent.\n\t * @return {!Element} The appended child.\n\t */\n\tstatic append(parent, child) {\n\t\tif (core.isString(child)) {\n\t\t\tchild = dom.buildFragment(child);\n\t\t}\n\t\tif (child instanceof NodeList) {\n\t\t\tvar childArr = Array.prototype.slice.call(child);\n\t\t\tfor (var i = 0; i < childArr.length; i++) {\n\t\t\t\tparent.appendChild(childArr[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tparent.appendChild(child);\n\t\t}\n\t\treturn child;\n\t}\n\n\t/**\n\t * Helper for converting a HTML string into a document fragment.\n\t * @param {string} htmlString The HTML string to convert.\n\t * @return {!Element} The resulting document fragment.\n\t */\n\tstatic buildFragment(htmlString) {\n\t\tvar tempDiv = document.createElement('div');\n\t\ttempDiv.innerHTML = ' ' + htmlString;\n\t\ttempDiv.removeChild(tempDiv.firstChild);\n\n\t\tvar fragment = document.createDocumentFragment();\n\t\twhile (tempDiv.firstChild) {\n\t\t\tfragment.appendChild(tempDiv.firstChild);\n\t\t}\n\t\treturn fragment;\n\t}\n\n\t/**\n\t * Checks if the first element contains the second one.\n\t * @param {!Element} element1\n\t * @param {!Element} element2\n\t * @return {boolean}\n\t */\n\tstatic contains(element1, element2) {\n\t\tif (core.isDocument(element1)) {\n\t\t\t// document.contains is not defined on IE9, so call it on documentElement instead.\n\t\t\treturn element1.documentElement.contains(element2);\n\t\t} else {\n\t\t\treturn element1.contains(element2);\n\t\t}\n\t}\n\n\t/**\n\t * Listens to the specified event on the given DOM element, but only calls the\n\t * given callback listener when it's triggered by elements that match the\n\t * given selector or target element.\n\t * @param {!Element} element The DOM element the event should be listened on.\n\t * @param {string} eventName The name of the event to listen to.\n\t * @param {!Element|string} selectorOrTarget Either an element or css selector\n\t * that should match the event for the listener to be triggered.\n\t * @param {!function(!Object)} callback Function to be called when the event\n\t * is triggered. It will receive the normalized event object.\n\t * @param {boolean=} opt_default Optional flag indicating if this is a default\n\t * listener. That means that it would only be executed after all non\n\t * default listeners, and only if the event isn't prevented via\n\t * `preventDefault`.\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\tstatic delegate(element, eventName, selectorOrTarget, callback, opt_default) {\n\t\tvar customConfig = dom.customEvents[eventName];\n\t\tif (customConfig && customConfig.delegate) {\n\t\t\teventName = customConfig.originalEvent;\n\t\t\tcallback = customConfig.handler.bind(customConfig, callback);\n\t\t}\n\n\t\tif (opt_default) {\n\t\t\t// Wrap callback so we don't set property directly on it.\n\t\t\tcallback = callback.bind();\n\t\t\tcallback.defaultListener_ = true;\n\t\t}\n\n\t\tdom.attachDelegateEvent_(element, eventName);\n\t\tif (core.isString(selectorOrTarget)) {\n\t\t\tdom.addSelectorListener_(element, eventName, selectorOrTarget, callback);\n\t\t} else {\n\t\t\tdom.addElementListener_(selectorOrTarget, eventName, callback);\n\t\t}\n\n\t\treturn new DomDelegatedEventHandle(\n\t\t\tcore.isString(selectorOrTarget) ? element : selectorOrTarget,\n\t\t\teventName,\n\t\t\tcallback,\n\t\t\tcore.isString(selectorOrTarget) ? selectorOrTarget : null\n\t\t);\n\t}\n\n\t/**\n\t * Inserts node in document as last element.\n\t * @param {Element} node Element to remove children from.\n\t */\n\tstatic enterDocument(node) {\n\t\tnode && dom.append(document.body, node);\n\t}\n\n\t/**\n\t * Removes node from document.\n\t * @param {Element} node Element to remove children from.\n\t */\n\tstatic exitDocument(node) {\n\t\tif (node && node.parentNode) {\n\t\t\tnode.parentNode.removeChild(node);\n\t\t}\n\t}\n\n\t/**\n\t * This is called when an event is triggered by a delegate listener. All\n\t * matching listeners of this event type from `target` to `currentTarget` will\n\t * be triggered.\n\t * @param {!Event} event The event payload.\n\t * @return {boolean} False if at least one of the triggered callbacks returns\n\t * false, or true otherwise.\n\t * @protected\n\t */\n\tstatic handleDelegateEvent_(event) {\n\t\tdom.normalizeDelegateEvent_(event);\n\t\tvar currElement = core.isDef(event[NEXT_TARGET]) ?\n\t\t\tevent[NEXT_TARGET] :\n\t\t\tevent.target;\n\t\tvar ret = true;\n\t\tvar container = event.currentTarget;\n\t\tvar limit = event.currentTarget.parentNode;\n\t\tvar defFns = [];\n\n\t\twhile (currElement && currElement !== limit && !event.stopped) {\n\t\t\tevent.delegateTarget = currElement;\n\t\t\tret &= dom.triggerMatchedListeners_(container, currElement, event, defFns);\n\t\t\tcurrElement = currElement.parentNode;\n\t\t}\n\n\t\tfor (var i = 0; i < defFns.length && !event.defaultPrevented; i++) {\n\t\t\tevent.delegateTarget = defFns[i].element;\n\t\t\tret &= defFns[i].fn(event);\n\t\t}\n\n\t\tevent.delegateTarget = null;\n\t\tevent[NEXT_TARGET] = limit;\n\t\treturn ret;\n\t}\n\n\t/**\n\t * Checks if the given element has the requested css class.\n\t * @param {!Element} element\n\t * @param {string} className\n\t * @return {boolean}\n\t */\n\tstatic hasClass(element, className) {\n\t\tif ('classList' in element) {\n\t\t\treturn dom.hasClassWithNative_(element, className);\n\t\t} else {\n\t\t\treturn dom.hasClassWithoutNative_(element, className);\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the given element has the requested css class using classList.\n\t * @param {!Element} element\n\t * @param {string} className\n\t * @return {boolean}\n\t * @protected\n\t */\n\tstatic hasClassWithNative_(element, className) {\n\t\treturn element.classList.contains(className);\n\t}\n\n\t/**\n\t * Checks if the given element has the requested css class without using classList.\n\t * @param {!Element} element\n\t * @param {string} className\n\t * @return {boolean}\n\t * @protected\n\t */\n\tstatic hasClassWithoutNative_(element, className) {\n\t\treturn (' ' + element.className + ' ').indexOf(' ' + className + ' ') >= 0;\n\t}\n\n\t/**\n\t * Checks if the given element is empty or not.\n\t * @param {!Element} element\n\t * @return {boolean}\n\t */\n\tstatic isEmpty(element) {\n\t\treturn element.childNodes.length === 0;\n\t}\n\n\t/**\n\t * Check if an element matches a given selector.\n\t * @param {Element} element\n\t * @param {string} selector\n\t * @return {boolean}\n\t */\n\tstatic match(element, selector) {\n\t\tif (!element || element.nodeType !== 1) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar p = Element.prototype;\n\t\tvar m = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector;\n\t\tif (m) {\n\t\t\treturn m.call(element, selector);\n\t\t}\n\n\t\treturn dom.matchFallback_(element, selector);\n\t}\n\n\t/**\n\t * Check if an element matches a given selector, using an internal implementation\n\t * instead of calling existing javascript functions.\n\t * @param {Element} element\n\t * @param {string} selector\n\t * @return {boolean}\n\t * @protected\n\t */\n\tstatic matchFallback_(element, selector) {\n\t\tvar nodes = document.querySelectorAll(selector, element.parentNode);\n\t\tfor (var i = 0; i < nodes.length; ++i) {\n\t\t\tif (nodes[i] === element) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Returns the next sibling of the given element that matches the specified\n\t * selector, or null if there is none.\n\t * @param {!Element} element\n\t * @param {?string} selector\n\t */\n\tstatic next(element, selector) {\n\t\tdo {\n\t\t\telement = element.nextSibling;\n\t\t\tif (element && dom.match(element, selector)) {\n\t\t\t\treturn element;\n\t\t\t}\n\t\t} while (element);\n\t\treturn null;\n\t}\n\n\t/**\n\t * Normalizes the event payload for delegate listeners.\n\t * @param {!Event} event\n\t */\n\tstatic normalizeDelegateEvent_(event) {\n\t\tevent.stopPropagation = dom.stopPropagation_;\n\t\tevent.stopImmediatePropagation = dom.stopImmediatePropagation_;\n\t}\n\n\t/**\n\t * Listens to the specified event on the given DOM element. This function normalizes\n\t * DOM event payloads and functions so they'll work the same way on all supported\n\t * browsers.\n\t * @param {!Element|string} element The DOM element to listen to the event on, or\n\t * a selector that should be delegated on the entire document.\n\t * @param {string} eventName The name of the event to listen to.\n\t * @param {!function(!Object)} callback Function to be called when the event is\n\t * triggered. It will receive the normalized event object.\n\t * @param {boolean} opt_capture Flag indicating if listener should be triggered\n\t * during capture phase, instead of during the bubbling phase. Defaults to false.\n\t * @return {!DomEventHandle} Can be used to remove the listener.\n\t */\n\tstatic on(element, eventName, callback, opt_capture) {\n\t\tif (core.isString(element)) {\n\t\t\treturn dom.delegate(document, eventName, element, callback);\n\t\t}\n\t\tvar customConfig = dom.customEvents[eventName];\n\t\tif (customConfig && customConfig.event) {\n\t\t\teventName = customConfig.originalEvent;\n\t\t\tcallback = customConfig.handler.bind(customConfig, callback);\n\t\t}\n\t\telement.addEventListener(eventName, callback, opt_capture);\n\t\treturn new DomEventHandle(element, eventName, callback, opt_capture);\n\t}\n\n\t/**\n\t * Listens to the specified event on the given DOM element once. This\n\t * function normalizes DOM event payloads and functions so they'll work the\n\t * same way on all supported browsers.\n\t * @param {!Element} element The DOM element to listen to the event on.\n\t * @param {string} eventName The name of the event to listen to.\n\t * @param {!function(!Object)} callback Function to be called when the event\n\t * is triggered. It will receive the normalized event object.\n\t * @return {!DomEventHandle} Can be used to remove the listener.\n\t */\n\tstatic once(element, eventName, callback) {\n\t\tvar domEventHandle = this.on(element, eventName, function() {\n\t\t\tdomEventHandle.removeListener();\n\t\t\treturn callback.apply(this, arguments);\n\t\t});\n\t\treturn domEventHandle;\n\t}\n\n\t/**\n\t * Gets the first parent from the given element that matches the specified\n\t * selector, or null if none match.\n\t * @param {!Element} element\n\t * @param {string} selector\n\t * @return {Element}\n\t */\n\tstatic parent(element, selector) {\n\t\treturn dom.closest(element.parentNode, selector);\n\t}\n\n\t/**\n\t * Registers a custom event.\n\t * @param {string} eventName The name of the custom event.\n\t * @param {!Object} customConfig An object with information about how the event\n\t * should be handled.\n\t */\n\tstatic registerCustomEvent(eventName, customConfig) {\n\t\tdom.customEvents[eventName] = customConfig;\n\t}\n\n\t/**\n\t * Removes all the child nodes on a DOM node.\n\t * @param {Element} node Element to remove children from.\n\t */\n\tstatic removeChildren(node) {\n\t\tvar child;\n\t\twhile ((child = node.firstChild)) {\n\t\t\tnode.removeChild(child);\n\t\t}\n\t}\n\n\t/**\n\t * Removes the requested CSS classes from an element.\n\t * @param {!Element} element The element to remove CSS classes from.\n\t * @param {string} classes CSS classes to remove.\n\t */\n\tstatic removeClasses(element, classes) {\n\t\tif (!core.isObject(element) || !core.isString(classes)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ('classList' in element) {\n\t\t\tdom.removeClassesWithNative_(element, classes);\n\t\t} else {\n\t\t\tdom.removeClassesWithoutNative_(element, classes);\n\t\t}\n\t}\n\n\t/**\n\t * Removes the requested CSS classes from an element using classList.\n\t * @param {!Element} element The element to remove CSS classes from.\n\t * @param {string} classes CSS classes to remove.\n\t * @protected\n\t */\n\tstatic removeClassesWithNative_(element, classes) {\n\t\tclasses.split(' ').forEach(function(className) {\n\t\t\tif (className) {\n\t\t\t\telement.classList.remove(className);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Removes the requested CSS classes from an element without using classList.\n\t * @param {!Element} element The element to remove CSS classes from.\n\t * @param {string} classes CSS classes to remove.\n\t * @protected\n\t */\n\tstatic removeClassesWithoutNative_(element, classes) {\n\t\tvar elementClassName = ' ' + element.className + ' ';\n\n\t\tclasses = classes.split(' ');\n\n\t\tfor (var i = 0; i < classes.length; i++) {\n\t\t\telementClassName = elementClassName.replace(' ' + classes[i] + ' ', ' ');\n\t\t}\n\n\t\telement.className = elementClassName.trim();\n\t}\n\n\t/**\n\t * Replaces the first element with the second.\n\t * @param {Element} element1\n\t * @param {Element} element2\n\t */\n\tstatic replace(element1, element2) {\n\t\tif (element1 && element2 && element1 !== element2 && element1.parentNode) {\n\t\t\telement1.parentNode.insertBefore(element2, element1);\n\t\t\telement1.parentNode.removeChild(element1);\n\t\t}\n\t}\n\n\t/**\n\t * The function that replaces `stopImmediatePropagation_` for events.\n\t * @protected\n\t */\n\tstatic stopImmediatePropagation_() {\n\t\tthis.stopped = true;\n\t\tthis.stoppedImmediate = true;\n\t\tEvent.prototype.stopImmediatePropagation.call(this);\n\t}\n\n\t/**\n\t * The function that replaces `stopPropagation` for events.\n\t * @protected\n\t */\n\tstatic stopPropagation_() {\n\t\tthis.stopped = true;\n\t\tEvent.prototype.stopPropagation.call(this);\n\t}\n\n\t/**\n\t * Checks if the given element supports the given event type.\n\t * @param {!Element|string} element The DOM element or element tag name to check.\n\t * @param {string} eventName The name of the event to check.\n\t * @return {boolean}\n\t */\n\tstatic supportsEvent(element, eventName) {\n\t\tif (dom.customEvents[eventName]) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (core.isString(element)) {\n\t\t\tif (!elementsByTag[element]) {\n\t\t\t\telementsByTag[element] = document.createElement(element);\n\t\t\t}\n\t\t\telement = elementsByTag[element];\n\t\t}\n\t\treturn 'on' + eventName in element;\n\t}\n\n\t/**\n\t * Converts the given argument to a DOM element. Strings are assumed to\n\t * be selectors, and so a matched element will be returned. If the arg\n\t * is already a DOM element it will be the return value.\n\t * @param {string|Element|Document} selectorOrElement\n\t * @return {Element} The converted element, or null if none was found.\n\t */\n\tstatic toElement(selectorOrElement) {\n\t\tif (core.isElement(selectorOrElement) || core.isDocument(selectorOrElement)) {\n\t\t\treturn selectorOrElement;\n\t\t} else if (core.isString(selectorOrElement)) {\n\t\t\tif (selectorOrElement[0] === '#' && selectorOrElement.indexOf(' ') === -1) {\n\t\t\t\treturn document.getElementById(selectorOrElement.substr(1));\n\t\t\t} else {\n\t\t\t\treturn document.querySelector(selectorOrElement);\n\t\t\t}\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Adds or removes one or more classes from an element. If any of the classes\n\t * is present, it will be removed from the element, or added otherwise.\n\t * @param {!Element} element The element which classes will be toggled.\n\t * @param {string} classes The classes which have to added or removed from the element.\n\t */\n\tstatic toggleClasses(element, classes) {\n\t\tif (!core.isObject(element) || !core.isString(classes)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ('classList' in element) {\n\t\t\tdom.toggleClassesWithNative_(element, classes);\n\t\t} else {\n\t\t\tdom.toggleClassesWithoutNative_(element, classes);\n\t\t}\n\t}\n\n\t/**\n\t * Adds or removes one or more classes from an element using classList.\n\t * If any of the classes is present, it will be removed from the element,\n\t * or added otherwise.\n\t * @param {!Element} element The element which classes will be toggled.\n\t * @param {string} classes The classes which have to added or removed from the element.\n\t */\n\tstatic toggleClassesWithNative_(element, classes) {\n\t\tclasses.split(' ').forEach(function(className) {\n\t\t\telement.classList.toggle(className);\n\t\t});\n\t}\n\n\t/**\n\t * Adds or removes one or more classes from an element without using classList.\n\t * If any of the classes is present, it will be removed from the element,\n\t * or added otherwise.\n\t * @param {!Element} element The element which classes will be toggled.\n\t * @param {string} classes The classes which have to added or removed from the element.\n\t */\n\tstatic toggleClassesWithoutNative_(element, classes) {\n\t\tvar elementClassName = ' ' + element.className + ' ';\n\n\t\tclasses = classes.split(' ');\n\n\t\tfor (var i = 0; i < classes.length; i++) {\n\t\t\tvar className = ' ' + classes[i] + ' ';\n\t\t\tvar classIndex = elementClassName.indexOf(className);\n\n\t\t\tif (classIndex === -1) {\n\t\t\t\telementClassName = elementClassName + classes[i] + ' ';\n\t\t\t} else {\n\t\t\t\telementClassName = elementClassName.substring(0, classIndex) + ' ' +\n\t\t\t\t\telementClassName.substring(classIndex + className.length);\n\t\t\t}\n\t\t}\n\n\t\telement.className = elementClassName.trim();\n\t}\n\n\t/**\n\t * Triggers the specified event on the given element.\n\t * NOTE: This should mostly be used for testing, not on real code.\n\t * @param {!Element} element The node that should trigger the event.\n\t * @param {string} eventName The name of the event to be triggred.\n\t * @param {Object=} opt_eventObj An object with data that should be on the\n\t * triggered event's payload.\n\t */\n\tstatic triggerEvent(element, eventName, opt_eventObj) {\n\t\tvar eventObj = document.createEvent('HTMLEvents');\n\t\teventObj.initEvent(eventName, true, true);\n\t\tobject.mixin(eventObj, opt_eventObj);\n\t\telement.dispatchEvent(eventObj);\n\t}\n\n\t/**\n\t * Triggers the given listeners array.\n\t * @param {Array} Array of collected values.\n\t * TODO(*): Rethink superclass loop.\n\t */\n\tstatic collectSuperClassesProperty(constructor, propertyName) {\n\t\tvar propertyValues = [constructor[propertyName]];\n\t\twhile (constructor.__proto__ && !constructor.__proto__.isPrototypeOf(Function)) {\n\t\t\tconstructor = constructor.__proto__;\n\t\t\tpropertyValues.push(constructor[propertyName]);\n\t\t}\n\t\treturn propertyValues;\n\t}\n\n\t/**\n\t * Gets the name of the given function. If the current browser doesn't\n\t * support the `name` property, this will calculate it from the function's\n\t * content string.\n\t * @param {!function()} fn\n\t * @return {string}\n\t */\n\tstatic getFunctionName(fn) {\n\t\tif (!fn.name) {\n\t\t\tvar str = fn.toString();\n\t\t\tfn.name = str.substring(9, str.indexOf('('));\n\t\t}\n\t\treturn fn.name;\n\t}\n\n\t/**\n\t * Gets an unique id. If `opt_object` argument is passed, the object is\n\t * mutated with an unique id. Consecutive calls with the same object\n\t * reference won't mutate the object again, instead the current object uid\n\t * returns. See {@link core.UID_PROPERTY}.\n\t * @type {opt_object} Optional object to be mutated with the uid. If not\n\t * specified this method only returns the uid.\n\t * @throws {Error} when invoked to indicate the method should be overridden.\n\t */\n\tstatic getUid(opt_object) {\n\t\tif (opt_object) {\n\t\t\treturn opt_object[core.UID_PROPERTY] ||\n\t\t\t\t(opt_object[core.UID_PROPERTY] = core.uniqueIdCounter_++);\n\t\t}\n\t\treturn core.uniqueIdCounter_++;\n\t}\n\n\t/**\n\t * The identity function. Returns its first argument.\n\t * @param {*=} opt_returnValue The single value that will be returned.\n\t * @return {?} The first argument.\n\t */\n\tstatic identityFunction(opt_returnValue) {\n\t\treturn opt_returnValue;\n\t}\n\n\t/**\n\t * Returns true if the specified value is a boolean.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is boolean.\n\t */\n\tstatic isBoolean(val) {\n\t\treturn typeof val === 'boolean';\n\t}\n\n\t/**\n\t * Returns true if the specified value is not undefined.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is defined.\n\t */\n\tstatic isDef(val) {\n\t\treturn val !== undefined;\n\t}\n\n\t/**\n\t * Returns true if value is not undefined or null.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isDefAndNotNull(val) {\n\t\treturn core.isDef(val) && !core.isNull(val);\n\t}\n\n\t/**\n\t * Returns true if value is a document.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isDocument(val) {\n\t\treturn val && typeof val === 'object' && val.nodeType === 9;\n\t}\n\n\t/**\n\t * Returns true if value is a dom element.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isElement(val) {\n\t\treturn val && typeof val === 'object' && val.nodeType === 1;\n\t}\n\n\t/**\n\t * Returns true if the specified value is a function.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is a function.\n\t */\n\tstatic isFunction(val) {\n\t\treturn typeof val === 'function';\n\t}\n\n\t/**\n\t * Returns true if value is null.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isNull(val) {\n\t\treturn val === null;\n\t}\n\n\t/**\n\t * Returns true if the specified value is a number.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is a number.\n\t */\n\tstatic isNumber(val) {\n\t\treturn typeof val === 'number';\n\t}\n\n\t/**\n\t * Returns true if value is a window.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isWindow(val) {\n\t\treturn val !== null && val === val.window;\n\t}\n\n\t/**\n\t * Returns true if the specified value is an object. This includes arrays\n\t * and functions.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is an object.\n\t */\n\tstatic isObject(val) {\n\t\tvar type = typeof val;\n\t\treturn type === 'object' && val !== null || type === 'function';\n\t}\n\n\t/**\n\t * Returns true if value is a Promise.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isPromise(val) {\n\t\treturn val && typeof val === 'object' && typeof val.then === 'function';\n\t}\n\n\t/**\n\t * Returns true if value is a string.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isString(val) {\n\t\treturn typeof val === 'string';\n\t}\n\n\t/**\n\t * Merges the values of a static property a class with the values of that\n\t * property for all its super classes, and stores it as a new static\n\t * property of that class. If the static property already existed, it won't\n\t * be recalculated.\n\t * @param {!function()} constructor Class constructor.\n\t * @param {string} propertyName Property name to be collected.\n\t * @param {function(*, *):*=} opt_mergeFn Function that receives an array filled\n\t * with the values of the property for the current class and all its super classes.\n\t * Should return the merged value to be stored on the current class.\n\t * @return {boolean} Returns true if merge happens, false otherwise.\n\t */\n\tstatic mergeSuperClassesProperty(constructor, propertyName, opt_mergeFn) {\n\t\tvar mergedName = propertyName + '_MERGED';\n\t\tif (constructor.hasOwnProperty(mergedName)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar merged = core.collectSuperClassesProperty(constructor, propertyName);\n\t\tif (opt_mergeFn) {\n\t\t\tmerged = opt_mergeFn(merged);\n\t\t}\n\t\tconstructor[mergedName] = merged;\n\t\treturn true;\n\t}\n\n\t/**\n\t * Null function used for default values of callbacks, etc.\n\t * @return {void} Nothing.\n\t */\n\tstatic nullFunction() {}\n}\n\n/**\n * Unique id property prefix.\n * @type {String}\n * @protected\n */\ncore.UID_PROPERTY = 'core_' + ((Math.random() * 1e9) >>> 0);\n\n/**\n * Counter for unique id.\n * @type {Number}\n * @private\n */\ncore.uniqueIdCounter_ = 1;\n\nexport default core;\n"],"sourceRoot":"/source/"}
\ No newline at end of file
+{"version":3,"sources":["core.js"],"names":[],"mappings":"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","file":"node_modules/metal/src/core.js","sourcesContent":["'use strict';\n\n/**\n * A collection of core utility functions.\n * @const\n */\nclass core {\n\t/**\n\t * When defining a class Foo with an abstract method bar(), you can do:\n\t * Foo.prototype.bar = core.abstractMethod\n\t *\n\t * Now if a subclass of Foo fails to override bar(), an error will be thrown\n\t * when bar() is invoked.\n\t *\n\t * @type {!Function}\n\t * @throws {Error} when invoked to indicate the method should be overridden.\n\t */\n\tstatic abstractMethod() {\n\t\tthrow Error('Unimplemented abstract method');\n\t}\n\n\t/**\n\t * Loops constructor super classes collecting its properties values. If\n\t * property is not available on the super class `undefined` will be\n\t * collected as value for the class hierarchy position.\n\t * @param {!function()} constructor Class constructor.\n\t * @param {string} propertyName Property name to be collected.\n\t * @return {Array.<*>} Array of collected values.\n\t * TODO(*): Rethink superclass loop.\n\t */\n\tstatic collectSuperClassesProperty(constructor, propertyName) {\n\t\tvar propertyValues = [constructor[propertyName]];\n\t\twhile (constructor.__proto__ && !constructor.__proto__.isPrototypeOf(Function)) {\n\t\t\tconstructor = constructor.__proto__;\n\t\t\tpropertyValues.push(constructor[propertyName]);\n\t\t}\n\t\treturn propertyValues;\n\t}\n\n\t/**\n\t * Gets the name of the given function. If the current browser doesn't\n\t * support the `name` property, this will calculate it from the function's\n\t * content string.\n\t * @param {!function()} fn\n\t * @return {string}\n\t */\n\tstatic getFunctionName(fn) {\n\t\tif (!fn.name) {\n\t\t\tvar str = fn.toString();\n\t\t\tfn.name = str.substring(9, str.indexOf('('));\n\t\t}\n\t\treturn fn.name;\n\t}\n\n\t/**\n\t * Gets an unique id. If `opt_object` argument is passed, the object is\n\t * mutated with an unique id. Consecutive calls with the same object\n\t * reference won't mutate the object again, instead the current object uid\n\t * returns. See {@link core.UID_PROPERTY}.\n\t * @param {Object=} opt_object Optional object to be mutated with the uid. If\n\t * not specified this method only returns the uid.\n\t * @param {boolean=} opt_noInheritance Optional flag indicating if this\n\t * object's uid property can be inherited from parents or not.\n\t * @throws {Error} when invoked to indicate the method should be overridden.\n\t */\n\tstatic getUid(opt_object, opt_noInheritance) {\n\t\tif (opt_object) {\n\t\t\tvar id = opt_object[core.UID_PROPERTY];\n\t\t\tif (opt_noInheritance && !opt_object.hasOwnProperty(core.UID_PROPERTY)) {\n\t\t\t\tid = null;\n\t\t\t}\n\t\t\treturn id || (opt_object[core.UID_PROPERTY] = core.uniqueIdCounter_++);\n\t\t}\n\t\treturn core.uniqueIdCounter_++;\n\t}\n\n\t/**\n\t * The identity function. Returns its first argument.\n\t * @param {*=} opt_returnValue The single value that will be returned.\n\t * @return {?} The first argument.\n\t */\n\tstatic identityFunction(opt_returnValue) {\n\t\treturn opt_returnValue;\n\t}\n\n\t/**\n\t * Returns true if the specified value is a boolean.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is boolean.\n\t */\n\tstatic isBoolean(val) {\n\t\treturn typeof val === 'boolean';\n\t}\n\n\t/**\n\t * Returns true if the specified value is not undefined.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is defined.\n\t */\n\tstatic isDef(val) {\n\t\treturn val !== undefined;\n\t}\n\n\t/**\n\t * Returns true if value is not undefined or null.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isDefAndNotNull(val) {\n\t\treturn core.isDef(val) && !core.isNull(val);\n\t}\n\n\t/**\n\t * Returns true if value is a document.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isDocument(val) {\n\t\treturn val && typeof val === 'object' && val.nodeType === 9;\n\t}\n\n\t/**\n\t * Returns true if value is a dom element.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isElement(val) {\n\t\treturn val && typeof val === 'object' && val.nodeType === 1;\n\t}\n\n\t/**\n\t * Returns true if the specified value is a function.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is a function.\n\t */\n\tstatic isFunction(val) {\n\t\treturn typeof val === 'function';\n\t}\n\n\t/**\n\t * Returns true if value is null.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isNull(val) {\n\t\treturn val === null;\n\t}\n\n\t/**\n\t * Returns true if the specified value is a number.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is a number.\n\t */\n\tstatic isNumber(val) {\n\t\treturn typeof val === 'number';\n\t}\n\n\t/**\n\t * Returns true if value is a window.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isWindow(val) {\n\t\treturn val !== null && val === val.window;\n\t}\n\n\t/**\n\t * Returns true if the specified value is an object. This includes arrays\n\t * and functions.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is an object.\n\t */\n\tstatic isObject(val) {\n\t\tvar type = typeof val;\n\t\treturn type === 'object' && val !== null || type === 'function';\n\t}\n\n\t/**\n\t * Returns true if value is a Promise.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isPromise(val) {\n\t\treturn val && typeof val === 'object' && typeof val.then === 'function';\n\t}\n\n\t/**\n\t * Returns true if value is a string.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isString(val) {\n\t\treturn typeof val === 'string';\n\t}\n\n\t/**\n\t * Merges the values of a static property a class with the values of that\n\t * property for all its super classes, and stores it as a new static\n\t * property of that class. If the static property already existed, it won't\n\t * be recalculated.\n\t * @param {!function()} constructor Class constructor.\n\t * @param {string} propertyName Property name to be collected.\n\t * @param {function(*, *):*=} opt_mergeFn Function that receives an array filled\n\t * with the values of the property for the current class and all its super classes.\n\t * Should return the merged value to be stored on the current class.\n\t * @return {boolean} Returns true if merge happens, false otherwise.\n\t */\n\tstatic mergeSuperClassesProperty(constructor, propertyName, opt_mergeFn) {\n\t\tvar mergedName = propertyName + '_MERGED';\n\t\tif (constructor.hasOwnProperty(mergedName)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar merged = core.collectSuperClassesProperty(constructor, propertyName);\n\t\tif (opt_mergeFn) {\n\t\t\tmerged = opt_mergeFn(merged);\n\t\t}\n\t\tconstructor[mergedName] = merged;\n\t\treturn true;\n\t}\n\n\t/**\n\t * Null function used for default values of callbacks, etc.\n\t * @return {void} Nothing.\n\t */\n\tstatic nullFunction() {}\n}\n\n/**\n * Unique id property prefix.\n * @type {String}\n * @protected\n */\ncore.UID_PROPERTY = 'core_' + ((Math.random() * 1e9) >>> 0);\n\n/**\n * Counter for unique id.\n * @type {Number}\n * @private\n */\ncore.uniqueIdCounter_ = 1;\n\nexport default core;\n"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/build/amd/senna/src/app/App.js b/build/amd/senna/src/app/App.js
index 5526990..9fca50f 100644
--- a/build/amd/senna/src/app/App.js
+++ b/build/amd/senna/src/app/App.js
@@ -528,11 +528,6 @@ define(['exports', 'metal/src/metal', 'metal-dom/src/all/dom', 'metal-promise/sr
return;
}
- if (this.allowPreventNavigate && event.defaultPrevented) {
- void 0;
- return;
- }
-
_globals2.default.capturedFormElement = event.capturedFormElement;
var navigateFailed = false;
@@ -801,7 +796,7 @@ define(['exports', 'metal/src/metal', 'metal-dom/src/all/dom', 'metal-promise/sr
if (this.formEventHandler_) {
this.formEventHandler_.removeListener();
}
- this.formEventHandler_ = _dom2.default.delegate(document, 'submit', this.formSelector, this.onDocSubmitDelegate_.bind(this));
+ this.formEventHandler_ = _dom2.default.delegate(document, 'submit', this.formSelector, this.onDocSubmitDelegate_.bind(this), this.allowPreventNavigate);
};
App.prototype.setLinkSelector = function setLinkSelector(linkSelector) {
@@ -809,7 +804,7 @@ define(['exports', 'metal/src/metal', 'metal-dom/src/all/dom', 'metal-promise/sr
if (this.linkEventHandler_) {
this.linkEventHandler_.removeListener();
}
- this.linkEventHandler_ = _dom2.default.delegate(document, 'click', this.linkSelector, this.onDocClickDelegate_.bind(this));
+ this.linkEventHandler_ = _dom2.default.delegate(document, 'click', this.linkSelector, this.onDocClickDelegate_.bind(this), this.allowPreventNavigate);
};
App.prototype.setLoadingCssClass = function setLoadingCssClass(loadingCssClass) {
diff --git a/build/amd/senna/src/app/App.js.map b/build/amd/senna/src/app/App.js.map
index 65a1ba6..c72a2c2 100644
--- a/build/amd/senna/src/app/App.js.map
+++ b/build/amd/senna/src/app/App.js.map
@@ -1 +1 @@
-{"version":3,"sources":["App.js"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAaM,G;;;;;;;;;AAOL,iBAAc;AAAA;;AAAA,gDACb,wBADa;;;;;;;AAQb,SAAK,YAAL,GAAoB,IAApB;;;;;;;AAOA,SAAK,UAAL,GAAkB,IAAlB;;;;;;;;AAQA,SAAK,oBAAL,GAA4B,IAA5B;;;;;;;;AAQA,SAAK,QAAL,GAAgB,EAAhB;;;;;;;;AAQA,SAAK,oCAAL,GAA4C,IAA5C;;;;;;;;AAQA,SAAK,YAAL,GAAoB,kBAAQ,QAAR,CAAiB,KAArC;;;;;;;;AAQA,SAAK,YAAL,GAAoB,2DAApB;;;;;;;;AAQA,SAAK,YAAL,GAAoB,yBAApB;;;;;;;;AAQA,SAAK,eAAL,GAAuB,eAAvB;;;;;;;;;;;;;;;AAeA,SAAK,gCAAL,GAAyC,uBAAuB,kBAAQ,MAAR,CAAe,OAA/E;;;;;;;;AAQA,SAAK,eAAL,GAAuB,IAAvB;;;;;;;;;AASA,SAAK,kBAAL,GAA0B,CAA1B;;;;;;;;;AASA,SAAK,iBAAL,GAAyB,CAAzB;;;;;;;AAOA,SAAK,YAAL,GAAoB,IAApB;;;;;;;;AAQA,SAAK,MAAL,GAAc,EAAd;;;;;;;;AAQA,SAAK,OAAL,GAAe,EAAf;;;;;;;;;;AAUA,SAAK,gBAAL,GAAwB,KAAxB;;;;;;;;AAQA,SAAK,QAAL,GAAgB,EAAhB;;;;;;;;;;AAUA,SAAK,oBAAL,GAA4B,IAA5B;;AAEA,SAAK,iBAAL,GAAyB,0BAAzB;;AAEA,SAAK,iBAAL,CAAuB,GAAvB,CACC,cAAI,EAAJ,CAAO,kBAAQ,MAAf,EAAuB,QAAvB,EAAiC,MAAK,SAAL,CAAe,IAAf,OAAjC,CADD,EAEC,cAAI,EAAJ,CAAO,kBAAQ,MAAf,EAAuB,MAAvB,EAA+B,MAAK,OAAL,CAAa,IAAb,OAA/B,CAFD,EAGC,cAAI,EAAJ,CAAO,kBAAQ,MAAf,EAAuB,UAAvB,EAAmC,MAAK,WAAL,CAAiB,IAAjB,OAAnC,CAHD;;AAMA,SAAK,EAAL,CAAQ,eAAR,EAAyB,MAAK,gBAA9B;AACA,SAAK,EAAL,CAAQ,gBAAR,EAA0B,MAAK,iBAA/B;AACA,SAAK,EAAL,CAAQ,gBAAR,EAA0B,MAAK,wBAA/B,EAAyD,IAAzD;;AAEA,SAAK,eAAL,CAAqB,MAAK,YAA1B;AACA,SAAK,eAAL,CAAqB,MAAK,YAA1B;AAlLa;AAmLb;;;;;;;;;;;;;;;;;;;;;;;gBAqBD,S,sBAAU,M,EAAQ;AAAA;;AACjB,OAAI,CAAC,MAAM,OAAN,CAAc,MAAd,CAAL,EAA4B;AAC3B,aAAS,CAAC,MAAD,CAAT;AACA;AACD,UAAO,OAAP,CAAe,UAAC,KAAD,EAAW;AACzB,QAAI,EAAE,gCAAF,CAAJ,EAA+B;AAC9B,aAAQ,oBAAU,MAAM,IAAhB,EAAsB,MAAM,OAA5B,CAAR;AACA;AACD,WAAK,MAAL,CAAY,IAAZ,CAAiB,KAAjB;AACA,IALD;AAMA,UAAO,IAAP;AACA,G;;gBAUD,W,wBAAY,Q,EAAU;AAAA;;AACrB,OAAI,CAAC,MAAM,OAAN,CAAc,QAAd,CAAL,EAA8B;AAC7B,eAAW,CAAC,QAAD,CAAX;AACA;AACD,YAAS,OAAT,CAAiB,UAAC,OAAD,EAAa;AAC7B,QAAI,YAAK,QAAL,CAAc,OAAd,CAAJ,EAA4B;AAC3B,eAAU,sBAAY,OAAZ,CAAV;AACA;AACD,WAAK,QAAL,CAAc,QAAQ,KAAR,EAAd,IAAiC,OAAjC;AACA,IALD;AAMA,UAAO,IAAP;AACA,G;;gBAOD,W,wBAAY,G,EAAK;AAChB,OAAI,OAAO,gBAAM,UAAN,CAAiB,GAAjB,CAAX;AACA,OAAI,MAAM,kBAAQ,GAAR,CAAV;;AAEA,OAAI,CAAC,KAAK,iBAAL,CAAuB,IAAI,WAAJ,EAAvB,CAAL,EAAgD;AAC/C,YAAQ,GAAR,CAAY,sBAAZ;AACA,WAAO,KAAP;AACA;AACD,OAAI,CAAC,KAAK,eAAL,CAAqB,IAArB,CAAL,EAAiC;AAChC,YAAQ,GAAR,CAAY,uCAAZ;AACA,WAAO,KAAP;AACA;AACD,OAAI,CAAC,KAAK,SAAL,CAAe,IAAf,CAAL,EAA2B;AAC1B,YAAQ,GAAR,CAAY,kBAAkB,IAA9B;AACA,WAAO,KAAP;AACA;;AAED,UAAO,IAAP;AACA,G;;gBAMD,iB,gCAAoB;AAAA;;AACnB,UAAO,IAAP,CAAY,KAAK,OAAjB,EAA0B,OAA1B,CAAkC,UAAC,IAAD,EAAU;AAC3C,QAAI,SAAS,OAAK,UAAlB,EAA8B;AAC7B,YAAK,YAAL,CAAkB,UAAlB;AACA,KAFD,MAEO;AACN,YAAK,YAAL,CAAkB,IAAlB;AACA;AACD,IAND;AAOA,G;;gBAOD,oB,iCAAqB,I,EAAM,K,EAAO;AACjC,OAAI,CAAC,KAAK,eAAN,IAAyB,SAAS,KAAK,UAA3C,EAAuD;AACtD,YAAQ,GAAR,CAAY,4CAAZ;AACA,WAAO,KAAK,YAAZ;AACA;;AAED,OAAI,SAAS,KAAK,OAAL,CAAa,IAAb,CAAb;AACA,OAAI,CAAC,MAAL,EAAa;AACZ,QAAI,UAAU,MAAM,UAAN,EAAd;AACA,QAAI,gCAAsB,iBAAO,eAAP,CAAuB,QAAQ,SAA/B,CAA1B,EAAqE;AACpE,cAAS,IAAI,OAAJ,EAAT;AACA,KAFD,MAEO;AACN,cAAS,QAAQ,KAAR,KAAkB,sBAA3B;AACA;AACD,YAAQ,GAAR,CAAY,wBAAwB,IAAxB,GAA+B,KAA/B,GAAuC,MAAvC,GAAgD,GAA5D;AACA;AACD,UAAO,MAAP;AACA,G;;gBAKD,e,8BAAkB;AACjB,OAAI,KAAK,YAAT,EAAuB;AACtB,SAAK,YAAL,CAAkB,KAAK,UAAvB;AACA;AACD,QAAK,iBAAL;AACA,QAAK,iBAAL,CAAuB,cAAvB;AACA,QAAK,iBAAL,CAAuB,cAAvB;AACA,QAAK,iBAAL,CAAuB,kBAAvB;AACA,2BAAM,eAAN;AACA,G;;gBAOD,Q,uBAAW;AACV,UAAO,KAAK,QAAL,CAAc,gBAAM,qBAAN,EAAd,EAA6C,IAA7C,CAAP;AACA,G;;gBAQD,W,wBAAY,I,EAAM,kB,EAAoB;AAAA;;AACrC,OAAI,KAAK,YAAL,IAAqB,KAAK,YAAL,CAAkB,gBAAlB,EAAzB,EAA+D;AAC9D,SAAK,eAAL,GAAuB,kBAAmB,MAAnB,CAA0B,IAAI,kBAAmB,iBAAvB,CAAyC,4BAAzC,CAA1B,CAAvB;AACA,WAAO,KAAK,eAAZ;AACA;;AAED,OAAI,QAAQ,KAAK,SAAL,CAAe,IAAf,CAAZ;AACA,OAAI,CAAC,KAAL,EAAY;AACX,SAAK,eAAL,GAAuB,kBAAmB,MAAnB,CAA0B,IAAI,kBAAmB,iBAAvB,CAAyC,kBAAkB,IAA3D,CAA1B,CAAvB;AACA,WAAO,KAAK,eAAZ;AACA;;AAED,WAAQ,GAAR,CAAY,kBAAkB,IAAlB,GAAyB,GAArC;;AAEA,QAAK,oBAAL;;AAEA,OAAI,aAAa,KAAK,oBAAL,CAA0B,IAA1B,EAAgC,KAAhC,CAAjB;;AAEA,UAAO,WAAW,IAAX,CAAgB,IAAhB,EACL,IADK,CACA,YAAM;AACX,QAAI,OAAK,YAAT,EAAuB;AACtB,YAAK,YAAL,CAAkB,UAAlB;AACA;AACD,WAAK,uBAAL,CAA6B,IAA7B,EAAmC,UAAnC,EAA+C,kBAA/C;AACA,WAAK,wBAAL,CAA8B,UAA9B,EAA0C,OAAK,QAA/C;AACA,IAPK,EAQL,IARK,CAQA;AAAA,WAAM,WAAW,cAAX,CAA0B,OAAK,QAA/B,CAAN;AAAA,IARA,EASL,IATK,CASA;AAAA,WAAM,WAAW,IAAX,CAAgB,OAAK,QAArB,CAAN;AAAA,IATA,EAUL,IAVK,CAUA;AAAA,WAAM,WAAW,eAAX,CAA2B,OAAK,QAAhC,CAAN;AAAA,IAVA,EAWL,IAXK,CAWA;AAAA,WAAM,OAAK,gCAAL,EAAN;AAAA,IAXA,EAYL,IAZK,CAYA;AAAA,WAAM,OAAK,iBAAL,CAAuB,IAAvB,EAA6B,UAA7B,CAAN;AAAA,IAZA,EAaL,KAbK,CAaC,UAAC,MAAD,EAAY;AAClB,WAAK,oBAAL,CAA0B,IAA1B,EAAgC,UAAhC,EAA4C,MAA5C;AACA,UAAM,MAAN;AACA,IAhBK,CAAP;AAiBA,G;;gBAQD,iB,8BAAkB,I,EAAM,U,EAAY;AACnC,cAAW,QAAX;;AAEA,OAAI,KAAK,YAAL,IAAqB,CAAC,KAAK,YAAL,CAAkB,WAAlB,EAA1B,EAA2D;AAC1D,QAAI,KAAK,YAAL,KAAsB,UAA1B,EAAsC;AACrC,UAAK,YAAL,CAAkB,KAAK,UAAvB;AACA;AACD;;AAED,QAAK,UAAL,GAAkB,IAAlB;AACA,QAAK,YAAL,GAAoB,UAApB;AACA,QAAK,OAAL,CAAa,IAAb,IAAqB,UAArB;AACA,QAAK,eAAL,GAAuB,IAAvB;AACA,qBAAQ,mBAAR,GAA8B,IAA9B;AACA,WAAQ,GAAR,CAAY,iBAAZ;AACA,G;;gBASD,S,sBAAU,I,EAAM;;AAEf,OAAK,KAAK,WAAL,CAAiB,GAAjB,IAAwB,CAAC,CAA1B,IAAgC,gBAAM,oBAAN,CAA2B,IAA3B,CAApC,EAAsE;AACrE,WAAO,IAAP;AACA;;AAED,UAAO,gBAAM,qBAAN,CAA4B,IAA5B,CAAP;;;;AAIA,UAAO,gBAAM,qBAAN,CAA4B,KAAK,MAAL,CAAY,KAAK,QAAL,CAAc,MAA1B,CAA5B,CAAP;;AAEA,QAAK,IAAI,IAAI,CAAb,EAAgB,IAAI,KAAK,MAAL,CAAY,MAAhC,EAAwC,GAAxC,EAA6C;AAC5C,QAAI,QAAQ,KAAK,MAAL,CAAY,CAAZ,CAAZ;AACA,QAAI,MAAM,WAAN,CAAkB,IAAlB,CAAJ,EAA6B;AAC5B,YAAO,KAAP;AACA;AACD;;AAED,UAAO,IAAP;AACA,G;;gBAMD,uB,sCAA0B;AACzB,UAAO,KAAK,oBAAZ;AACA,G;;gBAMD,W,0BAAc;AACb,UAAO,KAAK,QAAZ;AACA,G;;gBAMD,e,8BAAkB;AACjB,UAAO,KAAK,YAAZ;AACA,G;;gBAMD,e,8BAAkB;AACjB,UAAO,KAAK,YAAZ;AACA,G;;gBAMD,e,8BAAkB;AACjB,UAAO,KAAK,YAAZ;AACA,G;;gBAMD,kB,iCAAqB;AACpB,UAAO,KAAK,eAAZ;AACA,G;;gBAMD,uB,sCAA0B;AACzB,UAAO,KAAK,oBAAZ;AACA,G;;gBASD,oB,iCAAqB,I,EAAM,U,EAAY,G,EAAK;AAC3C,WAAQ,GAAR,CAAY,2BAA2B,UAA3B,GAAwC,KAAxC,GAAgD,GAAhD,GAAsD,GAAlE;AACA,OAAI,CAAC,gBAAM,oBAAN,CAA2B,IAA3B,CAAL,EAAuC;AACtC,SAAK,YAAL,CAAkB,IAAlB;AACA;AACD,G;;gBAMD,S,wBAAY;AACX,UAAO,KAAK,MAAL,CAAY,MAAZ,GAAqB,CAA5B;AACA,G;;gBASD,iB,8BAAkB,Q,EAAU;AAC3B,UAAO,aAAa,kBAAQ,MAAR,CAAe,QAAf,CAAwB,QAA5C;AACA,G;;gBAQD,e,4BAAgB,I,EAAM;AACrB,UAAO,KAAK,OAAL,CAAa,KAAK,QAAlB,MAAgC,CAAvC;AACA,G;;gBAQD,0B,yCAA6B;AAC5B,OAAI,QAAQ,kBAAQ,MAAR,CAAe,OAAf,CAAuB,KAAnC;AACA,OAAI,CAAC,KAAL,EAAY;AACX;AACA;;;;;;;;;AASD,OAAI,SAAS,KAAb;AACA,OAAI,2BAA2B,SAA3B,wBAA2B,GAAW;AACzC,sBAAQ,QAAR,CAAiB,mBAAjB,CAAqC,QAArC,EAA+C,wBAA/C,EAAyE,KAAzE;AACA,QAAI,CAAC,MAAL,EAAa;AACZ,uBAAQ,MAAR,CAAe,QAAf,CAAwB,MAAM,UAA9B,EAA0C,MAAM,SAAhD;AACA,cAAS,IAAT;AACA;AACD,IAND;AAOA,gBAAM,QAAN,CAAe,wBAAf;AACA,qBAAQ,QAAR,CAAiB,gBAAjB,CAAkC,QAAlC,EAA4C,wBAA5C,EAAsE,KAAtE;AACA,G;;gBAMD,mC,kDAAsC;AACrC,OAAI,KAAK,gCAAT,EAA2C;AAC1C,SAAK,wBAAL,GAAgC,kBAAQ,MAAR,CAAe,OAAf,CAAuB,iBAAvD;AACA,sBAAQ,MAAR,CAAe,OAAf,CAAuB,iBAAvB,GAA2C,QAA3C;AACA;AACD,G;;gBAOD,c,2BAAe,I,EAAM,K,EAAO;AAC3B,OAAI,CAAC,KAAK,WAAL,CAAiB,IAAjB,CAAL,EAA6B;AAC5B;AACA;;AAED,OAAI,KAAK,oBAAL,IAA6B,MAAM,gBAAvC,EAAyD;AACxD,YAAQ,GAAR,CAAY,oBAAZ;AACA;AACA;;AAED,qBAAQ,mBAAR,GAA8B,MAAM,mBAApC;;AAEA,OAAI,iBAAiB,KAArB;AACA,OAAI;AACH,SAAK,QAAL,CAAc,gBAAM,UAAN,CAAiB,IAAjB,CAAd;AACA,IAFD,CAEE,OAAO,GAAP,EAAY;;AAEb,qBAAiB,IAAjB;AACA;;AAED,OAAI,CAAC,cAAL,EAAqB;AACpB,UAAM,cAAN;AACA;AACD,G;;gBAKD,mC,kDAAsC;AACrC,OAAI,OAAO,kBAAQ,MAAR,CAAe,QAAf,CAAwB,IAAnC;AACA,OAAI,IAAJ,EAAU;AACT,QAAI,gBAAgB,kBAAQ,QAAR,CAAiB,cAAjB,CAAgC,KAAK,SAAL,CAAe,CAAf,CAAhC,CAApB;AACA,QAAI,aAAJ,EAAmB;AAClB,uBAAQ,MAAR,CAAe,QAAf,CAAwB,cAAc,UAAtC,EAAkD,cAAc,SAAhE;AACA;AACD;AACD,G;;gBAMD,mC,kDAAsC;AACrC,OAAI,KAAK,gCAAL,IAAyC,KAAK,wBAAlD,EAA4E;AAC3E,sBAAQ,MAAR,CAAe,OAAf,CAAuB,iBAAvB,GAA2C,KAAK,wBAAhD;AACA;AACD,G;;gBAQD,Q,qBAAS,I,EAAM,kB,EAAoB;AAClC,OAAI,CAAC,gBAAM,uBAAN,EAAL,EAAsC;AACrC,UAAM,IAAI,KAAJ,CAAU,sEAAV,CAAN;AACA;;;;AAID,OAAI,SAAS,KAAK,UAAlB,EAA8B;AAC7B,yBAAqB,IAArB;AACA;;AAED,QAAK,IAAL,CAAU,gBAAV,EAA4B;AAC3B,UAAM,IADqB;AAE3B,oBAAgB,CAAC,CAAC;AAFS,IAA5B;;AAKA,UAAO,KAAK,eAAZ;AACA,G;;gBAQD,iB,8BAAkB,K,EAAO;AACxB,OAAI,kBAAQ,mBAAZ,EAAiC;AAChC,UAAM,IAAN,GAAa,kBAAQ,mBAArB;AACA;AACD,G;;gBAQD,wB,qCAAyB,K,EAAO;AAC/B,OAAI,KAAK,eAAT,EAA0B;AACzB,QAAI,KAAK,eAAL,CAAqB,IAArB,KAA8B,MAAM,IAAxC,EAA8C;AAC7C,aAAQ,GAAR,CAAY,YAAZ;AACA;AACA;AACD;;AAED,QAAK,IAAL,CAAU,eAAV,EAA2B;AAC1B,UAAM,MAAM,IADc;AAE1B,UAAM,MAAM,IAFc;AAG1B,oBAAgB,MAAM;AAHI,IAA3B;AAKA,G;;gBAQD,mB,gCAAoB,K,EAAO;AAC1B,OAAI,MAAM,MAAN,IAAgB,MAAM,OAAtB,IAAiC,MAAM,OAAvC,IAAkD,MAAM,QAAxD,IAAoE,MAAM,MAA9E,EAAsF;AACrF,YAAQ,GAAR,CAAY,iEAAZ;AACA;AACA;AACD,QAAK,cAAL,CAAoB,MAAM,cAAN,CAAqB,IAAzC,EAA+C,KAA/C;AACA,G;;gBAQD,oB,iCAAqB,K,EAAO;AAC3B,OAAI,OAAO,MAAM,cAAjB;AACA,OAAI,KAAK,MAAL,KAAgB,KAApB,EAA2B;AAC1B,YAAQ,GAAR,CAAY,0BAAZ;AACA;AACA;AACD,SAAM,mBAAN,GAA4B,IAA5B;AACA,QAAK,cAAL,CAAoB,KAAK,MAAzB,EAAiC,KAAjC;AACA,G;;gBAQD,O,sBAAU;AAAA;;AACT,QAAK,gBAAL,GAAwB,IAAxB;AACA,cAAW,YAAM;;;AAGhB,WAAK,gBAAL,GAAwB,KAAxB;AACA,IAJD,EAIG,CAJH;;AAMA,QAAK,mCAAL;AACA,G;;gBAWD,W,wBAAY,K,EAAO;AAClB,OAAI,KAAK,gBAAT,EAA2B;AAC1B;AACA;;AAED,OAAI,QAAQ,MAAM,KAAlB;;AAEA,OAAI,CAAC,KAAL,EAAY;AACX,QAAI,kBAAQ,MAAR,CAAe,QAAf,CAAwB,IAA5B,EAAkC;;;;;AAKjC,SAAI,KAAK,YAAL,IAAqB,CAAC,gBAAM,oBAAN,CAA2B,KAAK,YAAhC,CAA1B,EAAyE;AACxE,WAAK,UAAL;AACA;;;AAGD,UAAK,mCAAL;AACA,KAXD,MAWO;AACN,UAAK,UAAL;AACA;AACD;AACA;;AAED,OAAI,MAAM,KAAV,EAAiB;AAChB,YAAQ,GAAR,CAAY,4BAA4B,MAAM,IAAlC,GAAyC,GAArD;AACA,SAAK,iBAAL,GAAyB,MAAM,SAA/B;AACA,SAAK,kBAAL,GAA0B,MAAM,UAAhC;AACA,QAAI,CAAC,KAAK,gCAAV,EAA4C;AAC3C,UAAK,0BAAL;AACA;AACD,SAAK,QAAL,CAAc,MAAM,IAApB,EAA0B,IAA1B;AACA;AACD,G;;gBAOD,S,wBAAY;AACX,OAAI,KAAK,oCAAT,EAA+C;AAC9C,SAAK,qCAAL;AACA;AACD,G;;gBAQD,gB,6BAAiB,K,EAAO;AAAA;;AACvB,QAAK,mCAAL;AACA,QAAK,oCAAL,GAA4C,KAA5C;AACA,iBAAI,UAAJ,CAAe,kBAAQ,QAAR,CAAiB,eAAhC,EAAiD,KAAK,eAAtD;;AAEA,OAAI,qBAAqB;AACxB,UAAM,MAAM,IADY;AAExB,UAAM,MAAM;AAFY,IAAzB;;AAKA,QAAK,eAAL,GAAuB,KAAK,WAAL,CAAiB,MAAM,IAAvB,EAA6B,MAAM,cAAnC,EACrB,KADqB,CACf,UAAC,MAAD,EAAY;AAClB,uBAAmB,KAAnB,GAA2B,MAA3B;AACA,UAAM,MAAN;AACA,IAJqB,EAKrB,UALqB,CAKV,YAAM;AACjB,QAAI,CAAC,OAAK,eAAV,EAA2B;AAC1B,mBAAI,aAAJ,CAAkB,kBAAQ,QAAR,CAAiB,eAAnC,EAAoD,OAAK,eAAzD;AACA,YAAK,mCAAL;AACA,YAAK,oCAAL,GAA4C,IAA5C;AACA;AACD,WAAK,IAAL,CAAU,aAAV,EAAyB,kBAAzB;AACA,IAZqB,CAAvB;;AAcA,QAAK,eAAL,CAAqB,IAArB,GAA4B,MAAM,IAAlC;AACA,G;;gBAOD,Q,qBAAS,I,EAAM;AAAA;;AACd,OAAI,QAAQ,KAAK,SAAL,CAAe,IAAf,CAAZ;AACA,OAAI,CAAC,KAAL,EAAY;AACX,WAAO,kBAAmB,MAAnB,CAA0B,IAAI,kBAAmB,iBAAvB,CAAyC,kBAAkB,IAA3D,CAA1B,CAAP;AACA;;AAED,WAAQ,GAAR,CAAY,kBAAkB,IAAlB,GAAyB,GAArC;;AAEA,OAAI,aAAa,KAAK,oBAAL,CAA0B,IAA1B,EAAgC,KAAhC,CAAjB;;AAEA,UAAO,WAAW,IAAX,CAAgB,IAAhB,EACL,IADK,CACA;AAAA,WAAM,OAAK,OAAL,CAAa,IAAb,IAAqB,UAA3B;AAAA,IADA,EAEL,KAFK,CAEC,UAAC,MAAD,EAAY;AAClB,WAAK,oBAAL,CAA0B,IAA1B,EAAgC,UAAhC,EAA4C,MAA5C;AACA,UAAM,MAAN;AACA,IALK,CAAP;AAMA,G;;gBAQD,uB,oCAAwB,I,EAAM,U,EAAY,kB,EAAoB;AAC7D,OAAI,QAAQ,WAAW,QAAX,EAAZ;AACA,OAAI,CAAC,YAAK,QAAL,CAAc,KAAd,CAAL,EAA2B;AAC1B,YAAQ,KAAK,eAAL,EAAR;AACA;AACD,OAAI,eAAe,WAAW,uBAAX,CAAmC,IAAnC,CAAnB;AACA,OAAI,eAAe;AAClB,UAAM,YAAK,eAAL,CAAqB,kBAAQ,mBAA7B,CADY;AAElB,kBAAc,YAFI;AAGlB,UAAM,IAHY;AAIlB,WAAO,IAJW;AAKlB,eAAW,CALO;AAMlB,gBAAY;AANM,IAAnB;AAQA,OAAI,kBAAJ,EAAwB;AACvB,iBAAa,SAAb,GAAyB,KAAK,iBAA9B;AACA,iBAAa,UAAb,GAA0B,KAAK,kBAA/B;AACA;AACD,QAAK,cAAL,CAAoB,KAApB,EAA2B,YAA3B,EAAyC,WAAW,wBAAX,CAAoC,YAApC,CAAzC,EAA4F,kBAA5F;AACA,QAAK,YAAL,GAAoB,YAApB;AACA,G;;gBAOD,wB,qCAAyB,U,EAAY,Q,EAAU;AAC9C,UAAO,IAAP,CAAY,QAAZ,EAAsB,OAAtB,CAA8B,UAAC,EAAD,EAAQ;AACrC,QAAI,iBAAiB,WAAW,iBAAX,CAA6B,EAA7B,CAArB;AACA,aAAS,EAAT,EAAa,UAAb,CAAwB,WAAW,KAAX,EAAxB,EAA4C,cAA5C;AACA,YAAQ,GAAR,CAAY,aAAa,WAAW,KAAX,EAAb,GAAkC,2BAAlC,GACX,GADW,GACL,SAAS,EAAT,CADK,GACU,KADV,IACmB,YAAK,eAAL,CAAqB,cAArB,IAAuC,KAAvC,GAA+C,OADlE,IAC6E,GADzF;AAEA,IALD;AAMA,G;;gBAKD,U,yBAAa;AACZ,qBAAQ,MAAR,CAAe,QAAf,CAAwB,MAAxB;AACA,G;;gBAOD,W,wBAAY,K,EAAO;AAClB,UAAO,aAAM,MAAN,CAAa,KAAK,MAAlB,EAA0B,KAA1B,CAAP;AACA,G;;gBAMD,Y,yBAAa,I,EAAM;AAAA;;AAClB,OAAI,SAAS,KAAK,OAAL,CAAa,IAAb,CAAb;AACA,OAAI,MAAJ,EAAY;AACX,WAAO,IAAP,CAAY,KAAK,QAAjB,EAA2B,OAA3B,CAAmC,UAAC,SAAD;AAAA,YAAe,OAAK,QAAL,CAAc,SAAd,EAAyB,MAAzB,CAAgC,OAAO,KAAP,EAAhC,CAAf;AAAA,KAAnC;AACA,WAAO,OAAP;AACA,WAAO,KAAK,OAAL,CAAa,IAAb,CAAP;AACA;AACD,G;;gBAKD,qC,oDAAwC;AACvC,OAAI,QAAQ,kBAAQ,MAAR,CAAe,OAAf,CAAuB,KAAnC;AACA,OAAI,SAAS,MAAM,KAAnB,EAA0B;AACzB,UAAM,SAAN,GAAkB,kBAAQ,MAAR,CAAe,WAAjC;AACA,UAAM,UAAN,GAAmB,kBAAQ,MAAR,CAAe,WAAlC;AACA,sBAAQ,MAAR,CAAe,OAAf,CAAuB,YAAvB,CAAoC,KAApC,EAA2C,IAA3C,EAAiD,IAAjD;AACA;AACD,G;;gBAMD,uB,oCAAwB,oB,EAAsB;AAC7C,QAAK,oBAAL,GAA4B,oBAA5B;AACA,G;;gBAMD,W,wBAAY,Q,EAAU;AACrB,QAAK,QAAL,GAAgB,QAAhB;AACA,G;;gBAMD,e,4BAAgB,Y,EAAc;AAC7B,QAAK,YAAL,GAAoB,YAApB;AACA,G;;gBAMD,e,4BAAgB,Y,EAAc;AAC7B,QAAK,YAAL,GAAoB,YAApB;AACA,OAAI,KAAK,iBAAT,EAA4B;AAC3B,SAAK,iBAAL,CAAuB,cAAvB;AACA;AACD,QAAK,iBAAL,GAAyB,cAAI,QAAJ,CAAa,QAAb,EAAuB,QAAvB,EAAiC,KAAK,YAAtC,EAAoD,KAAK,oBAAL,CAA0B,IAA1B,CAA+B,IAA/B,CAApD,CAAzB;AACA,G;;gBAMD,e,4BAAgB,Y,EAAc;AAC7B,QAAK,YAAL,GAAoB,YAApB;AACA,OAAI,KAAK,iBAAT,EAA4B;AAC3B,SAAK,iBAAL,CAAuB,cAAvB;AACA;AACD,QAAK,iBAAL,GAAyB,cAAI,QAAJ,CAAa,QAAb,EAAuB,OAAvB,EAAgC,KAAK,YAArC,EAAmD,KAAK,mBAAL,CAAyB,IAAzB,CAA8B,IAA9B,CAAnD,CAAzB;AACA,G;;gBAMD,kB,+BAAmB,e,EAAiB;AACnC,QAAK,eAAL,GAAuB,eAAvB;AACA,G;;gBAMD,uB,oCAAwB,oB,EAAsB;AAC7C,QAAK,oBAAL,GAA4B,oBAA5B;AACA,G;;gBAMD,oB,mCAAuB;AACtB,OAAI,KAAK,eAAT,EAA0B;AACzB,SAAK,eAAL,CAAqB,MAArB,CAA4B,2BAA5B;AACA,SAAK,eAAL,GAAuB,IAAvB;AACA;AACD,G;;gBASD,gC,+CAAmC;AAAA;;AAClC,OAAI,QAAQ,kBAAQ,MAAR,CAAe,OAAf,CAAuB,KAAnC;AACA,OAAI,CAAC,KAAL,EAAY;AACX;AACA;;AAED,OAAI,YAAY,MAAM,SAAtB;AACA,OAAI,aAAa,MAAM,UAAvB;;AAEA,OAAI,OAAO,SAAP,IAAO,GAAM;AAChB,QAAI,QAAK,oBAAT,EAA+B;AAC9B,uBAAQ,MAAR,CAAe,QAAf,CAAwB,UAAxB,EAAoC,SAApC;AACA;AACD,IAJD;;AAMA,UAAO,sBAAuB,UAAC,OAAD;AAAA,WAAa,SAAS,aAAM,QAAN,CAAe;AAAA,YAAM,SAAS,SAAf;AAAA,KAAf,CAAtB;AAAA,IAAvB,CAAP;AACA,G;;gBAUD,c,2BAAe,K,EAAO,I,EAAM,K,EAAO,kB,EAAoB;AACtD,OAAI,kBAAJ,EAAwB;AACvB,sBAAQ,MAAR,CAAe,OAAf,CAAuB,YAAvB,CAAoC,KAApC,EAA2C,KAA3C,EAAkD,IAAlD;AACA,IAFD,MAEO;AACN,sBAAQ,MAAR,CAAe,OAAf,CAAuB,SAAvB,CAAiC,KAAjC,EAAwC,KAAxC,EAA+C,IAA/C;AACA;AACD,qBAAQ,QAAR,CAAiB,KAAjB,GAAyB,KAAzB;AACA,G;;;;;mBAIa,G","file":"src/app/App.js","sourcesContent":["'use strict';\n\nimport { array, async, core } from 'metal';\nimport dom from 'metal-dom';\nimport CancellablePromise from 'metal-promise';\nimport { EventEmitter, EventHandler } from 'metal-events';\nimport utils from '../utils/utils';\nimport globals from '../globals/globals';\nimport Route from '../route/Route';\nimport Screen from '../screen/Screen';\nimport Surface from '../surface/Surface';\nimport Uri from 'metal-uri';\n\nclass App extends EventEmitter {\n\n\t/**\n\t * App class that handle routes and screens lifecycle.\n\t * @constructor\n\t * @extends {EventEmitter}\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the active screen.\n\t\t * @type {?Screen}\n\t\t * @protected\n\t\t */\n\t\tthis.activeScreen = null;\n\n\t\t/**\n\t\t * Holds the active path containing the query parameters.\n\t\t * @type {?string}\n\t\t * @protected\n\t\t */\n\t\tthis.activePath = null;\n\n\t\t/**\n\t\t * Allows prevent navigate from dom prevented event.\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.allowPreventNavigate = true;\n\n\t\t/**\n\t\t * Holds link base path.\n\t\t * @type {!string}\n\t\t * @default ''\n\t\t * @protected\n\t\t */\n\t\tthis.basePath = '';\n\n\t\t/**\n\t\t * Captures scroll position from scroll event.\n\t\t * @type {!boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.captureScrollPositionFromScrollEvent = true;\n\n\t\t/**\n\t\t * Holds the default page title.\n\t\t * @type {string}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.defaultTitle = globals.document.title;\n\n\t\t/**\n\t\t * Holds the form selector to define forms that are routed.\n\t\t * @type {!string}\n\t\t * @default form[enctype=\"multipart/form-data\"]:not([data-senna-off])\n\t\t * @protected\n\t\t */\n\t\tthis.formSelector = 'form[enctype=\"multipart/form-data\"]:not([data-senna-off])';\n\n\t\t/**\n\t\t * Holds the link selector to define links that are routed.\n\t\t * @type {!string}\n\t\t * @default a:not([data-senna-off])\n\t\t * @protected\n\t\t */\n\t\tthis.linkSelector = 'a:not([data-senna-off])';\n\n\t\t/**\n\t\t * Holds the loading css class.\n\t\t * @type {!string}\n\t\t * @default senna-loading\n\t\t * @protected\n\t\t */\n\t\tthis.loadingCssClass = 'senna-loading';\n\n\t\t/**\n\t\t * Using the History API to manage your URLs is awesome and, as it happens,\n\t\t * a crucial feature of good web apps. One of its downsides, however, is\n\t\t * that scroll positions are stored and then, more importantly, restored\n\t\t * whenever you traverse the history. This often means unsightly jumps as\n\t\t * the scroll position changes automatically, and especially so if your app\n\t\t * does transitions, or changes the contents of the page in any way.\n\t\t * Ultimately this leads to an horrible user experience. The good news is,\n\t\t * however, that there’s a potential fix: history.scrollRestoration.\n\t\t * https://developers.google.com/web/updates/2015/09/history-api-scroll-restoration\n\t\t * @type {boolean}\n\t\t * @protected\n\t\t */\n\t\tthis.nativeScrollRestorationSupported = ('scrollRestoration' in globals.window.history);\n\n\t\t/**\n\t\t * Holds a deferred with the current navigation.\n\t\t * @type {?CancellablePromise}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.pendingNavigate = null;\n\n\t\t/**\n\t\t * Holds the window horizontal scroll position when the navigation using\n\t\t * back or forward happens to be restored after the surfaces are updated.\n\t\t * @type {!Number}\n\t\t * @default 0\n\t\t * @protected\n\t\t */\n\t\tthis.popstateScrollLeft = 0;\n\n\t\t/**\n\t\t * Holds the window vertical scroll position when the navigation using\n\t\t * back or forward happens to be restored after the surfaces are updated.\n\t\t * @type {!Number}\n\t\t * @default 0\n\t\t * @protected\n\t\t */\n\t\tthis.popstateScrollTop = 0;\n\n\t\t/**\n\t\t * Holds the redirect path containing the query parameters.\n\t\t * @type {?string}\n\t\t * @protected\n\t\t */\n\t\tthis.redirectPath = null;\n\n\t\t/**\n\t\t * Holds the screen routes configuration.\n\t\t * @type {?Array}\n\t\t * @default []\n\t\t * @protected\n\t\t */\n\t\tthis.routes = [];\n\n\t\t/**\n\t\t * Maps the screen instances by the url containing the parameters.\n\t\t * @type {?Object}\n\t\t * @default {}\n\t\t * @protected\n\t\t */\n\t\tthis.screens = {};\n\n\t\t/**\n\t\t * When set to true the first erroneous popstate fired on page load will be\n\t\t * ignored, only if globals.window.history.state is also\n\t\t * null.\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t * @protected\n\t\t */\n\t\tthis.skipLoadPopstate = false;\n\n\t\t/**\n\t\t * Maps that index the surfaces instances by the surface id.\n\t\t * @type {?Object}\n\t\t * @default {}\n\t\t * @protected\n\t\t */\n\t\tthis.surfaces = {};\n\n\t\t/**\n\t\t * When set to true, moves the scroll position after popstate, or to the\n\t\t * top of the viewport for new navigation. If false, the browser will\n\t\t * take care of scroll restoration.\n\t\t * @type {!boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.updateScrollPosition = true;\n\n\t\tthis.appEventHandlers_ = new EventHandler();\n\n\t\tthis.appEventHandlers_.add(\n\t\t\tdom.on(globals.window, 'scroll', this.onScroll_.bind(this)),\n\t\t\tdom.on(globals.window, 'load', this.onLoad_.bind(this)),\n\t\t\tdom.on(globals.window, 'popstate', this.onPopstate_.bind(this))\n\t\t);\n\n\t\tthis.on('startNavigate', this.onStartNavigate_);\n\t\tthis.on('beforeNavigate', this.onBeforeNavigate_);\n\t\tthis.on('beforeNavigate', this.onBeforeNavigateDefault_, true);\n\n\t\tthis.setLinkSelector(this.linkSelector);\n\t\tthis.setFormSelector(this.formSelector);\n\t}\n\n\t/**\n\t * Adds one or more screens to the application.\n\t *\n\t * Example:\n\t *\n\t * \n\t * app.addRoutes({ path: '/foo', handler: FooScreen });\n\t * or\n\t * app.addRoutes([{ path: '/foo', handler: function(route) { return new FooScreen(); } }]);\n\t * \n\t *\n\t * @param {Object} or {Array} routes Single object or an array of object.\n\t * Each object should contain path and screen.\n\t * The path should be a string or a regex that maps the\n\t * navigation route to a screen class definition (not an instance), e.g:\n\t * { path: \"/home:param1\", handler: MyScreen }\n\t * { path: /foo.+/, handler: MyScreen }\n\t * @chainable\n\t */\n\taddRoutes(routes) {\n\t\tif (!Array.isArray(routes)) {\n\t\t\troutes = [routes];\n\t\t}\n\t\troutes.forEach((route) => {\n\t\t\tif (!(route instanceof Route)) {\n\t\t\t\troute = new Route(route.path, route.handler);\n\t\t\t}\n\t\t\tthis.routes.push(route);\n\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds one or more surfaces to the application.\n\t * @param {Surface|String|Array.} surfaces\n\t * Surface element id or surface instance. You can also pass an Array\n\t * whichcontains surface instances or id. In case of ID, these should be\n\t * the id of surface element.\n\t * @chainable\n\t */\n\taddSurfaces(surfaces) {\n\t\tif (!Array.isArray(surfaces)) {\n\t\t\tsurfaces = [surfaces];\n\t\t}\n\t\tsurfaces.forEach((surface) => {\n\t\t\tif (core.isString(surface)) {\n\t\t\t\tsurface = new Surface(surface);\n\t\t\t}\n\t\t\tthis.surfaces[surface.getId()] = surface;\n\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns if can navigate to path.\n\t * @param {!string} url\n\t * @return {boolean}\n\t */\n\tcanNavigate(url) {\n\t\tvar path = utils.getUrlPath(url);\n\t\tvar uri = new Uri(url);\n\n\t\tif (!this.isLinkSameOrigin_(uri.getHostname())) {\n\t\t\tconsole.log('Offsite link clicked');\n\t\t\treturn false;\n\t\t}\n\t\tif (!this.isSameBasePath_(path)) {\n\t\t\tconsole.log('Link clicked outside app\\'s base path');\n\t\t\treturn false;\n\t\t}\n\t\tif (!this.findRoute(path)) {\n\t\t\tconsole.log('No route for ' + path);\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Clear screens cache.\n\t * @chainable\n\t */\n\tclearScreensCache() {\n\t\tObject.keys(this.screens).forEach((path) => {\n\t\t\tif (path === this.activePath) {\n\t\t\t\tthis.activeScreen.clearCache();\n\t\t\t} else {\n\t\t\t\tthis.removeScreen(path);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves or create a screen instance to a path.\n\t * @param {!string} path Path containing the querystring part.\n\t * @return {Screen}\n\t */\n\tcreateScreenInstance(path, route) {\n\t\tif (!this.pendingNavigate && path === this.activePath) {\n\t\t\tconsole.log('Already at destination, refresh navigation');\n\t\t\treturn this.activeScreen;\n\t\t}\n\t\t/* jshint newcap: false */\n\t\tvar screen = this.screens[path];\n\t\tif (!screen) {\n\t\t\tvar handler = route.getHandler();\n\t\t\tif (handler === Screen || Screen.isImplementedBy(handler.prototype)) {\n\t\t\t\tscreen = new handler();\n\t\t\t} else {\n\t\t\t\tscreen = handler(route) || new Screen();\n\t\t\t}\n\t\t\tconsole.log('Create screen for [' + path + '] [' + screen + ']');\n\t\t}\n\t\treturn screen;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdisposeInternal() {\n\t\tif (this.activeScreen) {\n\t\t\tthis.removeScreen(this.activePath);\n\t\t}\n\t\tthis.clearScreensCache();\n\t\tthis.formEventHandler_.removeListener();\n\t\tthis.linkEventHandler_.removeListener();\n\t\tthis.appEventHandlers_.removeAllListeners();\n\t\tsuper.disposeInternal();\n\t}\n\n\t/**\n\t * Dispatches to the first route handler that matches the current path, if\n\t * any.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tdispatch() {\n\t\treturn this.navigate(utils.getCurrentBrowserPath(), true);\n\t}\n\n\t/**\n\t * Starts navigation to a path.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tdoNavigate_(path, opt_replaceHistory) {\n\t\tif (this.activeScreen && this.activeScreen.beforeDeactivate()) {\n\t\t\tthis.pendingNavigate = CancellablePromise.reject(new CancellablePromise.CancellationError('Cancelled by active screen'));\n\t\t\treturn this.pendingNavigate;\n\t\t}\n\n\t\tvar route = this.findRoute(path);\n\t\tif (!route) {\n\t\t\tthis.pendingNavigate = CancellablePromise.reject(new CancellablePromise.CancellationError('No route for ' + path));\n\t\t\treturn this.pendingNavigate;\n\t\t}\n\n\t\tconsole.log('Navigate to [' + path + ']');\n\n\t\tthis.stopPendingNavigate_();\n\n\t\tvar nextScreen = this.createScreenInstance(path, route);\n\n\t\treturn nextScreen.load(path)\n\t\t\t.then(() => {\n\t\t\t\tif (this.activeScreen) {\n\t\t\t\t\tthis.activeScreen.deactivate();\n\t\t\t\t}\n\t\t\t\tthis.prepareNavigateHistory_(path, nextScreen, opt_replaceHistory);\n\t\t\t\tthis.prepareNavigateSurfaces_(nextScreen, this.surfaces);\n\t\t\t})\n\t\t\t.then(() => nextScreen.evaluateStyles(this.surfaces))\n\t\t\t.then(() => nextScreen.flip(this.surfaces))\n\t\t\t.then(() => nextScreen.evaluateScripts(this.surfaces))\n\t\t\t.then(() => this.syncScrollPositionSyncThenAsync_())\n\t\t\t.then(() => this.finalizeNavigate_(path, nextScreen))\n\t\t\t.catch((reason) => {\n\t\t\t\tthis.handleNavigateError_(path, nextScreen, reason);\n\t\t\t\tthrow reason;\n\t\t\t});\n\t}\n\n\t/**\n\t * Finalizes a screen navigation.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @protected\n\t */\n\tfinalizeNavigate_(path, nextScreen) {\n\t\tnextScreen.activate();\n\n\t\tif (this.activeScreen && !this.activeScreen.isCacheable()) {\n\t\t\tif (this.activeScreen !== nextScreen) {\n\t\t\t\tthis.removeScreen(this.activePath);\n\t\t\t}\n\t\t}\n\n\t\tthis.activePath = path;\n\t\tthis.activeScreen = nextScreen;\n\t\tthis.screens[path] = nextScreen;\n\t\tthis.pendingNavigate = null;\n\t\tglobals.capturedFormElement = null;\n\t\tconsole.log('Navigation done');\n\t}\n\n\t/**\n\t * Finds a route for the test path. Returns true if matches has a route,\n\t * otherwise returns null.\n\t * @param {!string} path Path containing the querystring part.\n\t * @return {?Object} Route handler if match any or null if the\n\t * path is the same as the current url and the path contains a fragment.\n\t */\n\tfindRoute(path) {\n\t\t// Prevents navigation if it's a hash change on the same url.\n\t\tif ((path.lastIndexOf('#') > -1) && utils.isCurrentBrowserPath(path)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tpath = utils.getUrlPathWithoutHash(path);\n\n\t\t// Makes sure that the path substring will be in the expected format\n\t\t// (that is, will end with a \"/\").\n\t\tpath = utils.getUrlPathWithoutHash(path.substr(this.basePath.length));\n\n\t\tfor (var i = 0; i < this.routes.length; i++) {\n\t\t\tvar route = this.routes[i];\n\t\t\tif (route.matchesPath(path)) {\n\t\t\t\treturn route;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Gets allow prevent navigate.\n\t * @return {boolean}\n\t */\n\tgetAllowPreventNavigate() {\n\t\treturn this.allowPreventNavigate;\n\t}\n\n\t/**\n\t * Gets link base path.\n\t * @return {!string}\n\t */\n\tgetBasePath() {\n\t\treturn this.basePath;\n\t}\n\n\t/**\n\t * Gets the default page title.\n\t * @return {string} defaultTitle\n\t */\n\tgetDefaultTitle() {\n\t\treturn this.defaultTitle;\n\t}\n\n\t/**\n\t * Gets the form selector.\n\t * @return {!string}\n\t */\n\tgetFormSelector() {\n\t\treturn this.formSelector;\n\t}\n\n\t/**\n\t * Gets the link selector.\n\t * @return {!string}\n\t */\n\tgetLinkSelector() {\n\t\treturn this.linkSelector;\n\t}\n\n\t/**\n\t * Gets the loading css class.\n\t * @return {!string}\n\t */\n\tgetLoadingCssClass() {\n\t\treturn this.loadingCssClass;\n\t}\n\n\t/**\n\t * Gets the update scroll position value.\n\t * @return {boolean}\n\t */\n\tgetUpdateScrollPosition() {\n\t\treturn this.updateScrollPosition;\n\t}\n\n\t/**\n\t * Handle navigation error.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @param {!Error} error\n\t * @protected\n\t */\n\thandleNavigateError_(path, nextScreen, err) {\n\t\tconsole.log('Navigation error for [' + nextScreen + '] (' + err + ')');\n\t\tif (!utils.isCurrentBrowserPath(path)) {\n\t\t\tthis.removeScreen(path);\n\t\t}\n\t}\n\n\t/**\n\t * Checks if app has routes.\n\t * @return {boolean}\n\t */\n\thasRoutes() {\n\t\treturn this.routes.length > 0;\n\t}\n\n\t/**\n\t * Tests if hostname is an offsite link.\n\t * @param {!string} hostname Link hostname to compare with\n\t * globals.window.location.hostname.\n\t * @return {boolean}\n\t * @protected\n\t */\n\tisLinkSameOrigin_(hostname) {\n\t\treturn hostname === globals.window.location.hostname;\n\t}\n\n\t/**\n\t * Tests if link element has the same app's base path.\n\t * @param {!string} path Link path containing the querystring part.\n\t * @return {boolean}\n\t * @protected\n\t */\n\tisSameBasePath_(path) {\n\t\treturn path.indexOf(this.basePath) === 0;\n\t}\n\n\t/**\n\t * Lock the document scroll in order to avoid the browser native back and\n\t * forward navigation to change the scroll position. In the end of\n\t * navigation lifecycle scroll is repositioned.\n\t * @protected\n\t */\n\tlockHistoryScrollPosition_() {\n\t\tvar state = globals.window.history.state;\n\t\tif (!state) {\n\t\t\treturn;\n\t\t}\n\t\t// Browsers are inconsistent when re-positioning the scroll history on\n\t\t// popstate. At some browsers, history scroll happens before popstate, then\n\t\t// lock the scroll on the last known position as soon as possible after the\n\t\t// current JS execution context and capture the current value. Some others,\n\t\t// history scroll happens after popstate, in this case, we bind an once\n\t\t// scroll event to lock the las known position. Lastly, the previous two\n\t\t// behaviors can happen even on the same browser, hence the race will decide\n\t\t// the winner.\n\t\tvar winner = false;\n\t\tvar switchScrollPositionRace = function() {\n\t\t\tglobals.document.removeEventListener('scroll', switchScrollPositionRace, false);\n\t\t\tif (!winner) {\n\t\t\t\tglobals.window.scrollTo(state.scrollLeft, state.scrollTop);\n\t\t\t\twinner = true;\n\t\t\t}\n\t\t};\n\t\tasync.nextTick(switchScrollPositionRace);\n\t\tglobals.document.addEventListener('scroll', switchScrollPositionRace, false);\n\t}\n\n\t/**\n\t * If supported by the browser, disables native scroll restoration and\n\t * stores current value.\n\t */\n\tmaybeDisableNativeScrollRestoration() {\n\t\tif (this.nativeScrollRestorationSupported) {\n\t\t\tthis.nativeScrollRestoration_ = globals.window.history.scrollRestoration;\n\t\t\tglobals.window.history.scrollRestoration = 'manual';\n\t\t}\n\t}\n\n\t/**\n\t * Maybe navigate to a path.\n\t * @param {string} href Information about the link's href.\n\t * @param {Event} event Dom event that initiated the navigation.\n\t */\n\tmaybeNavigate_(href, event) {\n\t\tif (!this.canNavigate(href)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.allowPreventNavigate && event.defaultPrevented) {\n\t\t\tconsole.log('Navigate prevented');\n\t\t\treturn;\n\t\t}\n\n\t\tglobals.capturedFormElement = event.capturedFormElement;\n\n\t\tvar navigateFailed = false;\n\t\ttry {\n\t\t\tthis.navigate(utils.getUrlPath(href));\n\t\t} catch (err) {\n\t\t\t// Do not prevent link navigation in case some synchronous error occurs\n\t\t\tnavigateFailed = true;\n\t\t}\n\n\t\tif (!navigateFailed) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n\n\t/**\n\t * Maybe reposition scroll to hashed anchor.\n\t */\n\tmaybeRepositionScrollToHashedAnchor() {\n\t\tvar hash = globals.window.location.hash;\n\t\tif (hash) {\n\t\t\tvar anchorElement = globals.document.getElementById(hash.substring(1));\n\t\t\tif (anchorElement) {\n\t\t\t\tglobals.window.scrollTo(anchorElement.offsetLeft, anchorElement.offsetTop);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If supported by the browser, restores native scroll restoration to the\n\t * value captured by `maybeDisableNativeScrollRestoration`.\n\t */\n\tmaybeRestoreNativeScrollRestoration() {\n\t\tif (this.nativeScrollRestorationSupported && this.nativeScrollRestoration_) {\n\t\t\tglobals.window.history.scrollRestoration = this.nativeScrollRestoration_;\n\t\t}\n\t}\n\n\t/**\n\t * Navigates to the specified path if there is a route handler that matches.\n\t * @param {!string} path Path to navigate containing the base path.\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tnavigate(path, opt_replaceHistory) {\n\t\tif (!utils.isHtml5HistorySupported()) {\n\t\t\tthrow new Error('HTML5 History is not supported. Senna will not intercept navigation.');\n\t\t}\n\n\t\t// When reloading the same path do replaceState instead of pushState to\n\t\t// avoid polluting history with states with the same path.\n\t\tif (path === this.activePath) {\n\t\t\topt_replaceHistory = true;\n\t\t}\n\n\t\tthis.emit('beforeNavigate', {\n\t\t\tpath: path,\n\t\t\treplaceHistory: !!opt_replaceHistory\n\t\t});\n\n\t\treturn this.pendingNavigate;\n\t}\n\n\t/**\n\t * Befores navigation to a path.\n\t * @param {!Event} event Event facade containing path and\n\t * replaceHistory.\n\t * @protected\n\t */\n\tonBeforeNavigate_(event) {\n\t\tif (globals.capturedFormElement) {\n\t\t\tevent.form = globals.capturedFormElement;\n\t\t}\n\t}\n\n\t/**\n\t * Befores navigation to a path. Runs after external listeners.\n\t * @param {!Event} event Event facade containing path and\n\t * replaceHistory.\n\t * @protected\n\t */\n\tonBeforeNavigateDefault_(event) {\n\t\tif (this.pendingNavigate) {\n\t\t\tif (this.pendingNavigate.path === event.path) {\n\t\t\t\tconsole.log('Waiting...');\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis.emit('startNavigate', {\n\t\t\tform: event.form,\n\t\t\tpath: event.path,\n\t\t\treplaceHistory: event.replaceHistory\n\t\t});\n\t}\n\n\t/**\n\t * Intercepts document clicks and test link elements in order to decide\n\t * whether Surface app can navigate.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonDocClickDelegate_(event) {\n\t\tif (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.button) {\n\t\t\tconsole.log('Navigate aborted, invalid mouse button or modifier key pressed.');\n\t\t\treturn;\n\t\t}\n\t\tthis.maybeNavigate_(event.delegateTarget.href, event);\n\t}\n\n\t/**\n\t * Intercepts document form submits and test action path in order to decide\n\t * whether Surface app can navigate.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonDocSubmitDelegate_(event) {\n\t\tvar form = event.delegateTarget;\n\t\tif (form.method === 'get') {\n\t\t\tconsole.log('GET method not supported');\n\t\t\treturn;\n\t\t}\n\t\tevent.capturedFormElement = form;\n\t\tthis.maybeNavigate_(form.action, event);\n\t}\n\n\t/**\n\t * Listens to the window's load event in order to avoid issues with some browsers\n\t * that trigger popstate calls on the first load. For more information see\n\t * http://stackoverflow.com/questions/6421769/popstate-on-pages-load-in-chrome.\n\t * @protected\n\t */\n\tonLoad_() {\n\t\tthis.skipLoadPopstate = true;\n\t\tsetTimeout(() => {\n\t\t\t// The timeout ensures that popstate events will be unblocked right\n\t\t\t// after the load event occured, but not in the same event-loop cycle.\n\t\t\tthis.skipLoadPopstate = false;\n\t\t}, 0);\n\t\t// Try to reposition scroll to the hashed anchor when page loads.\n\t\tthis.maybeRepositionScrollToHashedAnchor();\n\t}\n\n\t/**\n\t * Handles browser history changes and fires app's navigation if the state\n\t * belows to us. If we detect a popstate and the state is null,\n\t * assume it is navigating to an external page or to a page we don't have\n\t * route, then globals.window.location.reload() is invoked in order to\n\t * reload the content to the current url.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonPopstate_(event) {\n\t\tif (this.skipLoadPopstate) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar state = event.state;\n\n\t\tif (!state) {\n\t\t\tif (globals.window.location.hash) {\n\t\t\t\t// If senna is on an redirect path and a hash popstate happens\n\t\t\t\t// to a different url, reload the browser. This behavior doesn't\n\t\t\t\t// require senna to route hashed links and is closer to native\n\t\t\t\t// browser behavior.\n\t\t\t\tif (this.redirectPath && !utils.isCurrentBrowserPath(this.redirectPath)) {\n\t\t\t\t\tthis.reloadPage();\n\t\t\t\t}\n\t\t\t\t// Always try to reposition scroll to the hashed anchor when\n\t\t\t\t// hash popstate happens.\n\t\t\t\tthis.maybeRepositionScrollToHashedAnchor();\n\t\t\t} else {\n\t\t\t\tthis.reloadPage();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (state.senna) {\n\t\t\tconsole.log('History navigation to [' + state.path + ']');\n\t\t\tthis.popstateScrollTop = state.scrollTop;\n\t\t\tthis.popstateScrollLeft = state.scrollLeft;\n\t\t\tif (!this.nativeScrollRestorationSupported) {\n\t\t\t\tthis.lockHistoryScrollPosition_();\n\t\t\t}\n\t\t\tthis.navigate(state.path, true);\n\t\t}\n\t}\n\n\t/**\n\t * Listens document scroll changes in order to capture the possible lock\n\t * scroll position for history scrolling.\n\t * @protected\n\t */\n\tonScroll_() {\n\t\tif (this.captureScrollPositionFromScrollEvent) {\n\t\t\tthis.saveHistoryCurrentPageScrollPosition_();\n\t\t}\n\t}\n\n\t/**\n\t * Starts navigation to a path.\n\t * @param {!Event} event Event facade containing path and\n\t * replaceHistory.\n\t * @protected\n\t */\n\tonStartNavigate_(event) {\n\t\tthis.maybeDisableNativeScrollRestoration();\n\t\tthis.captureScrollPositionFromScrollEvent = false;\n\t\tdom.addClasses(globals.document.documentElement, this.loadingCssClass);\n\n\t\tvar endNavigatePayload = {\n\t\t\tform: event.form,\n\t\t\tpath: event.path\n\t\t};\n\n\t\tthis.pendingNavigate = this.doNavigate_(event.path, event.replaceHistory)\n\t\t\t.catch((reason) => {\n\t\t\t\tendNavigatePayload.error = reason;\n\t\t\t\tthrow reason;\n\t\t\t})\n\t\t\t.thenAlways(() => {\n\t\t\t\tif (!this.pendingNavigate) {\n\t\t\t\t\tdom.removeClasses(globals.document.documentElement, this.loadingCssClass);\n\t\t\t\t\tthis.maybeRestoreNativeScrollRestoration();\n\t\t\t\t\tthis.captureScrollPositionFromScrollEvent = true;\n\t\t\t\t}\n\t\t\t\tthis.emit('endNavigate', endNavigatePayload);\n\t\t\t});\n\n\t\tthis.pendingNavigate.path = event.path;\n\t}\n\n\t/**\n\t * Prefetches the specified path if there is a route handler that matches.\n\t * @param {!string} path Path to navigate containing the base path.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tprefetch(path) {\n\t\tvar route = this.findRoute(path);\n\t\tif (!route) {\n\t\t\treturn CancellablePromise.reject(new CancellablePromise.CancellationError('No route for ' + path));\n\t\t}\n\n\t\tconsole.log('Prefetching [' + path + ']');\n\n\t\tvar nextScreen = this.createScreenInstance(path, route);\n\n\t\treturn nextScreen.load(path)\n\t\t\t.then(() => this.screens[path] = nextScreen)\n\t\t\t.catch((reason) => {\n\t\t\t\tthis.handleNavigateError_(path, nextScreen, reason);\n\t\t\t\tthrow reason;\n\t\t\t});\n\t}\n\n\t/**\n\t * Prepares screen flip. Updates history state and surfaces content.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t */\n\tprepareNavigateHistory_(path, nextScreen, opt_replaceHistory) {\n\t\tvar title = nextScreen.getTitle();\n\t\tif (!core.isString(title)) {\n\t\t\ttitle = this.getDefaultTitle();\n\t\t}\n\t\tvar redirectPath = nextScreen.beforeUpdateHistoryPath(path);\n\t\tvar historyState = {\n\t\t\tform: core.isDefAndNotNull(globals.capturedFormElement),\n\t\t\tredirectPath: redirectPath,\n\t\t\tpath: path,\n\t\t\tsenna: true,\n\t\t\tscrollTop: 0,\n\t\t\tscrollLeft: 0\n\t\t};\n\t\tif (opt_replaceHistory) {\n\t\t\thistoryState.scrollTop = this.popstateScrollTop;\n\t\t\thistoryState.scrollLeft = this.popstateScrollLeft;\n\t\t}\n\t\tthis.updateHistory_(title, redirectPath, nextScreen.beforeUpdateHistoryState(historyState), opt_replaceHistory);\n\t\tthis.redirectPath = redirectPath;\n\t}\n\n\t/**\n\t * Prepares screen flip. Updates history state and surfaces content.\n\t * @param {!Screen} nextScreen\n\t * @param {!object} surfaces Map of surfaces to flip keyed by surface id.\n\t */\n\tprepareNavigateSurfaces_(nextScreen, surfaces) {\n\t\tObject.keys(surfaces).forEach((id) => {\n\t\t\tvar surfaceContent = nextScreen.getSurfaceContent(id);\n\t\t\tsurfaces[id].addContent(nextScreen.getId(), surfaceContent);\n\t\t\tconsole.log('Screen [' + nextScreen.getId() + '] add content to surface ' +\n\t\t\t\t'[' + surfaces[id] + '] [' + (core.isDefAndNotNull(surfaceContent) ? '...' : 'empty') + ']');\n\t\t});\n\t}\n\n\t/**\n\t * Reloads the page by performing `window.location.reload()`.\n\t */\n\treloadPage() {\n\t\tglobals.window.location.reload();\n\t}\n\n\t/**\n\t * Removes route instance from app routes.\n\t * @param {Route} route\n\t * @return {boolean} True if an element was removed.\n\t */\n\tremoveRoute(route) {\n\t\treturn array.remove(this.routes, route);\n\t}\n\n\t/**\n\t * Removes a screen.\n\t * @param {!string} path Path containing the querystring part.\n\t */\n\tremoveScreen(path) {\n\t\tvar screen = this.screens[path];\n\t\tif (screen) {\n\t\t\tObject.keys(this.surfaces).forEach((surfaceId) => this.surfaces[surfaceId].remove(screen.getId()));\n\t\t\tscreen.dispose();\n\t\t\tdelete this.screens[path];\n\t\t}\n\t}\n\n\t/**\n\t * Saves scroll position from page offset into history state.\n\t */\n\tsaveHistoryCurrentPageScrollPosition_() {\n\t\tvar state = globals.window.history.state;\n\t\tif (state && state.senna) {\n\t\t\tstate.scrollTop = globals.window.pageYOffset;\n\t\t\tstate.scrollLeft = globals.window.pageXOffset;\n\t\t\tglobals.window.history.replaceState(state, null, null);\n\t\t}\n\t}\n\n\t/**\n\t * Sets allow prevent navigate.\n\t * @param {boolean} allowPreventNavigate\n\t */\n\tsetAllowPreventNavigate(allowPreventNavigate) {\n\t\tthis.allowPreventNavigate = allowPreventNavigate;\n\t}\n\n\t/**\n\t * Sets link base path.\n\t * @param {!string} path\n\t */\n\tsetBasePath(basePath) {\n\t\tthis.basePath = basePath;\n\t}\n\n\t/**\n\t * Sets the default page title.\n\t * @param {string} defaultTitle\n\t */\n\tsetDefaultTitle(defaultTitle) {\n\t\tthis.defaultTitle = defaultTitle;\n\t}\n\n\t/**\n\t * Sets the form selector.\n\t * @param {!string} formSelector\n\t */\n\tsetFormSelector(formSelector) {\n\t\tthis.formSelector = formSelector;\n\t\tif (this.formEventHandler_) {\n\t\t\tthis.formEventHandler_.removeListener();\n\t\t}\n\t\tthis.formEventHandler_ = dom.delegate(document, 'submit', this.formSelector, this.onDocSubmitDelegate_.bind(this));\n\t}\n\n\t/**\n\t * Sets the link selector.\n\t * @param {!string} linkSelector\n\t */\n\tsetLinkSelector(linkSelector) {\n\t\tthis.linkSelector = linkSelector;\n\t\tif (this.linkEventHandler_) {\n\t\t\tthis.linkEventHandler_.removeListener();\n\t\t}\n\t\tthis.linkEventHandler_ = dom.delegate(document, 'click', this.linkSelector, this.onDocClickDelegate_.bind(this));\n\t}\n\n\t/**\n\t * Sets the loading css class.\n\t * @param {!string} loadingCssClass\n\t */\n\tsetLoadingCssClass(loadingCssClass) {\n\t\tthis.loadingCssClass = loadingCssClass;\n\t}\n\n\t/**\n\t * Sets the update scroll position value.\n\t * @param {boolean} updateScrollPosition\n\t */\n\tsetUpdateScrollPosition(updateScrollPosition) {\n\t\tthis.updateScrollPosition = updateScrollPosition;\n\t}\n\n\t/**\n\t * Cancels pending navigate with Cancel pending navigation error.\n\t * @protected\n\t */\n\tstopPendingNavigate_() {\n\t\tif (this.pendingNavigate) {\n\t\t\tthis.pendingNavigate.cancel('Cancel pending navigation');\n\t\t\tthis.pendingNavigate = null;\n\t\t}\n\t}\n\n\t/**\n\t * Sync document scroll position twice, the first one synchronous and then\n\t * one inside async.nextTick. Relevant to browsers that fires\n\t * scroll restoration asynchronously after popstate.\n\t * @protected\n\t * @return {?CancellablePromise=}\n\t */\n\tsyncScrollPositionSyncThenAsync_() {\n\t\tvar state = globals.window.history.state;\n\t\tif (!state) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar scrollTop = state.scrollTop;\n\t\tvar scrollLeft = state.scrollLeft;\n\n\t\tvar sync = () => {\n\t\t\tif (this.updateScrollPosition) {\n\t\t\t\tglobals.window.scrollTo(scrollLeft, scrollTop);\n\t\t\t}\n\t\t};\n\n\t\treturn new CancellablePromise((resolve) => sync() & async.nextTick(() => sync() & resolve()));\n\t}\n\n\t/**\n\t * Updates or replace browser history.\n\t * @param {?string} title Document title.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!object} state\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @protected\n\t */\n\tupdateHistory_(title, path, state, opt_replaceHistory) {\n\t\tif (opt_replaceHistory) {\n\t\t\tglobals.window.history.replaceState(state, title, path);\n\t\t} else {\n\t\t\tglobals.window.history.pushState(state, title, path);\n\t\t}\n\t\tglobals.document.title = title;\n\t}\n\n}\n\nexport default App;\n"],"sourceRoot":"/source/"}
\ No newline at end of file
+{"version":3,"sources":["App.js"],"names":[],"mappings":"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","file":"src/app/App.js","sourcesContent":["'use strict';\n\nimport { array, async, core } from 'metal';\nimport dom from 'metal-dom';\nimport CancellablePromise from 'metal-promise';\nimport { EventEmitter, EventHandler } from 'metal-events';\nimport utils from '../utils/utils';\nimport globals from '../globals/globals';\nimport Route from '../route/Route';\nimport Screen from '../screen/Screen';\nimport Surface from '../surface/Surface';\nimport Uri from 'metal-uri';\n\nclass App extends EventEmitter {\n\n\t/**\n\t * App class that handle routes and screens lifecycle.\n\t * @constructor\n\t * @extends {EventEmitter}\n\t */\n\tconstructor() {\n\t\tsuper();\n\n\t\t/**\n\t\t * Holds the active screen.\n\t\t * @type {?Screen}\n\t\t * @protected\n\t\t */\n\t\tthis.activeScreen = null;\n\n\t\t/**\n\t\t * Holds the active path containing the query parameters.\n\t\t * @type {?string}\n\t\t * @protected\n\t\t */\n\t\tthis.activePath = null;\n\n\t\t/**\n\t\t * Allows prevent navigate from dom prevented event.\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.allowPreventNavigate = true;\n\n\t\t/**\n\t\t * Holds link base path.\n\t\t * @type {!string}\n\t\t * @default ''\n\t\t * @protected\n\t\t */\n\t\tthis.basePath = '';\n\n\t\t/**\n\t\t * Captures scroll position from scroll event.\n\t\t * @type {!boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.captureScrollPositionFromScrollEvent = true;\n\n\t\t/**\n\t\t * Holds the default page title.\n\t\t * @type {string}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.defaultTitle = globals.document.title;\n\n\t\t/**\n\t\t * Holds the form selector to define forms that are routed.\n\t\t * @type {!string}\n\t\t * @default form[enctype=\"multipart/form-data\"]:not([data-senna-off])\n\t\t * @protected\n\t\t */\n\t\tthis.formSelector = 'form[enctype=\"multipart/form-data\"]:not([data-senna-off])';\n\n\t\t/**\n\t\t * Holds the link selector to define links that are routed.\n\t\t * @type {!string}\n\t\t * @default a:not([data-senna-off])\n\t\t * @protected\n\t\t */\n\t\tthis.linkSelector = 'a:not([data-senna-off])';\n\n\t\t/**\n\t\t * Holds the loading css class.\n\t\t * @type {!string}\n\t\t * @default senna-loading\n\t\t * @protected\n\t\t */\n\t\tthis.loadingCssClass = 'senna-loading';\n\n\t\t/**\n\t\t * Using the History API to manage your URLs is awesome and, as it happens,\n\t\t * a crucial feature of good web apps. One of its downsides, however, is\n\t\t * that scroll positions are stored and then, more importantly, restored\n\t\t * whenever you traverse the history. This often means unsightly jumps as\n\t\t * the scroll position changes automatically, and especially so if your app\n\t\t * does transitions, or changes the contents of the page in any way.\n\t\t * Ultimately this leads to an horrible user experience. The good news is,\n\t\t * however, that there’s a potential fix: history.scrollRestoration.\n\t\t * https://developers.google.com/web/updates/2015/09/history-api-scroll-restoration\n\t\t * @type {boolean}\n\t\t * @protected\n\t\t */\n\t\tthis.nativeScrollRestorationSupported = ('scrollRestoration' in globals.window.history);\n\n\t\t/**\n\t\t * Holds a deferred with the current navigation.\n\t\t * @type {?CancellablePromise}\n\t\t * @default null\n\t\t * @protected\n\t\t */\n\t\tthis.pendingNavigate = null;\n\n\t\t/**\n\t\t * Holds the window horizontal scroll position when the navigation using\n\t\t * back or forward happens to be restored after the surfaces are updated.\n\t\t * @type {!Number}\n\t\t * @default 0\n\t\t * @protected\n\t\t */\n\t\tthis.popstateScrollLeft = 0;\n\n\t\t/**\n\t\t * Holds the window vertical scroll position when the navigation using\n\t\t * back or forward happens to be restored after the surfaces are updated.\n\t\t * @type {!Number}\n\t\t * @default 0\n\t\t * @protected\n\t\t */\n\t\tthis.popstateScrollTop = 0;\n\n\t\t/**\n\t\t * Holds the redirect path containing the query parameters.\n\t\t * @type {?string}\n\t\t * @protected\n\t\t */\n\t\tthis.redirectPath = null;\n\n\t\t/**\n\t\t * Holds the screen routes configuration.\n\t\t * @type {?Array}\n\t\t * @default []\n\t\t * @protected\n\t\t */\n\t\tthis.routes = [];\n\n\t\t/**\n\t\t * Maps the screen instances by the url containing the parameters.\n\t\t * @type {?Object}\n\t\t * @default {}\n\t\t * @protected\n\t\t */\n\t\tthis.screens = {};\n\n\t\t/**\n\t\t * When set to true the first erroneous popstate fired on page load will be\n\t\t * ignored, only if globals.window.history.state is also\n\t\t * null.\n\t\t * @type {boolean}\n\t\t * @default false\n\t\t * @protected\n\t\t */\n\t\tthis.skipLoadPopstate = false;\n\n\t\t/**\n\t\t * Maps that index the surfaces instances by the surface id.\n\t\t * @type {?Object}\n\t\t * @default {}\n\t\t * @protected\n\t\t */\n\t\tthis.surfaces = {};\n\n\t\t/**\n\t\t * When set to true, moves the scroll position after popstate, or to the\n\t\t * top of the viewport for new navigation. If false, the browser will\n\t\t * take care of scroll restoration.\n\t\t * @type {!boolean}\n\t\t * @default true\n\t\t * @protected\n\t\t */\n\t\tthis.updateScrollPosition = true;\n\n\t\tthis.appEventHandlers_ = new EventHandler();\n\n\t\tthis.appEventHandlers_.add(\n\t\t\tdom.on(globals.window, 'scroll', this.onScroll_.bind(this)),\n\t\t\tdom.on(globals.window, 'load', this.onLoad_.bind(this)),\n\t\t\tdom.on(globals.window, 'popstate', this.onPopstate_.bind(this))\n\t\t);\n\n\t\tthis.on('startNavigate', this.onStartNavigate_);\n\t\tthis.on('beforeNavigate', this.onBeforeNavigate_);\n\t\tthis.on('beforeNavigate', this.onBeforeNavigateDefault_, true);\n\n\t\tthis.setLinkSelector(this.linkSelector);\n\t\tthis.setFormSelector(this.formSelector);\n\t}\n\n\t/**\n\t * Adds one or more screens to the application.\n\t *\n\t * Example:\n\t *\n\t * \n\t * app.addRoutes({ path: '/foo', handler: FooScreen });\n\t * or\n\t * app.addRoutes([{ path: '/foo', handler: function(route) { return new FooScreen(); } }]);\n\t * \n\t *\n\t * @param {Object} or {Array} routes Single object or an array of object.\n\t * Each object should contain path and screen.\n\t * The path should be a string or a regex that maps the\n\t * navigation route to a screen class definition (not an instance), e.g:\n\t * { path: \"/home:param1\", handler: MyScreen }\n\t * { path: /foo.+/, handler: MyScreen }\n\t * @chainable\n\t */\n\taddRoutes(routes) {\n\t\tif (!Array.isArray(routes)) {\n\t\t\troutes = [routes];\n\t\t}\n\t\troutes.forEach((route) => {\n\t\t\tif (!(route instanceof Route)) {\n\t\t\t\troute = new Route(route.path, route.handler);\n\t\t\t}\n\t\t\tthis.routes.push(route);\n\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds one or more surfaces to the application.\n\t * @param {Surface|String|Array.} surfaces\n\t * Surface element id or surface instance. You can also pass an Array\n\t * whichcontains surface instances or id. In case of ID, these should be\n\t * the id of surface element.\n\t * @chainable\n\t */\n\taddSurfaces(surfaces) {\n\t\tif (!Array.isArray(surfaces)) {\n\t\t\tsurfaces = [surfaces];\n\t\t}\n\t\tsurfaces.forEach((surface) => {\n\t\t\tif (core.isString(surface)) {\n\t\t\t\tsurface = new Surface(surface);\n\t\t\t}\n\t\t\tthis.surfaces[surface.getId()] = surface;\n\t\t});\n\t\treturn this;\n\t}\n\n\t/**\n\t * Returns if can navigate to path.\n\t * @param {!string} url\n\t * @return {boolean}\n\t */\n\tcanNavigate(url) {\n\t\tvar path = utils.getUrlPath(url);\n\t\tvar uri = new Uri(url);\n\n\t\tif (!this.isLinkSameOrigin_(uri.getHostname())) {\n\t\t\tconsole.log('Offsite link clicked');\n\t\t\treturn false;\n\t\t}\n\t\tif (!this.isSameBasePath_(path)) {\n\t\t\tconsole.log('Link clicked outside app\\'s base path');\n\t\t\treturn false;\n\t\t}\n\t\tif (!this.findRoute(path)) {\n\t\t\tconsole.log('No route for ' + path);\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Clear screens cache.\n\t * @chainable\n\t */\n\tclearScreensCache() {\n\t\tObject.keys(this.screens).forEach((path) => {\n\t\t\tif (path === this.activePath) {\n\t\t\t\tthis.activeScreen.clearCache();\n\t\t\t} else {\n\t\t\t\tthis.removeScreen(path);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Retrieves or create a screen instance to a path.\n\t * @param {!string} path Path containing the querystring part.\n\t * @return {Screen}\n\t */\n\tcreateScreenInstance(path, route) {\n\t\tif (!this.pendingNavigate && path === this.activePath) {\n\t\t\tconsole.log('Already at destination, refresh navigation');\n\t\t\treturn this.activeScreen;\n\t\t}\n\t\t/* jshint newcap: false */\n\t\tvar screen = this.screens[path];\n\t\tif (!screen) {\n\t\t\tvar handler = route.getHandler();\n\t\t\tif (handler === Screen || Screen.isImplementedBy(handler.prototype)) {\n\t\t\t\tscreen = new handler();\n\t\t\t} else {\n\t\t\t\tscreen = handler(route) || new Screen();\n\t\t\t}\n\t\t\tconsole.log('Create screen for [' + path + '] [' + screen + ']');\n\t\t}\n\t\treturn screen;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdisposeInternal() {\n\t\tif (this.activeScreen) {\n\t\t\tthis.removeScreen(this.activePath);\n\t\t}\n\t\tthis.clearScreensCache();\n\t\tthis.formEventHandler_.removeListener();\n\t\tthis.linkEventHandler_.removeListener();\n\t\tthis.appEventHandlers_.removeAllListeners();\n\t\tsuper.disposeInternal();\n\t}\n\n\t/**\n\t * Dispatches to the first route handler that matches the current path, if\n\t * any.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tdispatch() {\n\t\treturn this.navigate(utils.getCurrentBrowserPath(), true);\n\t}\n\n\t/**\n\t * Starts navigation to a path.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tdoNavigate_(path, opt_replaceHistory) {\n\t\tif (this.activeScreen && this.activeScreen.beforeDeactivate()) {\n\t\t\tthis.pendingNavigate = CancellablePromise.reject(new CancellablePromise.CancellationError('Cancelled by active screen'));\n\t\t\treturn this.pendingNavigate;\n\t\t}\n\n\t\tvar route = this.findRoute(path);\n\t\tif (!route) {\n\t\t\tthis.pendingNavigate = CancellablePromise.reject(new CancellablePromise.CancellationError('No route for ' + path));\n\t\t\treturn this.pendingNavigate;\n\t\t}\n\n\t\tconsole.log('Navigate to [' + path + ']');\n\n\t\tthis.stopPendingNavigate_();\n\n\t\tvar nextScreen = this.createScreenInstance(path, route);\n\n\t\treturn nextScreen.load(path)\n\t\t\t.then(() => {\n\t\t\t\tif (this.activeScreen) {\n\t\t\t\t\tthis.activeScreen.deactivate();\n\t\t\t\t}\n\t\t\t\tthis.prepareNavigateHistory_(path, nextScreen, opt_replaceHistory);\n\t\t\t\tthis.prepareNavigateSurfaces_(nextScreen, this.surfaces);\n\t\t\t})\n\t\t\t.then(() => nextScreen.evaluateStyles(this.surfaces))\n\t\t\t.then(() => nextScreen.flip(this.surfaces))\n\t\t\t.then(() => nextScreen.evaluateScripts(this.surfaces))\n\t\t\t.then(() => this.syncScrollPositionSyncThenAsync_())\n\t\t\t.then(() => this.finalizeNavigate_(path, nextScreen))\n\t\t\t.catch((reason) => {\n\t\t\t\tthis.handleNavigateError_(path, nextScreen, reason);\n\t\t\t\tthrow reason;\n\t\t\t});\n\t}\n\n\t/**\n\t * Finalizes a screen navigation.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @protected\n\t */\n\tfinalizeNavigate_(path, nextScreen) {\n\t\tnextScreen.activate();\n\n\t\tif (this.activeScreen && !this.activeScreen.isCacheable()) {\n\t\t\tif (this.activeScreen !== nextScreen) {\n\t\t\t\tthis.removeScreen(this.activePath);\n\t\t\t}\n\t\t}\n\n\t\tthis.activePath = path;\n\t\tthis.activeScreen = nextScreen;\n\t\tthis.screens[path] = nextScreen;\n\t\tthis.pendingNavigate = null;\n\t\tglobals.capturedFormElement = null;\n\t\tconsole.log('Navigation done');\n\t}\n\n\t/**\n\t * Finds a route for the test path. Returns true if matches has a route,\n\t * otherwise returns null.\n\t * @param {!string} path Path containing the querystring part.\n\t * @return {?Object} Route handler if match any or null if the\n\t * path is the same as the current url and the path contains a fragment.\n\t */\n\tfindRoute(path) {\n\t\t// Prevents navigation if it's a hash change on the same url.\n\t\tif ((path.lastIndexOf('#') > -1) && utils.isCurrentBrowserPath(path)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tpath = utils.getUrlPathWithoutHash(path);\n\n\t\t// Makes sure that the path substring will be in the expected format\n\t\t// (that is, will end with a \"/\").\n\t\tpath = utils.getUrlPathWithoutHash(path.substr(this.basePath.length));\n\n\t\tfor (var i = 0; i < this.routes.length; i++) {\n\t\t\tvar route = this.routes[i];\n\t\t\tif (route.matchesPath(path)) {\n\t\t\t\treturn route;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Gets allow prevent navigate.\n\t * @return {boolean}\n\t */\n\tgetAllowPreventNavigate() {\n\t\treturn this.allowPreventNavigate;\n\t}\n\n\t/**\n\t * Gets link base path.\n\t * @return {!string}\n\t */\n\tgetBasePath() {\n\t\treturn this.basePath;\n\t}\n\n\t/**\n\t * Gets the default page title.\n\t * @return {string} defaultTitle\n\t */\n\tgetDefaultTitle() {\n\t\treturn this.defaultTitle;\n\t}\n\n\t/**\n\t * Gets the form selector.\n\t * @return {!string}\n\t */\n\tgetFormSelector() {\n\t\treturn this.formSelector;\n\t}\n\n\t/**\n\t * Gets the link selector.\n\t * @return {!string}\n\t */\n\tgetLinkSelector() {\n\t\treturn this.linkSelector;\n\t}\n\n\t/**\n\t * Gets the loading css class.\n\t * @return {!string}\n\t */\n\tgetLoadingCssClass() {\n\t\treturn this.loadingCssClass;\n\t}\n\n\t/**\n\t * Gets the update scroll position value.\n\t * @return {boolean}\n\t */\n\tgetUpdateScrollPosition() {\n\t\treturn this.updateScrollPosition;\n\t}\n\n\t/**\n\t * Handle navigation error.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @param {!Error} error\n\t * @protected\n\t */\n\thandleNavigateError_(path, nextScreen, err) {\n\t\tconsole.log('Navigation error for [' + nextScreen + '] (' + err + ')');\n\t\tif (!utils.isCurrentBrowserPath(path)) {\n\t\t\tthis.removeScreen(path);\n\t\t}\n\t}\n\n\t/**\n\t * Checks if app has routes.\n\t * @return {boolean}\n\t */\n\thasRoutes() {\n\t\treturn this.routes.length > 0;\n\t}\n\n\t/**\n\t * Tests if hostname is an offsite link.\n\t * @param {!string} hostname Link hostname to compare with\n\t * globals.window.location.hostname.\n\t * @return {boolean}\n\t * @protected\n\t */\n\tisLinkSameOrigin_(hostname) {\n\t\treturn hostname === globals.window.location.hostname;\n\t}\n\n\t/**\n\t * Tests if link element has the same app's base path.\n\t * @param {!string} path Link path containing the querystring part.\n\t * @return {boolean}\n\t * @protected\n\t */\n\tisSameBasePath_(path) {\n\t\treturn path.indexOf(this.basePath) === 0;\n\t}\n\n\t/**\n\t * Lock the document scroll in order to avoid the browser native back and\n\t * forward navigation to change the scroll position. In the end of\n\t * navigation lifecycle scroll is repositioned.\n\t * @protected\n\t */\n\tlockHistoryScrollPosition_() {\n\t\tvar state = globals.window.history.state;\n\t\tif (!state) {\n\t\t\treturn;\n\t\t}\n\t\t// Browsers are inconsistent when re-positioning the scroll history on\n\t\t// popstate. At some browsers, history scroll happens before popstate, then\n\t\t// lock the scroll on the last known position as soon as possible after the\n\t\t// current JS execution context and capture the current value. Some others,\n\t\t// history scroll happens after popstate, in this case, we bind an once\n\t\t// scroll event to lock the las known position. Lastly, the previous two\n\t\t// behaviors can happen even on the same browser, hence the race will decide\n\t\t// the winner.\n\t\tvar winner = false;\n\t\tvar switchScrollPositionRace = function() {\n\t\t\tglobals.document.removeEventListener('scroll', switchScrollPositionRace, false);\n\t\t\tif (!winner) {\n\t\t\t\tglobals.window.scrollTo(state.scrollLeft, state.scrollTop);\n\t\t\t\twinner = true;\n\t\t\t}\n\t\t};\n\t\tasync.nextTick(switchScrollPositionRace);\n\t\tglobals.document.addEventListener('scroll', switchScrollPositionRace, false);\n\t}\n\n\t/**\n\t * If supported by the browser, disables native scroll restoration and\n\t * stores current value.\n\t */\n\tmaybeDisableNativeScrollRestoration() {\n\t\tif (this.nativeScrollRestorationSupported) {\n\t\t\tthis.nativeScrollRestoration_ = globals.window.history.scrollRestoration;\n\t\t\tglobals.window.history.scrollRestoration = 'manual';\n\t\t}\n\t}\n\n\t/**\n\t * Maybe navigate to a path.\n\t * @param {string} href Information about the link's href.\n\t * @param {Event} event Dom event that initiated the navigation.\n\t */\n\tmaybeNavigate_(href, event) {\n\t\tif (!this.canNavigate(href)) {\n\t\t\treturn;\n\t\t}\n\n\t\tglobals.capturedFormElement = event.capturedFormElement;\n\n\t\tvar navigateFailed = false;\n\t\ttry {\n\t\t\tthis.navigate(utils.getUrlPath(href));\n\t\t} catch (err) {\n\t\t\t// Do not prevent link navigation in case some synchronous error occurs\n\t\t\tnavigateFailed = true;\n\t\t}\n\n\t\tif (!navigateFailed) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n\n\t/**\n\t * Maybe reposition scroll to hashed anchor.\n\t */\n\tmaybeRepositionScrollToHashedAnchor() {\n\t\tvar hash = globals.window.location.hash;\n\t\tif (hash) {\n\t\t\tvar anchorElement = globals.document.getElementById(hash.substring(1));\n\t\t\tif (anchorElement) {\n\t\t\t\tglobals.window.scrollTo(anchorElement.offsetLeft, anchorElement.offsetTop);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If supported by the browser, restores native scroll restoration to the\n\t * value captured by `maybeDisableNativeScrollRestoration`.\n\t */\n\tmaybeRestoreNativeScrollRestoration() {\n\t\tif (this.nativeScrollRestorationSupported && this.nativeScrollRestoration_) {\n\t\t\tglobals.window.history.scrollRestoration = this.nativeScrollRestoration_;\n\t\t}\n\t}\n\n\t/**\n\t * Navigates to the specified path if there is a route handler that matches.\n\t * @param {!string} path Path to navigate containing the base path.\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tnavigate(path, opt_replaceHistory) {\n\t\tif (!utils.isHtml5HistorySupported()) {\n\t\t\tthrow new Error('HTML5 History is not supported. Senna will not intercept navigation.');\n\t\t}\n\n\t\t// When reloading the same path do replaceState instead of pushState to\n\t\t// avoid polluting history with states with the same path.\n\t\tif (path === this.activePath) {\n\t\t\topt_replaceHistory = true;\n\t\t}\n\n\t\tthis.emit('beforeNavigate', {\n\t\t\tpath: path,\n\t\t\treplaceHistory: !!opt_replaceHistory\n\t\t});\n\n\t\treturn this.pendingNavigate;\n\t}\n\n\t/**\n\t * Befores navigation to a path.\n\t * @param {!Event} event Event facade containing path and\n\t * replaceHistory.\n\t * @protected\n\t */\n\tonBeforeNavigate_(event) {\n\t\tif (globals.capturedFormElement) {\n\t\t\tevent.form = globals.capturedFormElement;\n\t\t}\n\t}\n\n\t/**\n\t * Befores navigation to a path. Runs after external listeners.\n\t * @param {!Event} event Event facade containing path and\n\t * replaceHistory.\n\t * @protected\n\t */\n\tonBeforeNavigateDefault_(event) {\n\t\tif (this.pendingNavigate) {\n\t\t\tif (this.pendingNavigate.path === event.path) {\n\t\t\t\tconsole.log('Waiting...');\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthis.emit('startNavigate', {\n\t\t\tform: event.form,\n\t\t\tpath: event.path,\n\t\t\treplaceHistory: event.replaceHistory\n\t\t});\n\t}\n\n\t/**\n\t * Intercepts document clicks and test link elements in order to decide\n\t * whether Surface app can navigate.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonDocClickDelegate_(event) {\n\t\tif (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || event.button) {\n\t\t\tconsole.log('Navigate aborted, invalid mouse button or modifier key pressed.');\n\t\t\treturn;\n\t\t}\n\t\tthis.maybeNavigate_(event.delegateTarget.href, event);\n\t}\n\n\t/**\n\t * Intercepts document form submits and test action path in order to decide\n\t * whether Surface app can navigate.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonDocSubmitDelegate_(event) {\n\t\tvar form = event.delegateTarget;\n\t\tif (form.method === 'get') {\n\t\t\tconsole.log('GET method not supported');\n\t\t\treturn;\n\t\t}\n\t\tevent.capturedFormElement = form;\n\t\tthis.maybeNavigate_(form.action, event);\n\t}\n\n\t/**\n\t * Listens to the window's load event in order to avoid issues with some browsers\n\t * that trigger popstate calls on the first load. For more information see\n\t * http://stackoverflow.com/questions/6421769/popstate-on-pages-load-in-chrome.\n\t * @protected\n\t */\n\tonLoad_() {\n\t\tthis.skipLoadPopstate = true;\n\t\tsetTimeout(() => {\n\t\t\t// The timeout ensures that popstate events will be unblocked right\n\t\t\t// after the load event occured, but not in the same event-loop cycle.\n\t\t\tthis.skipLoadPopstate = false;\n\t\t}, 0);\n\t\t// Try to reposition scroll to the hashed anchor when page loads.\n\t\tthis.maybeRepositionScrollToHashedAnchor();\n\t}\n\n\t/**\n\t * Handles browser history changes and fires app's navigation if the state\n\t * belows to us. If we detect a popstate and the state is null,\n\t * assume it is navigating to an external page or to a page we don't have\n\t * route, then globals.window.location.reload() is invoked in order to\n\t * reload the content to the current url.\n\t * @param {!Event} event Event facade\n\t * @protected\n\t */\n\tonPopstate_(event) {\n\t\tif (this.skipLoadPopstate) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar state = event.state;\n\n\t\tif (!state) {\n\t\t\tif (globals.window.location.hash) {\n\t\t\t\t// If senna is on an redirect path and a hash popstate happens\n\t\t\t\t// to a different url, reload the browser. This behavior doesn't\n\t\t\t\t// require senna to route hashed links and is closer to native\n\t\t\t\t// browser behavior.\n\t\t\t\tif (this.redirectPath && !utils.isCurrentBrowserPath(this.redirectPath)) {\n\t\t\t\t\tthis.reloadPage();\n\t\t\t\t}\n\t\t\t\t// Always try to reposition scroll to the hashed anchor when\n\t\t\t\t// hash popstate happens.\n\t\t\t\tthis.maybeRepositionScrollToHashedAnchor();\n\t\t\t} else {\n\t\t\t\tthis.reloadPage();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (state.senna) {\n\t\t\tconsole.log('History navigation to [' + state.path + ']');\n\t\t\tthis.popstateScrollTop = state.scrollTop;\n\t\t\tthis.popstateScrollLeft = state.scrollLeft;\n\t\t\tif (!this.nativeScrollRestorationSupported) {\n\t\t\t\tthis.lockHistoryScrollPosition_();\n\t\t\t}\n\t\t\tthis.navigate(state.path, true);\n\t\t}\n\t}\n\n\t/**\n\t * Listens document scroll changes in order to capture the possible lock\n\t * scroll position for history scrolling.\n\t * @protected\n\t */\n\tonScroll_() {\n\t\tif (this.captureScrollPositionFromScrollEvent) {\n\t\t\tthis.saveHistoryCurrentPageScrollPosition_();\n\t\t}\n\t}\n\n\t/**\n\t * Starts navigation to a path.\n\t * @param {!Event} event Event facade containing path and\n\t * replaceHistory.\n\t * @protected\n\t */\n\tonStartNavigate_(event) {\n\t\tthis.maybeDisableNativeScrollRestoration();\n\t\tthis.captureScrollPositionFromScrollEvent = false;\n\t\tdom.addClasses(globals.document.documentElement, this.loadingCssClass);\n\n\t\tvar endNavigatePayload = {\n\t\t\tform: event.form,\n\t\t\tpath: event.path\n\t\t};\n\n\t\tthis.pendingNavigate = this.doNavigate_(event.path, event.replaceHistory)\n\t\t\t.catch((reason) => {\n\t\t\t\tendNavigatePayload.error = reason;\n\t\t\t\tthrow reason;\n\t\t\t})\n\t\t\t.thenAlways(() => {\n\t\t\t\tif (!this.pendingNavigate) {\n\t\t\t\t\tdom.removeClasses(globals.document.documentElement, this.loadingCssClass);\n\t\t\t\t\tthis.maybeRestoreNativeScrollRestoration();\n\t\t\t\t\tthis.captureScrollPositionFromScrollEvent = true;\n\t\t\t\t}\n\t\t\t\tthis.emit('endNavigate', endNavigatePayload);\n\t\t\t});\n\n\t\tthis.pendingNavigate.path = event.path;\n\t}\n\n\t/**\n\t * Prefetches the specified path if there is a route handler that matches.\n\t * @param {!string} path Path to navigate containing the base path.\n\t * @return {CancellablePromise} Returns a pending request cancellable promise.\n\t */\n\tprefetch(path) {\n\t\tvar route = this.findRoute(path);\n\t\tif (!route) {\n\t\t\treturn CancellablePromise.reject(new CancellablePromise.CancellationError('No route for ' + path));\n\t\t}\n\n\t\tconsole.log('Prefetching [' + path + ']');\n\n\t\tvar nextScreen = this.createScreenInstance(path, route);\n\n\t\treturn nextScreen.load(path)\n\t\t\t.then(() => this.screens[path] = nextScreen)\n\t\t\t.catch((reason) => {\n\t\t\t\tthis.handleNavigateError_(path, nextScreen, reason);\n\t\t\t\tthrow reason;\n\t\t\t});\n\t}\n\n\t/**\n\t * Prepares screen flip. Updates history state and surfaces content.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!Screen} nextScreen\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t */\n\tprepareNavigateHistory_(path, nextScreen, opt_replaceHistory) {\n\t\tvar title = nextScreen.getTitle();\n\t\tif (!core.isString(title)) {\n\t\t\ttitle = this.getDefaultTitle();\n\t\t}\n\t\tvar redirectPath = nextScreen.beforeUpdateHistoryPath(path);\n\t\tvar historyState = {\n\t\t\tform: core.isDefAndNotNull(globals.capturedFormElement),\n\t\t\tredirectPath: redirectPath,\n\t\t\tpath: path,\n\t\t\tsenna: true,\n\t\t\tscrollTop: 0,\n\t\t\tscrollLeft: 0\n\t\t};\n\t\tif (opt_replaceHistory) {\n\t\t\thistoryState.scrollTop = this.popstateScrollTop;\n\t\t\thistoryState.scrollLeft = this.popstateScrollLeft;\n\t\t}\n\t\tthis.updateHistory_(title, redirectPath, nextScreen.beforeUpdateHistoryState(historyState), opt_replaceHistory);\n\t\tthis.redirectPath = redirectPath;\n\t}\n\n\t/**\n\t * Prepares screen flip. Updates history state and surfaces content.\n\t * @param {!Screen} nextScreen\n\t * @param {!object} surfaces Map of surfaces to flip keyed by surface id.\n\t */\n\tprepareNavigateSurfaces_(nextScreen, surfaces) {\n\t\tObject.keys(surfaces).forEach((id) => {\n\t\t\tvar surfaceContent = nextScreen.getSurfaceContent(id);\n\t\t\tsurfaces[id].addContent(nextScreen.getId(), surfaceContent);\n\t\t\tconsole.log('Screen [' + nextScreen.getId() + '] add content to surface ' +\n\t\t\t\t'[' + surfaces[id] + '] [' + (core.isDefAndNotNull(surfaceContent) ? '...' : 'empty') + ']');\n\t\t});\n\t}\n\n\t/**\n\t * Reloads the page by performing `window.location.reload()`.\n\t */\n\treloadPage() {\n\t\tglobals.window.location.reload();\n\t}\n\n\t/**\n\t * Removes route instance from app routes.\n\t * @param {Route} route\n\t * @return {boolean} True if an element was removed.\n\t */\n\tremoveRoute(route) {\n\t\treturn array.remove(this.routes, route);\n\t}\n\n\t/**\n\t * Removes a screen.\n\t * @param {!string} path Path containing the querystring part.\n\t */\n\tremoveScreen(path) {\n\t\tvar screen = this.screens[path];\n\t\tif (screen) {\n\t\t\tObject.keys(this.surfaces).forEach((surfaceId) => this.surfaces[surfaceId].remove(screen.getId()));\n\t\t\tscreen.dispose();\n\t\t\tdelete this.screens[path];\n\t\t}\n\t}\n\n\t/**\n\t * Saves scroll position from page offset into history state.\n\t */\n\tsaveHistoryCurrentPageScrollPosition_() {\n\t\tvar state = globals.window.history.state;\n\t\tif (state && state.senna) {\n\t\t\tstate.scrollTop = globals.window.pageYOffset;\n\t\t\tstate.scrollLeft = globals.window.pageXOffset;\n\t\t\tglobals.window.history.replaceState(state, null, null);\n\t\t}\n\t}\n\n\t/**\n\t * Sets allow prevent navigate.\n\t * @param {boolean} allowPreventNavigate\n\t */\n\tsetAllowPreventNavigate(allowPreventNavigate) {\n\t\tthis.allowPreventNavigate = allowPreventNavigate;\n\t}\n\n\t/**\n\t * Sets link base path.\n\t * @param {!string} path\n\t */\n\tsetBasePath(basePath) {\n\t\tthis.basePath = basePath;\n\t}\n\n\t/**\n\t * Sets the default page title.\n\t * @param {string} defaultTitle\n\t */\n\tsetDefaultTitle(defaultTitle) {\n\t\tthis.defaultTitle = defaultTitle;\n\t}\n\n\t/**\n\t * Sets the form selector.\n\t * @param {!string} formSelector\n\t */\n\tsetFormSelector(formSelector) {\n\t\tthis.formSelector = formSelector;\n\t\tif (this.formEventHandler_) {\n\t\t\tthis.formEventHandler_.removeListener();\n\t\t}\n\t\tthis.formEventHandler_ = dom.delegate(document, 'submit', this.formSelector, this.onDocSubmitDelegate_.bind(this), this.allowPreventNavigate);\n\t}\n\n\t/**\n\t * Sets the link selector.\n\t * @param {!string} linkSelector\n\t */\n\tsetLinkSelector(linkSelector) {\n\t\tthis.linkSelector = linkSelector;\n\t\tif (this.linkEventHandler_) {\n\t\t\tthis.linkEventHandler_.removeListener();\n\t\t}\n\t\tthis.linkEventHandler_ = dom.delegate(document, 'click', this.linkSelector, this.onDocClickDelegate_.bind(this), this.allowPreventNavigate);\n\t}\n\n\t/**\n\t * Sets the loading css class.\n\t * @param {!string} loadingCssClass\n\t */\n\tsetLoadingCssClass(loadingCssClass) {\n\t\tthis.loadingCssClass = loadingCssClass;\n\t}\n\n\t/**\n\t * Sets the update scroll position value.\n\t * @param {boolean} updateScrollPosition\n\t */\n\tsetUpdateScrollPosition(updateScrollPosition) {\n\t\tthis.updateScrollPosition = updateScrollPosition;\n\t}\n\n\t/**\n\t * Cancels pending navigate with Cancel pending navigation error.\n\t * @protected\n\t */\n\tstopPendingNavigate_() {\n\t\tif (this.pendingNavigate) {\n\t\t\tthis.pendingNavigate.cancel('Cancel pending navigation');\n\t\t\tthis.pendingNavigate = null;\n\t\t}\n\t}\n\n\t/**\n\t * Sync document scroll position twice, the first one synchronous and then\n\t * one inside async.nextTick. Relevant to browsers that fires\n\t * scroll restoration asynchronously after popstate.\n\t * @protected\n\t * @return {?CancellablePromise=}\n\t */\n\tsyncScrollPositionSyncThenAsync_() {\n\t\tvar state = globals.window.history.state;\n\t\tif (!state) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar scrollTop = state.scrollTop;\n\t\tvar scrollLeft = state.scrollLeft;\n\n\t\tvar sync = () => {\n\t\t\tif (this.updateScrollPosition) {\n\t\t\t\tglobals.window.scrollTo(scrollLeft, scrollTop);\n\t\t\t}\n\t\t};\n\n\t\treturn new CancellablePromise((resolve) => sync() & async.nextTick(() => sync() & resolve()));\n\t}\n\n\t/**\n\t * Updates or replace browser history.\n\t * @param {?string} title Document title.\n\t * @param {!string} path Path containing the querystring part.\n\t * @param {!object} state\n\t * @param {boolean=} opt_replaceHistory Replaces browser history.\n\t * @protected\n\t */\n\tupdateHistory_(title, path, state, opt_replaceHistory) {\n\t\tif (opt_replaceHistory) {\n\t\t\tglobals.window.history.replaceState(state, title, path);\n\t\t} else {\n\t\t\tglobals.window.history.pushState(state, title, path);\n\t\t}\n\t\tglobals.document.title = title;\n\t}\n\n}\n\nexport default App;\n"],"sourceRoot":"/source/"}
\ No newline at end of file
diff --git a/build/globals/senna-debug.js b/build/globals/senna-debug.js
index 5867203..a0b0641 100644
--- a/build/globals/senna-debug.js
+++ b/build/globals/senna-debug.js
@@ -1,7 +1,7 @@
/**
* Senna.js - A blazing-fast Single Page Application engine
* @author Eduardo Lundgren
- * @version v1.2.0
+ * @version v1.3.0
* @link http://sennajs.com
* @license BSD-3-Clause
*/
@@ -154,15 +154,21 @@ babelHelpers;
* mutated with an unique id. Consecutive calls with the same object
* reference won't mutate the object again, instead the current object uid
* returns. See {@link core.UID_PROPERTY}.
- * @type {opt_object} Optional object to be mutated with the uid. If not
- * specified this method only returns the uid.
+ * @param {Object=} opt_object Optional object to be mutated with the uid. If
+ * not specified this method only returns the uid.
+ * @param {boolean=} opt_noInheritance Optional flag indicating if this
+ * object's uid property can be inherited from parents or not.
* @throws {Error} when invoked to indicate the method should be overridden.
*/
- core.getUid = function getUid(opt_object) {
+ core.getUid = function getUid(opt_object, opt_noInheritance) {
if (opt_object) {
- return opt_object[core.UID_PROPERTY] || (opt_object[core.UID_PROPERTY] = core.uniqueIdCounter_++);
+ var id = opt_object[core.UID_PROPERTY];
+ if (opt_noInheritance && !opt_object.hasOwnProperty(core.UID_PROPERTY)) {
+ id = null;
+ }
+ return id || (opt_object[core.UID_PROPERTY] = core.uniqueIdCounter_++);
}
return core.uniqueIdCounter_++;
};
@@ -980,6 +986,35 @@ babelHelpers;
}).call(this);
'use strict';
+(function () {
+ var METAL_DATA = '__metal_data__';
+
+ this.senna.metalData = function () {
+ function thisSennaMetalData() {
+ babelHelpers.classCallCheck(this, thisSennaMetalData);
+ }
+
+ /**
+ * Gets Metal.js's data for the given element.
+ * @param {!Element} element
+ * @return {!Object}
+ */
+
+ thisSennaMetalData.get = function get(element) {
+ if (!element[METAL_DATA]) {
+ element[METAL_DATA] = {
+ delegating: {},
+ listeners: {}
+ };
+ }
+ return element[METAL_DATA];
+ };
+
+ return thisSennaMetalData;
+ }();
+}).call(this);
+'use strict';
+
(function () {
var Disposable = this.sennaNamed.metal.Disposable;
@@ -1776,6 +1811,64 @@ babelHelpers;
}).call(this);
'use strict';
+(function () {
+ var array = this.sennaNamed.metal.array;
+ var core = this.sennaNamed.metal.core;
+ var metalData = this.senna.metalData;
+ var EventHandle = this.sennaNamed.events.EventHandle;
+
+ /**
+ * This is a special EventHandle, that is responsible for dom delegated events
+ * (only the ones that receive a target element, not a selector string).
+ * @extends {EventHandle}
+ */
+
+ var DomDelegatedEventHandle = function (_EventHandle) {
+ babelHelpers.inherits(DomDelegatedEventHandle, _EventHandle);
+
+ /**
+ * The constructor for `DomDelegatedEventHandle`.
+ * @param {!Event} emitter Element the event was subscribed to.
+ * @param {string} event The name of the event that was subscribed to.
+ * @param {!Function} listener The listener subscribed to the event.
+ * @param {string=} opt_selector An optional selector used when delegating
+ * the event.
+ * @constructor
+ */
+
+ function DomDelegatedEventHandle(emitter, event, listener, opt_selector) {
+ babelHelpers.classCallCheck(this, DomDelegatedEventHandle);
+
+ var _this = babelHelpers.possibleConstructorReturn(this, _EventHandle.call(this, emitter, event, listener));
+
+ _this.selector_ = opt_selector;
+ return _this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+
+
+ DomDelegatedEventHandle.prototype.removeListener = function removeListener() {
+ var data = metalData.get(this.emitter_);
+ var selector = this.selector_;
+ var arr = core.isString(selector) ? data.delegating[this.event_].selectors : data.listeners;
+ var key = core.isString(selector) ? selector : this.event_;
+
+ array.remove(arr[key] || [], this.listener_);
+ if (arr[key] && arr[key].length === 0) {
+ delete arr[key];
+ }
+ };
+
+ return DomDelegatedEventHandle;
+ }(EventHandle);
+
+ this.senna.DomDelegatedEventHandle = DomDelegatedEventHandle;
+}).call(this);
+'use strict';
+
(function () {
var EventHandle = this.sennaNamed.events.EventHandle;
@@ -1826,8 +1919,18 @@ babelHelpers;
(function () {
var core = this.sennaNamed.metal.core;
var object = this.sennaNamed.metal.object;
+ var metalData = this.senna.metalData;
+ var DomDelegatedEventHandle = this.senna.DomDelegatedEventHandle;
var DomEventHandle = this.senna.DomEventHandle;
+
+ var NEXT_TARGET = '__metal_next_target__';
+ var USE_CAPTURE = {
+ blur: true,
+ focus: true,
+ scroll: true
+ };
+
var dom = function () {
function dom() {
babelHelpers.classCallCheck(this, dom);
@@ -1894,6 +1997,71 @@ babelHelpers;
}
};
+ /**
+ * Adds an event listener to the given element, to be triggered via delegate.
+ * @param {!Element} element
+ * @param {string} eventName
+ * @param {!function()} listener
+ * @protected
+ */
+
+
+ dom.addElementListener_ = function addElementListener_(element, eventName, listener) {
+ var data = metalData.get(element);
+ dom.addToArr_(data.listeners, eventName, listener);
+ };
+
+ /**
+ * Adds an event listener to the given element, to be triggered via delegate
+ * selectors.
+ * @param {!Element} element
+ * @param {string} eventName
+ * @param {string} selector
+ * @param {!function()} listener
+ * @protected
+ */
+
+
+ dom.addSelectorListener_ = function addSelectorListener_(element, eventName, selector, listener) {
+ var data = metalData.get(element);
+ dom.addToArr_(data.delegating[eventName].selectors, selector, listener);
+ };
+
+ /**
+ * Adds a value to an array inside an object, creating it first if it doesn't
+ * yet exist.
+ * @param {!Array} arr
+ * @param {string} key
+ * @param {*} value
+ * @protected
+ */
+
+
+ dom.addToArr_ = function addToArr_(arr, key, value) {
+ if (!arr[key]) {
+ arr[key] = [];
+ }
+ arr[key].push(value);
+ };
+
+ /**
+ * Attaches a delegate listener, unless there's already one attached.
+ * @param {!Element} element
+ * @param {string} eventName
+ * @protected
+ */
+
+
+ dom.attachDelegateEvent_ = function attachDelegateEvent_(element, eventName) {
+ var data = metalData.get(element);
+ if (!data.delegating[eventName]) {
+ data.delegating[eventName] = {
+ handle: dom.on(element, eventName, dom.handleDelegateEvent_, !!USE_CAPTURE[eventName]),
+ selectors: {}
+ };
+ }
+ };
+
/**
* Gets the closest element up the tree from the given element (including
* itself) that matches the specified selector, or null if none match.
@@ -1973,25 +2141,43 @@ babelHelpers;
/**
* Listens to the specified event on the given DOM element, but only calls the
- * callback with the event when it triggered by elements that match the given
- * selector.
- * @param {!Element} element The container DOM element to listen to the event on.
+ * given callback listener when it's triggered by elements that match the
+ * given selector or target element.
+ * @param {!Element} element The DOM element the event should be listened on.
* @param {string} eventName The name of the event to listen to.
- * @param {string} selector The selector that matches the child elements that
- * the event should be triggered for.
- * @param {!function(!Object)} callback Function to be called when the event is
- * triggered. It will receive the normalized event object.
- * @return {!DomEventHandle} Can be used to remove the listener.
+ * @param {!Element|string} selectorOrTarget Either an element or css selector
+ * that should match the event for the listener to be triggered.
+ * @param {!function(!Object)} callback Function to be called when the event
+ * is triggered. It will receive the normalized event object.
+ * @param {boolean=} opt_default Optional flag indicating if this is a default
+ * listener. That means that it would only be executed after all non
+ * default listeners, and only if the event isn't prevented via
+ * `preventDefault`.
+ * @return {!EventHandle} Can be used to remove the listener.
*/
- dom.delegate = function delegate(element, eventName, selector, callback) {
+ dom.delegate = function delegate(element, eventName, selectorOrTarget, callback, opt_default) {
var customConfig = dom.customEvents[eventName];
if (customConfig && customConfig.delegate) {
eventName = customConfig.originalEvent;
callback = customConfig.handler.bind(customConfig, callback);
}
- return dom.on(element, eventName, dom.handleDelegateEvent_.bind(null, selector, callback));
+
+ if (opt_default) {
+ // Wrap callback so we don't set property directly on it.
+ callback = callback.bind();
+ callback.defaultListener_ = true;
+ }
+
+ dom.attachDelegateEvent_(element, eventName);
+ if (core.isString(selectorOrTarget)) {
+ dom.addSelectorListener_(element, eventName, selectorOrTarget, callback);
+ } else {
+ dom.addElementListener_(selectorOrTarget, eventName, callback);
+ }
+
+ return new DomDelegatedEventHandle(core.isString(selectorOrTarget) ? element : selectorOrTarget, eventName, callback, core.isString(selectorOrTarget) ? selectorOrTarget : null);
};
/**
@@ -2017,37 +2203,38 @@ babelHelpers;
};
/**
- * This is called when an event is triggered by a delegate listener (see
- * `dom.delegate` for more details).
- * @param {string} selector The selector or element that matches the child
- * elements that the event should be triggered for.
- * @param {!function(!Object)} callback Function to be called when the event
- * is triggered. It will receive the normalized event object.
+ * This is called when an event is triggered by a delegate listener. All
+ * matching listeners of this event type from `target` to `currentTarget` will
+ * be triggered.
* @param {!Event} event The event payload.
* @return {boolean} False if at least one of the triggered callbacks returns
- * false, or true otherwise.
+ * false, or true otherwise.
+ * @protected
*/
- dom.handleDelegateEvent_ = function handleDelegateEvent_(selector, callback, event) {
+ dom.handleDelegateEvent_ = function handleDelegateEvent_(event) {
dom.normalizeDelegateEvent_(event);
+ var currElement = core.isDef(event[NEXT_TARGET]) ? event[NEXT_TARGET] : event.target;
+ var ret = true;
+ var container = event.currentTarget;
+ var limit = event.currentTarget.parentNode;
+ var defFns = [];
- var currentElement = event.target;
- var returnValue = true;
+ while (currElement && currElement !== limit && !event.stopped) {
+ event.delegateTarget = currElement;
+ ret &= dom.triggerMatchedListeners_(container, currElement, event, defFns);
+ currElement = currElement.parentNode;
+ }
- while (currentElement && !event.stopped) {
- if (core.isString(selector) && dom.match(currentElement, selector)) {
- event.delegateTarget = currentElement;
- returnValue &= callback(event);
- }
- if (currentElement === event.currentTarget) {
- break;
- }
- currentElement = currentElement.parentNode;
+ for (var i = 0; i < defFns.length && !event.defaultPrevented; i++) {
+ event.delegateTarget = defFns[i].element;
+ ret &= defFns[i].fn(event);
}
- event.delegateTarget = null;
- return returnValue;
+ event.delegateTarget = null;
+ event[NEXT_TARGET] = limit;
+ return ret;
};
/**
@@ -2337,6 +2524,7 @@ babelHelpers;
dom.stopImmediatePropagation_ = function stopImmediatePropagation_() {
this.stopped = true;
+ this.stoppedImmediate = true;
Event.prototype.stopImmediatePropagation.call(this);
};
@@ -2476,6 +2664,66 @@ babelHelpers;
element.dispatchEvent(eventObj);
};
+ /**
+ * Triggers the given listeners array.
+ * @param {Array
- * @version v1.2.0
+ * @version v1.3.0
* @link http://sennajs.com
* @license BSD-3-Clause
*/
-(function(){this.senna=this.senna||{},this.sennaNamed=this.sennaNamed||{};var t={};t["typeof"]="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},t.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},t.inherits=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)},t.possibleConstructorReturn=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},t.slicedToArray=function(){function t(t,e){var n=[],r=!0,i=!1,o=void 0;try{for(var a,s=t[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(l){i=!0,o=l}finally{try{!r&&s["return"]&&s["return"]()}finally{if(i)throw o}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),function(){var e=function(){function e(){t.classCallCheck(this,e)}return e.abstractMethod=function(){throw Error("Unimplemented abstract method")},e.collectSuperClassesProperty=function(t,e){for(var n=[t[e]];t.__proto__&&!t.__proto__.isPrototypeOf(Function);)t=t.__proto__,n.push(t[e]);return n},e.getFunctionName=function(t){if(!t.name){var e=t.toString();t.name=e.substring(9,e.indexOf("("))}return t.name},e.getUid=function(t){return t?t[e.UID_PROPERTY]||(t[e.UID_PROPERTY]=e.uniqueIdCounter_++):e.uniqueIdCounter_++},e.identityFunction=function(t){return t},e.isBoolean=function(t){return"boolean"==typeof t},e.isDef=function(t){return void 0!==t},e.isDefAndNotNull=function(t){return e.isDef(t)&&!e.isNull(t)},e.isDocument=function(e){return e&&"object"===("undefined"==typeof e?"undefined":t["typeof"](e))&&9===e.nodeType},e.isElement=function(e){return e&&"object"===("undefined"==typeof e?"undefined":t["typeof"](e))&&1===e.nodeType},e.isFunction=function(t){return"function"==typeof t},e.isNull=function(t){return null===t},e.isNumber=function(t){return"number"==typeof t},e.isWindow=function(t){return null!==t&&t===t.window},e.isObject=function(e){var n="undefined"==typeof e?"undefined":t["typeof"](e);return"object"===n&&null!==e||"function"===n},e.isPromise=function(e){return e&&"object"===("undefined"==typeof e?"undefined":t["typeof"](e))&&"function"==typeof e.then},e.isString=function(t){return"string"==typeof t},e.mergeSuperClassesProperty=function(t,n,r){var i=n+"_MERGED";if(t.hasOwnProperty(i))return!1;var o=e.collectSuperClassesProperty(t,n);return r&&(o=r(o)),t[i]=o,!0},e.nullFunction=function(){},e}();e.UID_PROPERTY="core_"+(1e9*Math.random()>>>0),e.uniqueIdCounter_=1,this.senna.core=e}.call(this),function(){var e=this.senna.core,n=function(){function n(){t.classCallCheck(this,n)}return n.equal=function(t,e){if(t.length!==e.length)return!1;for(var n=0;n=0)&&n.removeAt(t,i),r},n.removeAt=function(t,e){return 1===Array.prototype.splice.call(t,e,1).length},n.slice=function(t,n,r){for(var i=[],o=e.isDef(r)?r:t.length,a=n;o>a;a++)i.push(t[a]);return i},n}();this.senna.array=n}.call(this),function(){var t={};t.throwException=function(e){t.nextTick(function(){throw e})},t.run=function(e,n){t.run.workQueueScheduled_||(t.nextTick(t.run.processWorkQueue),t.run.workQueueScheduled_=!0),t.run.workQueue_.push(new t.run.WorkItem_(e,n))},t.run.workQueueScheduled_=!1,t.run.workQueue_=[],t.run.processWorkQueue=function(){for(;t.run.workQueue_.length;){var e=t.run.workQueue_;t.run.workQueue_=[];for(var n=0;nn;n++)e=31*e+t.charCodeAt(n),e%=4294967296;return e},e.replaceInterval=function(t,e,n,r){return t.substring(0,e)+r+t.substring(n)},e}();this.senna.string=e}.call(this),function(){var t=this.senna.core,e=this.senna.array,n=this.senna.async,r=this.senna.Disposable,i=this.senna.object,o=this.senna.string;this.senna.metal=t,this.sennaNamed.metal=this.sennaNamed.metal||{},this.sennaNamed.metal.core=t,this.sennaNamed.metal.array=e,this.sennaNamed.metal.async=n,this.sennaNamed.metal.Disposable=r,this.sennaNamed.metal.object=i,this.sennaNamed.metal.string=o}.call(this),function(){var e=this.sennaNamed.metal.Disposable,n=function(e){function n(r,i,o){t.classCallCheck(this,n);var a=t.possibleConstructorReturn(this,e.call(this));return a.emitter_=r,a.event_=i,a.listener_=o,a}return t.inherits(n,e),n.prototype.disposeInternal=function(){this.removeListener(),this.emitter_=null,this.listener_=null},n.prototype.removeListener=function(){this.emitter_.isDisposed()||this.emitter_.removeListener(this.event_,this.listener_)},n}(e);this.senna.EventHandle=n}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.sennaNamed.metal.array,r=this.sennaNamed.metal.Disposable,i=this.senna.EventHandle,o=function(r){function o(){t.classCallCheck(this,o);var e=t.possibleConstructorReturn(this,r.call(this));return e.events_=[],e.maxListeners_=10,e.shouldUseFacade_=!1,e}return t.inherits(o,r),o.prototype.addListener=function(t,e,n){this.validateListener_(e),t=this.normalizeEvents_(t);for(var r=0;rthis.maxListeners_&&!i.warned&&(i.warned=!0)},o.prototype.disposeInternal=function(){this.events_=[]},o.prototype.emit=function(t){var e,r=n.slice(arguments,1),i=(this.events_[t]||[]).concat();this.getShouldUseFacade()&&(e={preventDefault:function(){e.preventedDefault=!0},target:this,type:t},r.push(e));for(var o=[],a=0;a0},o.prototype.getShouldUseFacade=function(){return this.shouldUseFacade_},o.prototype.listeners=function(t){return(this.events_[t]||[]).map(function(t){return t.fn})},o.prototype.many=function(t,e,n){t=this.normalizeEvents_(t);for(var r=0;r=e||i.addSingleListener_(t,r,!1,n)},o.prototype.matchesListener_=function(t,e){return t.fn===e||t.origin&&t.origin===e},o.prototype.normalizeEvents_=function(t){return e.isString(t)?[t]:t},o.prototype.off=function(t,e){this.validateListener_(e),t=this.normalizeEvents_(t);for(var n=0;n=0;n--)this.matchesListener_(t[n],e)&&t.splice(n,1)},o.prototype.removeListener=function(){return this.off.apply(this,arguments)},o.prototype.setMaxListeners=function(t){return this.maxListeners_=t,this},o.prototype.setShouldUseFacade=function(t){return this.shouldUseFacade_=t,this},o.prototype.validateListener_=function(t){if(!e.isFunction(t))throw new TypeError("Listener must be a function")},o}(r);this.senna.EventEmitter=o}.call(this),function(){var e=this.sennaNamed.metal.array,n=this.sennaNamed.metal.Disposable,r=function(n){function r(e,i,o,a){t.classCallCheck(this,r);var s=t.possibleConstructorReturn(this,n.call(this));return s.blacklist_=o||{},s.originEmitter_=e,s.pendingEvents_=[],s.proxiedEvents_={},s.targetEmitter_=i,s.whitelist_=a,s.startProxy_(),s}return t.inherits(r,n),r.prototype.addListener_=function(t,e){return this.originEmitter_.on(t,e)},r.prototype.addListenerForEvent_=function(t){return this.addListener_(t,this.emitOnTarget_.bind(this,t))},r.prototype.disposeInternal=function(){this.removeListeners_(),this.proxiedEvents_=null,this.originEmitter_=null,this.targetEmitter_=null},r.prototype.emitOnTarget_=function(t){var n=[t].concat(e.slice(arguments,1));this.targetEmitter_.emit.apply(this.targetEmitter_,n)},r.prototype.proxyEvent=function(t){this.shouldProxyEvent_(t)&&this.tryToAddListener_(t)},r.prototype.removeListeners_=function(){for(var t=Object.keys(this.proxiedEvents_),e=0;e"+t,e.removeChild(e.firstChild);for(var n=document.createDocumentFragment();e.firstChild;)n.appendChild(e.firstChild);return n},i.contains=function(t,n){return e.isDocument(t)?t.documentElement.contains(n):t.contains(n)},i.delegate=function(t,e,n,r){var o=i.customEvents[e];return o&&o.delegate&&(e=o.originalEvent,r=o.handler.bind(o,r)),i.on(t,e,i.handleDelegateEvent_.bind(null,n,r))},i.enterDocument=function(t){t&&i.append(document.body,t)},i.exitDocument=function(t){t&&t.parentNode&&t.parentNode.removeChild(t)},i.handleDelegateEvent_=function(t,n,r){i.normalizeDelegateEvent_(r);for(var o=r.target,a=!0;o&&!r.stopped&&(e.isString(t)&&i.match(o,t)&&(r.delegateTarget=o,a&=n(r)),o!==r.currentTarget);)o=o.parentNode;return r.delegateTarget=null,a},i.hasClass=function(t,e){return"classList"in t?i.hasClassWithNative_(t,e):i.hasClassWithoutNative_(t,e)},i.hasClassWithNative_=function(t,e){return t.classList.contains(e)},i.hasClassWithoutNative_=function(t,e){return(" "+t.className+" ").indexOf(" "+e+" ")>=0},i.isEmpty=function(t){return 0===t.childNodes.length},i.match=function(t,e){if(!t||1!==t.nodeType)return!1;var n=Element.prototype,r=n.matches||n.webkitMatchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector;return r?r.call(t,e):i.matchFallback_(t,e)},i.matchFallback_=function(t,e){for(var n=document.querySelectorAll(e,t.parentNode),r=0;r0?this.unhandledRejectionId_=0:0===a.UNHANDLED_REJECTION_DELAY&&(this.hadUnhandledRejection_=!1);try{var n=this;t.call(e,function(t){n.resolve_(a.State_.FULFILLED,t)},function(t){n.resolve_(a.State_.REJECTED,t)})}catch(r){this.resolve_(a.State_.REJECTED,r)}};o.UNHANDLED_REJECTION_DELAY=0,o.State_={PENDING:0,BLOCKED:1,FULFILLED:2,REJECTED:3},o.CallbackEntry_=null,o.resolve=function(t){return new o(function(e){e(t)})},o.reject=function(t){return new o(function(e,n){n(t)})},o.race=function(t){return new o(function(e,n){t.length||e(void 0);for(var r,i=0;r=t[i];i++)r.then(e,n)})},o.all=function(t){return new o(function(e,n){var r=t.length,o=[];if(!r)return void e(o);for(var a,s=function(t,n){r--,o[t]=n,0===r&&e(o)},l=function(t){n(t)},c=0;a=t[c];c++)a.then(i(s,c),l)})},o.firstFulfilled=function(t){return new o(function(e,n){var r=t.length,o=[];if(!r)return void e(void 0);for(var a,s=function(t){e(t)},l=function(t,e){r--,o[t]=e,0===r&&n(o)},c=0;a=t[c];c++)a.then(s,i(l,c))})},o.prototype.then=function(t,n,r){return this.addChildPromise_(e.isFunction(t)?t:null,e.isFunction(n)?n:null,r)},r.addImplementation(o),o.prototype.thenAlways=function(t,e){var n=function(){try{t.call(e)}catch(n){o.handleRejection_.call(null,n)}};return this.addCallbackEntry_({child:null,onRejected:n,onFulfilled:n}),this},o.prototype.thenCatch=function(t,e){return this.addChildPromise_(null,t,e)},o.prototype["catch"]=o.prototype.thenCatch,o.prototype.cancel=function(t){this.state_===o.State_.PENDING&&n.run(function(){var e=new o.CancellationError(t);e.IS_CANCELLATION_ERROR=!0,this.cancelInternal_(e)},this)},o.prototype.cancelInternal_=function(t){this.state_===o.State_.PENDING&&(this.parent_?this.parent_.cancelChild_(this,t):this.resolve_(o.State_.REJECTED,t))},o.prototype.cancelChild_=function(t,e){if(this.callbackEntries_){for(var n,r=0,i=-1,a=0;n=this.callbackEntries_[a];a++){var s=n.child;if(s&&(r++,s===t&&(i=a),i>=0&&r>1))break}if(i>=0)if(this.state_===o.State_.PENDING&&1===r)this.cancelInternal_(e);else{var l=this.callbackEntries_.splice(i,1)[0];this.executeCallback_(l,o.State_.REJECTED,e)}}},o.prototype.addCallbackEntry_=function(t){this.callbackEntries_&&this.callbackEntries_.length||this.state_!==o.State_.FULFILLED&&this.state_!==o.State_.REJECTED||this.scheduleCallbacks_(),this.callbackEntries_||(this.callbackEntries_=[]),this.callbackEntries_.push(t)},o.prototype.addChildPromise_=function(t,n,r){var i={child:null,onFulfilled:null,onRejected:null};return i.child=new o(function(o,a){i.onFulfilled=t?function(e){try{var n=t.call(r,e);o(n)}catch(i){a(i)}}:o,i.onRejected=n?function(t){try{var i=n.call(r,t);!e.isDef(i)&&t.IS_CANCELLATION_ERROR?a(t):o(i)}catch(s){a(s)}}:a}),i.child.parent_=this,this.addCallbackEntry_(i),i.child},o.prototype.unblockAndFulfill_=function(t){if(this.state_!==o.State_.BLOCKED)throw new Error("CancellablePromise is not blocked.");this.state_=o.State_.PENDING,this.resolve_(o.State_.FULFILLED,t)},o.prototype.unblockAndReject_=function(t){if(this.state_!==o.State_.BLOCKED)throw new Error("CancellablePromise is not blocked.");this.state_=o.State_.PENDING,this.resolve_(o.State_.REJECTED,t)},o.prototype.resolve_=function(t,n){if(this.state_===o.State_.PENDING){if(this===n)t=o.State_.REJECTED,n=new TypeError("CancellablePromise cannot resolve to itself");else{if(r.isImplementedBy(n))return n=n,this.state_=o.State_.BLOCKED,void n.then(this.unblockAndFulfill_,this.unblockAndReject_,this);if(e.isObject(n))try{var i=n.then;if(e.isFunction(i))return void this.tryThen_(n,i)}catch(a){t=o.State_.REJECTED,n=a}}this.result_=n,this.state_=t,this.scheduleCallbacks_(),t!==o.State_.REJECTED||n.IS_CANCELLATION_ERROR||o.addUnhandledRejection_(this,n)}},o.prototype.tryThen_=function(t,e){this.state_=o.State_.BLOCKED;var n=this,r=!1,i=function(t){r||(r=!0,n.unblockAndFulfill_(t))},a=function(t){r||(r=!0,n.unblockAndReject_(t))};try{e.call(t,i,a)}catch(s){a(s)}},o.prototype.scheduleCallbacks_=function(){this.executing_||(this.executing_=!0,n.run(this.executeCallbacks_,this))},o.prototype.executeCallbacks_=function(){for(;this.callbackEntries_&&this.callbackEntries_.length;){var t=this.callbackEntries_;this.callbackEntries_=[];for(var e=0;e0)for(t=this;t&&t.unhandledRejectionId_;t=t.parent_)clearTimeout(t.unhandledRejectionId_),t.unhandledRejectionId_=0;else if(0===o.UNHANDLED_REJECTION_DELAY)for(t=this;t&&t.hadUnhandledRejection_;t=t.parent_)t.hadUnhandledRejection_=!1},o.addUnhandledRejection_=function(t,e){o.UNHANDLED_REJECTION_DELAY>0?t.unhandledRejectionId_=setTimeout(function(){o.handleRejection_.call(null,e)},o.UNHANDLED_REJECTION_DELAY):0===o.UNHANDLED_REJECTION_DELAY&&(t.hadUnhandledRejection_=!0,n.run(function(){t.hadUnhandledRejection_&&o.handleRejection_.call(null,e)}))},o.handleRejection_=n.throwException,o.setUnhandledRejectionHandler=function(t){o.handleRejection_=t},o.CancellationError=function(e){function n(r){t.classCallCheck(this,n);var i=t.possibleConstructorReturn(this,e.call(this,r));return r&&(i.message=r),i}return t.inherits(n,e),n}(Error),o.CancellationError.prototype.name="cancel",this.sennaNamed.Promise=this.sennaNamed.Promise||{},this.sennaNamed.Promise.CancellablePromise=o,this.senna.Promise=o}.call(this),function(){var t={document:document,window:window};this.senna.globals=t}.call(this),function(){function t(t){var e=document.createElement("a");return e.href=t,{hash:e.hash,hostname:e.hostname,password:e.password,pathname:"/"===e.pathname[0]?e.pathname:"/"+e.pathname,port:e.port,protocol:e.protocol,search:e.search,username:e.username}}this.senna.parseFromAnchor=t}.call(this),function(){function t(t){return e.isFunction(URL)&&URL.length?new URL(t):n(t)}var e=this.sennaNamed.metal.core,n=this.senna.parseFromAnchor;this.senna.parse=t}.call(this),function(){var e=this.sennaNamed.metal.Disposable,n=Object.create,r=function(e){function r(){t.classCallCheck(this,r);var i=t.possibleConstructorReturn(this,e.call(this));return i.keys=n(null),i.values=n(null),i}return t.inherits(r,e),r.prototype.add=function(t,e){return this.keys[t.toLowerCase()]=t,this.values[t.toLowerCase()]=this.values[t.toLowerCase()]||[],this.values[t.toLowerCase()].push(e),this},r.prototype.clear=function(){return this.keys=n(null),this.values=n(null),this},r.prototype.contains=function(t){return t.toLowerCase()in this.values},r.prototype.disposeInternal=function(){this.values=null},r.prototype.get=function(t){var e=this.values[t.toLowerCase()];return e?e[0]:void 0},r.prototype.getAll=function(t){return this.values[t.toLowerCase()]},r.prototype.isEmpty=function(){return 0===this.size()},r.prototype.names=function(){var t=this;return Object.keys(this.values).map(function(e){return t.keys[e]})},r.prototype.remove=function(t){return delete this.keys[t.toLowerCase()],delete this.values[t.toLowerCase()],this},r.prototype.set=function(t,e){return this.keys[t.toLowerCase()]=t,this.values[t.toLowerCase()]=[e],this},r.prototype.size=function(){return this.names().length},r.prototype.toString=function(){return JSON.stringify(this.values)},r}(e);this.senna.MultiMap=r}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.sennaNamed.metal.string,r=this.senna.parse,i=this.senna.MultiMap,o=r,a=function(){
-function r(){var e=arguments.length<=0||void 0===arguments[0]?"":arguments[0];t.classCallCheck(this,r),this.url=r.parse(this.maybeAddProtocolAndHostname_(e))}return r.prototype.addParametersFromMultiMap=function(t){var e=this;return t.names().forEach(function(n){t.getAll(n).forEach(function(t){e.addParameterValue(n,t)})}),this},r.prototype.addParameterValue=function(t,n){return this.ensureQueryInitialized_(),e.isDef(n)&&(n=String(n)),this.query.add(t,n),this},r.prototype.addParameterValues=function(t,e){var n=this;return e.forEach(function(e){return n.addParameterValue(t,e)}),this},r.prototype.ensureQueryInitialized_=function(){var n=this;if(!this.query){this.query=new i;var o=this.url.search;o&&o.substring(1).split("&").forEach(function(i){var o=i.split("="),a=t.slicedToArray(o,2),s=a[0],l=a[1];e.isDef(l)&&(l=r.urlDecode(l)),n.addParameterValue(s,l)})}},r.prototype.getHash=function(){return this.url.hash||""},r.prototype.getHost=function(){var t=this.getHostname();if(t){var e=this.getPort();e&&"80"!==e&&(t+=":"+e)}return t},r.prototype.getHostname=function(){var t=this.url.hostname;return t===r.HOSTNAME_PLACEHOLDER?"":t},r.prototype.getOrigin=function(){var t=this.getHost();return t?this.getProtocol()+"//"+t:""},r.prototype.getParameterValue=function(t){return this.ensureQueryInitialized_(),this.query.get(t)},r.prototype.getParameterValues=function(t){return this.ensureQueryInitialized_(),this.query.getAll(t)},r.prototype.getParameterNames=function(){return this.ensureQueryInitialized_(),this.query.names()},r.getParseFn=function(){return o},r.prototype.getPathname=function(){return this.url.pathname},r.prototype.getPort=function(){return this.url.port},r.prototype.getProtocol=function(){return this.url.protocol},r.prototype.getSearch=function(){var t=this,n="",r="";return this.getParameterNames().forEach(function(n){t.getParameterValues(n).forEach(function(t){r+=n,e.isDef(t)&&(r+="="+encodeURIComponent(t)),r+="&"})}),r=r.slice(0,-1),r&&(n+="?"+r),n},r.prototype.hasParameter=function(t){return this.ensureQueryInitialized_(),this.query.contains(t)},r.prototype.makeUnique=function(){return this.setParameterValue(r.RANDOM_PARAM,n.getRandomString()),this},r.prototype.maybeAddProtocolAndHostname_=function(t){var e=t;if(-1===t.indexOf("://")&&0!==t.indexOf("javascript:"))switch(e=r.DEFAULT_PROTOCOL,"/"===t[0]&&"/"===t[1]||(e+="//"),t.charAt(0)){case".":case"?":case"#":e+=r.HOSTNAME_PLACEHOLDER,e+="/",e+=t;break;case"":case"/":"/"!==t[1]&&(e+=r.HOSTNAME_PLACEHOLDER),e+=t;break;default:e+=t}return e},r.normalizeObject=function(t){var e=t.pathname?t.pathname.length:0;return e>1&&"/"===t.pathname[e-1]&&(t.pathname=t.pathname.substr(0,e-1)),t},r.parse=function(t){return r.normalizeObject(o(t))},r.prototype.removeParameter=function(t){return this.ensureQueryInitialized_(),this.query.remove(t),this},r.prototype.removeUnique=function(){return this.removeParameter(r.RANDOM_PARAM),this},r.prototype.setHash=function(t){return this.url.hash=t,this},r.prototype.setHostname=function(t){return this.url.hostname=t,this},r.prototype.setParameterValue=function(t,e){return this.removeParameter(t),this.addParameterValue(t,e),this},r.prototype.setParameterValues=function(t,e){var n=this;return this.removeParameter(t),e.forEach(function(e){return n.addParameterValue(t,e)}),this},r.prototype.setPathname=function(t){return this.url.pathname=t,this},r.prototype.setPort=function(t){return this.url.port=t,this},r.setParseFn=function(t){o=t},r.prototype.setProtocol=function(t){return this.url.protocol=t,":"!==this.url.protocol[this.url.protocol.length-1]&&(this.url.protocol+=":"),this},r.prototype.toString=function(){var t="",e=this.getHost();return e&&(t+=this.getProtocol()+"//"),t+=e+this.getPathname()+this.getSearch()+this.getHash()},r.joinPaths=function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),r=1;e>r;r++)n[r-1]=arguments[r];return"/"===t.charAt(t.length-1)&&(t=t.substring(0,t.length-1)),n=n.map(function(t){return"/"===t.charAt(0)?t.substring(1):t}),[t].concat(n).join("/").replace(/\/$/,"")},r.urlDecode=function(t){return decodeURIComponent(t.replace(/\+/g," "))},r}();a.DEFAULT_PROTOCOL="http:",a.HOSTNAME_PLACEHOLDER="hostname"+Date.now(),a.RANDOM_PARAM="zx",this.senna.Uri=a}.call(this),function(){var e=this.senna.globals,n=this.senna.Uri,r=function(){function r(){t.classCallCheck(this,r)}return r.copyNodeAttributes=function(t,e){Array.prototype.slice.call(t.attributes).forEach(function(t){return e.setAttribute(t.name,t.value)})},r.getCurrentBrowserPath=function(){return this.getCurrentBrowserPathWithoutHash()+e.window.location.hash},r.getCurrentBrowserPathWithoutHash=function(){return e.window.location.pathname+e.window.location.search},r.getUrlPath=function(t){var e=new n(t);return e.getPathname()+e.getSearch()+e.getHash()},r.getUrlPathWithoutHash=function(t){var e=new n(t);return e.getPathname()+e.getSearch()},r.isCurrentBrowserPath=function(t){return t?r.getUrlPathWithoutHash(t)===this.getCurrentBrowserPathWithoutHash():!1},r.isHtml5HistorySupported=function(){return!(!e.window.history||!e.window.history.pushState)},r.clearNodeAttributes=function(t){Array.prototype.slice.call(t.attributes).forEach(function(e){return t.removeAttribute(e.name)})},r}();this.senna.utils=r}.call(this),function(){var e=this.sennaNamed.metal.core,n=function(){function n(r,i){if(t.classCallCheck(this,n),!e.isDefAndNotNull(r))throw new Error("Route path not specified.");if(!e.isFunction(i))throw new Error("Route handler is not a function.");this.handler=i,this.path=r}return n.prototype.getHandler=function(){return this.handler},n.prototype.getPath=function(){return this.path},n.prototype.matchesPath=function(t){var n=this.path;return e.isString(n)?t===n:e.isFunction(n)?n(t):n instanceof RegExp?t.search(n)>-1:!1},n}();this.senna.Route=n}.call(this),function(){var e=this.sennaNamed.metal.Disposable,n=function(e){function n(){t.classCallCheck(this,n);var r=t.possibleConstructorReturn(this,e.call(this));return r.cache=null,r.cacheable=!1,r}return t.inherits(n,e),n.prototype.addCache=function(t){return this.cacheable&&(this.cache=t),this},n.prototype.clearCache=function(){return this.cache=null,this},n.prototype.disposeInternal=function(){this.clearCache()},n.prototype.getCache=function(){return this.cache},n.prototype.isCacheable=function(){return this.cacheable},n.prototype.setCacheable=function(t){t||this.clearCache(),this.cacheable=t},n}(e);this.senna.Cacheable=n}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.sennaNamed.dom.globalEval,r=this.senna.Cacheable,i=this.senna.Promise,o=function(r){function o(){t.classCallCheck(this,o);var n=t.possibleConstructorReturn(this,r.call(this));return n.id=n.makeId_(e.getUid()),n.title=null,n}return t.inherits(o,r),o.prototype.activate=function(){},o.prototype.beforeDeactivate=function(){},o.prototype.beforeUpdateHistoryPath=function(t){return t},o.prototype.beforeUpdateHistoryState=function(t){return t},o.prototype.deactivate=function(){},o.prototype.disposeInternal=function(){r.prototype.disposeInternal.call(this)},o.prototype.evaluateScripts=function(t){return Object.keys(t).forEach(function(e){t[e].activeChild&&n.runScriptsInElement(t[e].activeChild)}),i.resolve()},o.prototype.evaluateStyles=function(){return i.resolve()},o.prototype.flip=function(t){var e=this,n=[];return Object.keys(t).forEach(function(r){var i=t[r],o=i.show(e.id);n.push(o)}),i.all(n)},o.prototype.getId=function(){return this.id},o.prototype.getSurfaceContent=function(){},o.prototype.getTitle=function(){return this.title},o.prototype.load=function(){return i.resolve()},o.prototype.makeId_=function(t){return"screen_"+t},o.prototype.setId=function(t){this.id=t},o.prototype.setTitle=function(t){this.title=t},o.prototype.toString=function(){return this.id},o}(r);o.isImplementedBy=function(t){return t instanceof o},this.senna.Screen=o}.call(this),function(){var e=this.senna.globals,n=this.sennaNamed.metal.core,r=this.sennaNamed.metal.Disposable,i=this.senna.dom,o=this.senna.Promise,a=function(r){function a(e){t.classCallCheck(this,a);var n=t.possibleConstructorReturn(this,r.call(this));if(!e)throw new Error("Surface element id not specified. A surface element requires a valid id.");return n.activeChild=null,n.defaultChild=null,n.element=null,n.id=e,n.transitionFn=null,n.defaultChild=n.getChild(a.DEFAULT),n.maybeWrapContentAsDefault_(),n.activeChild=n.defaultChild,n}return t.inherits(a,r),a.prototype.addContent=function(t,e){var r=this.defaultChild;n.isDefAndNotNull(e)&&(r=this.getChild(t),r?i.removeChildren(r):(r=this.createChild(t),this.transition(r,null)),i.append(r,e));var o=this.getElement();return o&&r&&i.append(o,r),r},a.prototype.createChild=function(t){var n=e.document.createElement("div");return n.setAttribute("id",this.makeId_(t)),n},a.prototype.getChild=function(t){return e.document.getElementById(this.makeId_(t))},a.prototype.getElement=function(){return this.element?this.element:(this.element=e.document.getElementById(this.id),this.element)},a.prototype.getId=function(){return this.id},a.prototype.getTransitionFn=function(){return this.transitionFn},a.prototype.makeId_=function(t){return this.id+"-"+t},a.prototype.maybeWrapContentAsDefault_=function(){var t=this.getElement();if(t&&!this.defaultChild){for(var n=e.document.createDocumentFragment();t.firstChild;)n.appendChild(t.firstChild);this.defaultChild=this.addContent(a.DEFAULT,n),this.transition(null,this.defaultChild)}},a.prototype.setId=function(t){this.id=t},a.prototype.setTransitionFn=function(t){this.transitionFn=t},a.prototype.show=function(t){var e=this.activeChild,n=this.getChild(t);return n||(n=this.defaultChild),this.activeChild=n,this.transition(e,n).thenAlways(function(){e&&e!==n&&i.exitDocument(e)})},a.prototype.remove=function(t){var e=this.getChild(t);e&&i.exitDocument(e)},a.prototype.toString=function(){return this.id},a.prototype.transition=function(t,e){var n=this.transitionFn||a.defaultTransition;return o.resolve(n.call(this,t,e))},a}(r);a.DEFAULT="default",a.defaultTransition=function(t,e){t&&(t.style.display="none",t.classList.remove("flipped")),e&&(e.style.display="block",e.classList.add("flipped"))},this.senna.Surface=a}.call(this),function(){var e=this.sennaNamed.metal.array,n=this.sennaNamed.metal.async,r=this.sennaNamed.metal.core,i=this.senna.dom,o=this.senna.Promise,a=this.sennaNamed.events.EventEmitter,s=this.sennaNamed.events.EventHandler,l=this.senna.utils,c=this.senna.globals,u=this.senna.Route,h=this.senna.Screen,p=this.senna.Surface,d=this.senna.Uri,f=function(a){function f(){t.classCallCheck(this,f);var e=t.possibleConstructorReturn(this,a.call(this));return e.activeScreen=null,e.activePath=null,e.allowPreventNavigate=!0,e.basePath="",e.captureScrollPositionFromScrollEvent=!0,e.defaultTitle=c.document.title,e.formSelector='form[enctype="multipart/form-data"]:not([data-senna-off])',e.linkSelector="a:not([data-senna-off])",e.loadingCssClass="senna-loading",e.nativeScrollRestorationSupported="scrollRestoration"in c.window.history,e.pendingNavigate=null,e.popstateScrollLeft=0,e.popstateScrollTop=0,e.redirectPath=null,e.routes=[],e.screens={},e.skipLoadPopstate=!1,e.surfaces={},e.updateScrollPosition=!0,e.appEventHandlers_=new s,e.appEventHandlers_.add(i.on(c.window,"scroll",e.onScroll_.bind(e)),i.on(c.window,"load",e.onLoad_.bind(e)),i.on(c.window,"popstate",e.onPopstate_.bind(e))),e.on("startNavigate",e.onStartNavigate_),e.on("beforeNavigate",e.onBeforeNavigate_),e.on("beforeNavigate",e.onBeforeNavigateDefault_,!0),e.setLinkSelector(e.linkSelector),e.setFormSelector(e.formSelector),e}return t.inherits(f,a),f.prototype.addRoutes=function(t){var e=this;return Array.isArray(t)||(t=[t]),t.forEach(function(t){t instanceof u||(t=new u(t.path,t.handler)),e.routes.push(t)}),this},f.prototype.addSurfaces=function(t){var e=this;return Array.isArray(t)||(t=[t]),t.forEach(function(t){r.isString(t)&&(t=new p(t)),e.surfaces[t.getId()]=t}),this},f.prototype.canNavigate=function(t){var e=l.getUrlPath(t),n=new d(t);return this.isLinkSameOrigin_(n.getHostname())&&this.isSameBasePath_(e)?!!this.findRoute(e):!1},f.prototype.clearScreensCache=function(){var t=this;Object.keys(this.screens).forEach(function(e){e===t.activePath?t.activeScreen.clearCache():t.removeScreen(e)})},f.prototype.createScreenInstance=function(t,e){if(!this.pendingNavigate&&t===this.activePath)return this.activeScreen;var n=this.screens[t];if(!n){var r=e.getHandler();n=r===h||h.isImplementedBy(r.prototype)?new r:r(e)||new h}return n},f.prototype.disposeInternal=function(){this.activeScreen&&this.removeScreen(this.activePath),this.clearScreensCache(),this.formEventHandler_.removeListener(),this.linkEventHandler_.removeListener(),this.appEventHandlers_.removeAllListeners(),a.prototype.disposeInternal.call(this)},f.prototype.dispatch=function(){return this.navigate(l.getCurrentBrowserPath(),!0)},f.prototype.doNavigate_=function(t,e){var n=this;if(this.activeScreen&&this.activeScreen.beforeDeactivate())return this.pendingNavigate=o.reject(new o.CancellationError("Cancelled by active screen")),this.pendingNavigate;var r=this.findRoute(t);if(!r)return this.pendingNavigate=o.reject(new o.CancellationError("No route for "+t)),this.pendingNavigate;this.stopPendingNavigate_();var i=this.createScreenInstance(t,r);return i.load(t).then(function(){n.activeScreen&&n.activeScreen.deactivate(),n.prepareNavigateHistory_(t,i,e),n.prepareNavigateSurfaces_(i,n.surfaces)}).then(function(){return i.evaluateStyles(n.surfaces)}).then(function(){return i.flip(n.surfaces)}).then(function(){return i.evaluateScripts(n.surfaces)}).then(function(){return n.syncScrollPositionSyncThenAsync_()}).then(function(){return n.finalizeNavigate_(t,i)})["catch"](function(e){throw n.handleNavigateError_(t,i,e),e})},f.prototype.finalizeNavigate_=function(t,e){e.activate(),this.activeScreen&&!this.activeScreen.isCacheable()&&this.activeScreen!==e&&this.removeScreen(this.activePath),this.activePath=t,this.activeScreen=e,this.screens[t]=e,this.pendingNavigate=null,c.capturedFormElement=null},f.prototype.findRoute=function(t){if(t.lastIndexOf("#")>-1&&l.isCurrentBrowserPath(t))return null;t=l.getUrlPathWithoutHash(t),t=l.getUrlPathWithoutHash(t.substr(this.basePath.length));for(var e=0;e0},f.prototype.isLinkSameOrigin_=function(t){return t===c.window.location.hostname},f.prototype.isSameBasePath_=function(t){return 0===t.indexOf(this.basePath)},f.prototype.lockHistoryScrollPosition_=function(){var t=c.window.history.state;if(t){var e=!1,r=function i(){c.document.removeEventListener("scroll",i,!1),e||(c.window.scrollTo(t.scrollLeft,t.scrollTop),e=!0)};n.nextTick(r),c.document.addEventListener("scroll",r,!1)}},f.prototype.maybeDisableNativeScrollRestoration=function(){this.nativeScrollRestorationSupported&&(this.nativeScrollRestoration_=c.window.history.scrollRestoration,c.window.history.scrollRestoration="manual")},f.prototype.maybeNavigate_=function(t,e){if(this.canNavigate(t)&&(!this.allowPreventNavigate||!e.defaultPrevented)){c.capturedFormElement=e.capturedFormElement;var n=!1;try{this.navigate(l.getUrlPath(t))}catch(r){n=!0}n||e.preventDefault()}},f.prototype.maybeRepositionScrollToHashedAnchor=function(){var t=c.window.location.hash;if(t){var e=c.document.getElementById(t.substring(1));e&&c.window.scrollTo(e.offsetLeft,e.offsetTop)}},f.prototype.maybeRestoreNativeScrollRestoration=function(){this.nativeScrollRestorationSupported&&this.nativeScrollRestoration_&&(c.window.history.scrollRestoration=this.nativeScrollRestoration_)},f.prototype.navigate=function(t,e){if(!l.isHtml5HistorySupported())throw new Error("HTML5 History is not supported. Senna will not intercept navigation.");return t===this.activePath&&(e=!0),this.emit("beforeNavigate",{path:t,replaceHistory:!!e}),this.pendingNavigate},f.prototype.onBeforeNavigate_=function(t){c.capturedFormElement&&(t.form=c.capturedFormElement)},f.prototype.onBeforeNavigateDefault_=function(t){this.pendingNavigate&&this.pendingNavigate.path===t.path||this.emit("startNavigate",{form:t.form,path:t.path,replaceHistory:t.replaceHistory})},f.prototype.onDocClickDelegate_=function(t){t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.button||this.maybeNavigate_(t.delegateTarget.href,t)},f.prototype.onDocSubmitDelegate_=function(t){var e=t.delegateTarget;"get"!==e.method&&(t.capturedFormElement=e,this.maybeNavigate_(e.action,t))},f.prototype.onLoad_=function(){var t=this;this.skipLoadPopstate=!0,setTimeout(function(){t.skipLoadPopstate=!1},0),this.maybeRepositionScrollToHashedAnchor()},f.prototype.onPopstate_=function(t){if(!this.skipLoadPopstate){var e=t.state;return e?void(e.senna&&(this.popstateScrollTop=e.scrollTop,this.popstateScrollLeft=e.scrollLeft,this.nativeScrollRestorationSupported||this.lockHistoryScrollPosition_(),this.navigate(e.path,!0))):void(c.window.location.hash?(this.redirectPath&&!l.isCurrentBrowserPath(this.redirectPath)&&this.reloadPage(),this.maybeRepositionScrollToHashedAnchor()):this.reloadPage())}},f.prototype.onScroll_=function(){this.captureScrollPositionFromScrollEvent&&this.saveHistoryCurrentPageScrollPosition_()},f.prototype.onStartNavigate_=function(t){var e=this;this.maybeDisableNativeScrollRestoration(),this.captureScrollPositionFromScrollEvent=!1,i.addClasses(c.document.documentElement,this.loadingCssClass);var n={form:t.form,path:t.path};this.pendingNavigate=this.doNavigate_(t.path,t.replaceHistory)["catch"](function(t){throw n.error=t,t}).thenAlways(function(){e.pendingNavigate||(i.removeClasses(c.document.documentElement,e.loadingCssClass),e.maybeRestoreNativeScrollRestoration(),e.captureScrollPositionFromScrollEvent=!0),e.emit("endNavigate",n)}),this.pendingNavigate.path=t.path},f.prototype.prefetch=function(t){var e=this,n=this.findRoute(t);if(!n)return o.reject(new o.CancellationError("No route for "+t));var r=this.createScreenInstance(t,n);return r.load(t).then(function(){return e.screens[t]=r})["catch"](function(n){throw e.handleNavigateError_(t,r,n),n})},f.prototype.prepareNavigateHistory_=function(t,e,n){var i=e.getTitle();r.isString(i)||(i=this.getDefaultTitle());var o=e.beforeUpdateHistoryPath(t),a={form:r.isDefAndNotNull(c.capturedFormElement),redirectPath:o,path:t,senna:!0,scrollTop:0,scrollLeft:0};n&&(a.scrollTop=this.popstateScrollTop,a.scrollLeft=this.popstateScrollLeft),this.updateHistory_(i,o,e.beforeUpdateHistoryState(a),n),this.redirectPath=o},f.prototype.prepareNavigateSurfaces_=function(t,e){Object.keys(e).forEach(function(n){var r=t.getSurfaceContent(n);e[n].addContent(t.getId(),r)})},f.prototype.reloadPage=function(){c.window.location.reload()},f.prototype.removeRoute=function(t){return e.remove(this.routes,t)},f.prototype.removeScreen=function(t){var e=this,n=this.screens[t];n&&(Object.keys(this.surfaces).forEach(function(t){return e.surfaces[t].remove(n.getId())}),n.dispose(),delete this.screens[t])},f.prototype.saveHistoryCurrentPageScrollPosition_=function(){var t=c.window.history.state;t&&t.senna&&(t.scrollTop=c.window.pageYOffset,t.scrollLeft=c.window.pageXOffset,c.window.history.replaceState(t,null,null))},f.prototype.setAllowPreventNavigate=function(t){this.allowPreventNavigate=t},f.prototype.setBasePath=function(t){this.basePath=t},f.prototype.setDefaultTitle=function(t){this.defaultTitle=t},f.prototype.setFormSelector=function(t){this.formSelector=t,this.formEventHandler_&&this.formEventHandler_.removeListener(),this.formEventHandler_=i.delegate(document,"submit",this.formSelector,this.onDocSubmitDelegate_.bind(this))},f.prototype.setLinkSelector=function(t){this.linkSelector=t,this.linkEventHandler_&&this.linkEventHandler_.removeListener(),this.linkEventHandler_=i.delegate(document,"click",this.linkSelector,this.onDocClickDelegate_.bind(this))},f.prototype.setLoadingCssClass=function(t){this.loadingCssClass=t},f.prototype.setUpdateScrollPosition=function(t){this.updateScrollPosition=t},f.prototype.stopPendingNavigate_=function(){this.pendingNavigate&&(this.pendingNavigate.cancel("Cancel pending navigation"),this.pendingNavigate=null)},f.prototype.syncScrollPositionSyncThenAsync_=function(){var t=this,e=c.window.history.state;if(e){var r=e.scrollTop,i=e.scrollLeft,a=function(){t.updateScrollPosition&&c.window.scrollTo(i,r)};return new o(function(t){return a()&n.nextTick(function(){return a()&t()})})}},f.prototype.updateHistory_=function(t,e,n,r){r?c.window.history.replaceState(n,t,e):c.window.history.pushState(n,t,e),c.document.title=t},f}(a);this.senna.App=f}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.senna.Uri,r=this.sennaNamed.Promise.CancellablePromise,i=function(){function i(){t.classCallCheck(this,i)}return i.parseResponseHeaders=function(t){var e=[];if(!t)return e;for(var n=t.split("\r\n"),r=0;r0){var o=n[r].substring(0,i),a=n[r].substring(i+2);e.push({name:o,value:a})}}return e},i.request=function o(t,i,a,s,l,c,u,h){var o=new XMLHttpRequest,p=new r(function(t,e){o.onload=function(){return o.aborted?void o.onerror():void t(o)},o.onerror=function(){var t=new Error("Request error");t.request=o,e(t)}}).thenCatch(function(t){throw o.abort(),t}).thenAlways(function(){clearTimeout(d)});if(l&&(t=new n(t).addParametersFromMultiMap(l).toString()),o.open(i,t,!u),h&&(o.withCredentials=!0),s&&s.names().forEach(function(t){o.setRequestHeader(t,s.getAll(t).join(", "))}),o.send(e.isDef(a)?a:null),e.isDefAndNotNull(c))var d=setTimeout(function(){p.cancel("Request timeout")},c);return p},i}();this.senna.Ajax=i}.call(this),function(){var e=function n(){t.classCallCheck(this,n)};e.INVALID_STATUS="Invalid status code",e.REQUEST_ERROR="Request error",e.REQUEST_TIMEOUT="Request timeout",this.senna.errors=e}.call(this),function(){var e=function(){function e(){t.classCallCheck(this,e)}return e.getNativeUserAgent=function(){var t=e.globals.window.navigator;if(t){var n=t.userAgent;if(n)return n}return""},e.matchUserAgent=function(t){return-1!==e.userAgent.indexOf(t)},e.testUserAgent=function(t){e.userAgent=t,e.isOpera=e.matchUserAgent("Opera")||e.matchUserAgent("OPR"),e.isIe=e.matchUserAgent("Trident")||e.matchUserAgent("MSIE"),e.isEdge=e.matchUserAgent("Edge"),e.isIeOrEdge=e.isIe||e.isEdge,e.isChrome=(e.matchUserAgent("Chrome")||e.matchUserAgent("CriOS"))&&!e.isOpera&&!e.isEdge,e.isSafari=e.matchUserAgent("Safari")&&!(e.isChrome||e.isOpera||e.isEdge),e.isFirefox=e.matchUserAgent("Firefox")},e}();e.globals={window:window},e.testUserAgent(e.getNativeUserAgent()),this.senna.UA=e}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.senna.Ajax,r=this.senna.MultiMap,i=this.senna.Promise,o=this.senna.errors,a=this.senna.utils,s=this.senna.globals,l=this.senna.Screen,c=this.senna.Uri,u=this.senna.UA,h=function(l){function h(){t.classCallCheck(this,h);var e=t.possibleConstructorReturn(this,l.call(this));return e.cacheable=!0,e.httpHeaders={"X-PJAX":"true","X-Requested-With":"XMLHttpRequest"},e.httpMethod=h.GET,e.request=null,e.timeout=3e4,e}return t.inherits(h,l),h.prototype.assertValidResponseStatusCode=function(t){if(!this.isValidResponseStatusCode(t)){var e=new Error(o.INVALID_STATUS);throw e.invalidStatus=!0,e}},h.prototype.beforeUpdateHistoryPath=function(t){var e=this.getRequestPath();return e&&e!==t?e:t},h.prototype.beforeUpdateHistoryState=function(t){return t.senna&&t.form&&t.redirectPath===t.path?null:t},h.prototype.formatLoadPath=function(t){return u.isIeOrEdge&&this.httpMethod===h.GET?new c(t).makeUnique().toString():t},h.prototype.getHttpHeaders=function(){return this.httpHeaders},h.prototype.getHttpMethod=function(){return this.httpMethod},h.prototype.getRequestPath=function(){var t=this.getRequest();if(t){var e=t.requestPath,n=this.maybeExtractResponseUrlFromRequest(t);return n&&(e=n),u.isIeOrEdge&&this.httpMethod===h.GET&&(e=new c(e).removeUnique().toString()),a.getUrlPath(e)}return null},h.prototype.getRequest=function(){return this.request},h.prototype.getTimeout=function(){return this.timeout},h.prototype.isValidResponseStatusCode=function(t){return t>=200&&399>=t},h.prototype.load=function(t){var a=this,l=this.getCache();if(e.isDefAndNotNull(l))return i.resolve(l);var c=null,p=this.httpMethod,d=new r;Object.keys(this.httpHeaders).forEach(function(t){return d.add(t,a.httpHeaders[t])}),s.capturedFormElement&&(c=new FormData(s.capturedFormElement),p=h.POST,u.isIeOrEdge&&d.add("If-None-Match",'"0"'));var f=this.formatLoadPath(t);return n.request(f,p,c,d,null,this.timeout).then(function(t){return a.setRequest(t),a.assertValidResponseStatusCode(t.status),p===h.GET&&a.isCacheable()&&a.addCache(t.responseText),t.requestPath=f,t.responseText})["catch"](function(t){switch(t.message){case o.REQUEST_TIMEOUT:t.timeout=!0;break;case o.REQUEST_ERROR:t.requestError=!0}throw t})},h.prototype.maybeExtractResponseUrlFromRequest=function(t){var e=t.responseURL;return e?e:t.getResponseHeader(h.X_REQUEST_URL_HEADER)},h.prototype.setHttpHeaders=function(t){this.httpHeaders=t},h.prototype.setHttpMethod=function(t){this.httpMethod=t.toLowerCase()},h.prototype.setRequest=function(t){this.request=t},h.prototype.setTimeout=function(t){this.timeout=t},h}(l);h.GET="get",h.POST="post",h.X_REQUEST_URL_HEADER="X-Request-URL",this.senna.RequestScreen=h}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.sennaNamed.dom.dom,r=this.sennaNamed.dom.globalEval,i=this.sennaNamed.dom.globalEvalStyles,o=this.senna.Promise,a=this.senna.globals,s=this.senna.RequestScreen,l=this.senna.Surface,c=this.senna.UA,u=this.senna.Uri,h=this.senna.utils,p=function(s){function p(){t.classCallCheck(this,p);var e=t.possibleConstructorReturn(this,s.call(this));return e.titleSelector="title",e}return t.inherits(p,s),p.prototype.activate=function(){s.prototype.activate.call(this),this.releaseVirtualDocument(),this.pendingStyles=null},p.prototype.allocateVirtualDocumentForContent=function(t){this.virtualDocument||(this.virtualDocument=a.document.createElement("html")),this.copyNodeAttributesFromContent_(t,this.virtualDocument),this.virtualDocument.innerHTML=t},p.prototype.appendStyleIntoDocument_=function(t){var e=n.match(t,p.selectors.stylesTemporary);if(e&&(this.pendingStyles.push(t),c.isIe&&t.href&&(t.href=new u(t.href).makeUnique().toString())),t.id){var r=a.document.getElementById(t.id);if(r)return void r.parentNode.insertBefore(t,r.nextSibling)}a.document.head.appendChild(t)},p.prototype.assertSameBodyIdInVirtualDocument=function(){var t=this.virtualDocument.querySelector("body");a.document.body.id||(a.document.body.id="senna_surface_"+e.getUid()),t&&(t.id=a.document.body.id)},p.prototype.copyNodeAttributesFromContent_=function(t,e){t=t.replace(/[<]\s*html/gi,"/gi,"/senna>"),e.innerHTML=t;var n=e.querySelector("senna");n&&(h.clearNodeAttributes(e),h.copyNodeAttributes(n,e))},p.prototype.disposeInternal=function(){this.disposePendingStyles(),s.prototype.disposeInternal.call(this)},p.prototype.disposePendingStyles=function(){this.pendingStyles&&this.pendingStyles.forEach(function(t){return n.exitDocument(t)})},p.prototype.evaluateScripts=function(t){var e=this,n=this.evaluateTrackedResources_(r.runScriptsInElement,p.selectors.scripts,p.selectors.scriptsTemporary,p.selectors.scriptsPermanent);return n.then(function(){return s.prototype.evaluateScripts.call(e,t)})},p.prototype.evaluateStyles=function(t){var e=this;this.pendingStyles=[];var n=this.evaluateTrackedResources_(i.runStylesInElement,p.selectors.styles,p.selectors.stylesTemporary,p.selectors.stylesPermanent,this.appendStyleIntoDocument_.bind(this));return n.then(function(){return s.prototype.evaluateStyles.call(e,t)})},p.prototype.evaluateTrackedResources_=function(t,e,r,i,a){var s=this,l=this.virtualQuerySelectorAll_(e),c=this.querySelectorAll_(r),u=this.querySelectorAll_(i);u.forEach(function(t){var e=s.getResourceKey_(t);e&&(p.permanentResourcesInDoc[e]=!0)});var h=n.buildFragment();return l.forEach(function(t){var e=s.getResourceKey_(t);p.permanentResourcesInDoc[e]||h.appendChild(t),e&&n.match(t,i)&&(p.permanentResourcesInDoc[e]=!0)}),new o(function(e){t(h,function(){c.forEach(function(t){return n.exitDocument(t)}),e()},a)})},p.prototype.flip=function(t){var e=this;return s.prototype.flip.call(this,t).then(function(){h.clearNodeAttributes(document.documentElement),h.copyNodeAttributes(e.virtualDocument,document.documentElement)})},p.prototype.getResourceKey_=function(t){return t.id||t.href||t.src||""},p.prototype.getSurfaceContent=function(t){var e=this.virtualDocument.querySelector("#"+t);if(e){var n=e.querySelector("#"+t+"-"+l.DEFAULT);return n?n.innerHTML:e.innerHTML}},p.prototype.getTitleSelector=function(){return this.titleSelector},p.prototype.load=function(t){var e=this;return s.prototype.load.call(this,t).then(function(t){return e.allocateVirtualDocumentForContent(t),e.resolveTitleFromVirtualDocument(),e.assertSameBodyIdInVirtualDocument(),t})},p.prototype.virtualQuerySelectorAll_=function(t){return Array.prototype.slice.call(this.virtualDocument.querySelectorAll(t))},p.prototype.querySelectorAll_=function(t){return Array.prototype.slice.call(a.document.querySelectorAll(t))},p.prototype.releaseVirtualDocument=function(){this.virtualDocument=null},p.prototype.resolveTitleFromVirtualDocument=function(){var t=this.virtualDocument.querySelector(this.titleSelector);t&&this.setTitle(t.innerHTML.trim())},p.prototype.setTitleSelector=function(t){this.titleSelector=t},p}(s);p.selectors={scripts:"script[data-senna-track]",scriptsPermanent:'script[data-senna-track="permanent"]',scriptsTemporary:'script[data-senna-track="temporary"]',styles:"style[data-senna-track],link[data-senna-track]",stylesPermanent:'style[data-senna-track="permanent"],link[data-senna-track="permanent"]',stylesTemporary:'style[data-senna-track="temporary"],link[data-senna-track="temporary"]'},p.permanentResourcesInDoc={},this.senna.HtmlScreen=p}.call(this),function(){var t=this.senna.App,e=this.senna.HtmlScreen,n=this.senna.RequestScreen,r=this.senna.Route,i=this.senna.Screen;this.senna.senna=t,this.sennaNamed.senna=this.sennaNamed.senna||{},this.sennaNamed.senna.App=t,this.sennaNamed.senna.HtmlScreen=e,this.sennaNamed.senna.Route=r,this.sennaNamed.senna.RequestScreen=n,this.sennaNamed.senna.Screen=i}.call(this),function(){this.senna.dataAttributes={basePath:"data-senna-base-path",linkSelector:"data-senna-link-selector",loadingCssClass:"data-senna-loading-css-class",senna:"data-senna",dispatch:"data-senna-dispatch",surface:"data-senna-surface",updateScrollPosition:"data-senna-update-scroll-position"}}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.sennaNamed.metal.object,r=this.sennaNamed.metal.Disposable,i=this.senna.dataAttributes,o=this.senna.globals,a=this.senna.App,s=this.senna.HtmlScreen,l=this.senna.Route,c=function(r){function c(){t.classCallCheck(this,c);var e=t.possibleConstructorReturn(this,r.call(this));return e.app=null,e.baseElement=null,e}return t.inherits(c,r),c.prototype.handle=function(){if(!e.isElement(this.baseElement))throw new Error("Senna data attribute handler base element not set or invalid, try setting a valid element that contains a `data-senna` attribute.");if(this.baseElement.hasAttribute(i.senna)){if(this.app)throw new Error("Senna app was already initialized.");this.app=new a,this.maybeAddRoutes_(),this.maybeAddSurfaces_(),this.maybeSetBasePath_(),this.maybeSetLinkSelector_(),
-this.maybeSetLoadingCssClass_(),this.maybeSetUpdateScrollPosition_(),this.maybeDispatch_()}},c.prototype.disposeInternal=function(){this.app&&this.app.dispose()},c.prototype.getApp=function(){return this.app},c.prototype.getBaseElement=function(){return this.baseElement},c.prototype.maybeAddRoutes_=function(){var t=this,e='link[rel="senna-route"]';this.querySelectorAllAsArray_(e).forEach(function(e){return t.maybeParseLinkRoute_(e)}),this.app.hasRoutes()||this.app.addRoutes(new l(/.*/,s))},c.prototype.maybeAddSurfaces_=function(){var t=this,e="["+i.surface+"]";this.querySelectorAllAsArray_(e).forEach(function(e){t.updateElementIdIfSpecialSurface_(e),t.app.addSurfaces(e.id)})},c.prototype.maybeDispatch_=function(){this.baseElement.hasAttribute(i.dispatch)&&this.app.dispatch()},c.prototype.maybeParseLinkRoute_=function(t){var e=new l(this.maybeParseLinkRoutePath_(t),this.maybeParseLinkRouteHandler_(t));this.app.addRoutes(e)},c.prototype.maybeParseLinkRouteHandler_=function(t){var r=t.getAttribute("type");return e.isDefAndNotNull(r)&&(r=n.getObjectByName(r)),r},c.prototype.maybeParseLinkRoutePath_=function(t){var n=t.getAttribute("href");return e.isDefAndNotNull(n)&&0===n.indexOf("regex:")&&(n=new RegExp(n.substring(6))),n},c.prototype.maybeSetBasePath_=function(){var t=this.baseElement.getAttribute(i.basePath);e.isDefAndNotNull(t)&&this.app.setBasePath(t)},c.prototype.maybeSetLinkSelector_=function(){var t=this.baseElement.getAttribute(i.linkSelector);e.isDefAndNotNull(t)&&this.app.setLinkSelector(t)},c.prototype.maybeSetLoadingCssClass_=function(){var t=this.baseElement.getAttribute(i.loadingCssClass);e.isDefAndNotNull(t)&&this.app.setLoadingCssClass(t)},c.prototype.maybeSetUpdateScrollPosition_=function(){var t=this.baseElement.getAttribute(i.updateScrollPosition);e.isDefAndNotNull(t)&&("false"===t?this.app.setUpdateScrollPosition(!1):this.app.setUpdateScrollPosition(!0))},c.prototype.querySelectorAllAsArray_=function(t){return Array.prototype.slice.call(o.document.querySelectorAll(t))},c.prototype.updateElementIdIfSpecialSurface_=function(t){t.id||t!==o.document.body||(t.id="senna_surface_"+e.getUid())},c.prototype.setBaseElement=function(t){this.baseElement=t},c}(r);this.senna.AppDataAttributeHandler=c}.call(this),function(){var t=this.senna.globals,e=this.senna.AppDataAttributeHandler,n=new e;t.document.addEventListener("DOMContentLoaded",function(){n.setBaseElement(t.document.body),n.handle()}),this.senna.dataAttributeHandler=n}.call(this)}).call(this);
\ No newline at end of file
+(function(){this.senna=this.senna||{},this.sennaNamed=this.sennaNamed||{};var t={};t["typeof"]="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},t.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},t.inherits=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)},t.possibleConstructorReturn=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},t.slicedToArray=function(){function t(t,e){var n=[],r=!0,i=!1,o=void 0;try{for(var a,s=t[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!e||n.length!==e);r=!0);}catch(l){i=!0,o=l}finally{try{!r&&s["return"]&&s["return"]()}finally{if(i)throw o}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),function(){var e=function(){function e(){t.classCallCheck(this,e)}return e.abstractMethod=function(){throw Error("Unimplemented abstract method")},e.collectSuperClassesProperty=function(t,e){for(var n=[t[e]];t.__proto__&&!t.__proto__.isPrototypeOf(Function);)t=t.__proto__,n.push(t[e]);return n},e.getFunctionName=function(t){if(!t.name){var e=t.toString();t.name=e.substring(9,e.indexOf("("))}return t.name},e.getUid=function(t,n){if(t){var r=t[e.UID_PROPERTY];return n&&!t.hasOwnProperty(e.UID_PROPERTY)&&(r=null),r||(t[e.UID_PROPERTY]=e.uniqueIdCounter_++)}return e.uniqueIdCounter_++},e.identityFunction=function(t){return t},e.isBoolean=function(t){return"boolean"==typeof t},e.isDef=function(t){return void 0!==t},e.isDefAndNotNull=function(t){return e.isDef(t)&&!e.isNull(t)},e.isDocument=function(e){return e&&"object"===("undefined"==typeof e?"undefined":t["typeof"](e))&&9===e.nodeType},e.isElement=function(e){return e&&"object"===("undefined"==typeof e?"undefined":t["typeof"](e))&&1===e.nodeType},e.isFunction=function(t){return"function"==typeof t},e.isNull=function(t){return null===t},e.isNumber=function(t){return"number"==typeof t},e.isWindow=function(t){return null!==t&&t===t.window},e.isObject=function(e){var n="undefined"==typeof e?"undefined":t["typeof"](e);return"object"===n&&null!==e||"function"===n},e.isPromise=function(e){return e&&"object"===("undefined"==typeof e?"undefined":t["typeof"](e))&&"function"==typeof e.then},e.isString=function(t){return"string"==typeof t},e.mergeSuperClassesProperty=function(t,n,r){var i=n+"_MERGED";if(t.hasOwnProperty(i))return!1;var o=e.collectSuperClassesProperty(t,n);return r&&(o=r(o)),t[i]=o,!0},e.nullFunction=function(){},e}();e.UID_PROPERTY="core_"+(1e9*Math.random()>>>0),e.uniqueIdCounter_=1,this.senna.core=e}.call(this),function(){var e=this.senna.core,n=function(){function n(){t.classCallCheck(this,n)}return n.equal=function(t,e){if(t.length!==e.length)return!1;for(var n=0;n=0)&&n.removeAt(t,i),r},n.removeAt=function(t,e){return 1===Array.prototype.splice.call(t,e,1).length},n.slice=function(t,n,r){for(var i=[],o=e.isDef(r)?r:t.length,a=n;o>a;a++)i.push(t[a]);return i},n}();this.senna.array=n}.call(this),function(){var t={};t.throwException=function(e){t.nextTick(function(){throw e})},t.run=function(e,n){t.run.workQueueScheduled_||(t.nextTick(t.run.processWorkQueue),t.run.workQueueScheduled_=!0),t.run.workQueue_.push(new t.run.WorkItem_(e,n))},t.run.workQueueScheduled_=!1,t.run.workQueue_=[],t.run.processWorkQueue=function(){for(;t.run.workQueue_.length;){var e=t.run.workQueue_;t.run.workQueue_=[];for(var n=0;nn;n++)e=31*e+t.charCodeAt(n),e%=4294967296;return e},e.replaceInterval=function(t,e,n,r){return t.substring(0,e)+r+t.substring(n)},e}();this.senna.string=e}.call(this),function(){var t=this.senna.core,e=this.senna.array,n=this.senna.async,r=this.senna.Disposable,i=this.senna.object,o=this.senna.string;this.senna.metal=t,this.sennaNamed.metal=this.sennaNamed.metal||{},this.sennaNamed.metal.core=t,this.sennaNamed.metal.array=e,this.sennaNamed.metal.async=n,this.sennaNamed.metal.Disposable=r,this.sennaNamed.metal.object=i,this.sennaNamed.metal.string=o}.call(this),function(){var e="__metal_data__";this.senna.metalData=function(){function n(){t.classCallCheck(this,n)}return n.get=function(t){return t[e]||(t[e]={delegating:{},listeners:{}}),t[e]},n}()}.call(this),function(){var e=this.sennaNamed.metal.Disposable,n=function(e){function n(r,i,o){t.classCallCheck(this,n);var a=t.possibleConstructorReturn(this,e.call(this));return a.emitter_=r,a.event_=i,a.listener_=o,a}return t.inherits(n,e),n.prototype.disposeInternal=function(){this.removeListener(),this.emitter_=null,this.listener_=null},n.prototype.removeListener=function(){this.emitter_.isDisposed()||this.emitter_.removeListener(this.event_,this.listener_)},n}(e);this.senna.EventHandle=n}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.sennaNamed.metal.array,r=this.sennaNamed.metal.Disposable,i=this.senna.EventHandle,o=function(r){function o(){t.classCallCheck(this,o);var e=t.possibleConstructorReturn(this,r.call(this));return e.events_=[],e.maxListeners_=10,e.shouldUseFacade_=!1,e}return t.inherits(o,r),o.prototype.addListener=function(t,e,n){this.validateListener_(e),t=this.normalizeEvents_(t);for(var r=0;rthis.maxListeners_&&!i.warned&&(i.warned=!0)},o.prototype.disposeInternal=function(){this.events_=[]},o.prototype.emit=function(t){var e,r=n.slice(arguments,1),i=(this.events_[t]||[]).concat();this.getShouldUseFacade()&&(e={preventDefault:function(){e.preventedDefault=!0},target:this,type:t},r.push(e));for(var o=[],a=0;a0},o.prototype.getShouldUseFacade=function(){return this.shouldUseFacade_},o.prototype.listeners=function(t){return(this.events_[t]||[]).map(function(t){return t.fn})},o.prototype.many=function(t,e,n){t=this.normalizeEvents_(t);for(var r=0;r=e||i.addSingleListener_(t,r,!1,n)},o.prototype.matchesListener_=function(t,e){return t.fn===e||t.origin&&t.origin===e},o.prototype.normalizeEvents_=function(t){return e.isString(t)?[t]:t},o.prototype.off=function(t,e){this.validateListener_(e),t=this.normalizeEvents_(t);for(var n=0;n=0;n--)this.matchesListener_(t[n],e)&&t.splice(n,1)},o.prototype.removeListener=function(){return this.off.apply(this,arguments)},o.prototype.setMaxListeners=function(t){return this.maxListeners_=t,this},o.prototype.setShouldUseFacade=function(t){return this.shouldUseFacade_=t,this},o.prototype.validateListener_=function(t){if(!e.isFunction(t))throw new TypeError("Listener must be a function")},o}(r);this.senna.EventEmitter=o}.call(this),function(){var e=this.sennaNamed.metal.array,n=this.sennaNamed.metal.Disposable,r=function(n){function r(e,i,o,a){t.classCallCheck(this,r);var s=t.possibleConstructorReturn(this,n.call(this));return s.blacklist_=o||{},s.originEmitter_=e,s.pendingEvents_=[],s.proxiedEvents_={},s.targetEmitter_=i,s.whitelist_=a,s.startProxy_(),s}return t.inherits(r,n),r.prototype.addListener_=function(t,e){return this.originEmitter_.on(t,e)},r.prototype.addListenerForEvent_=function(t){return this.addListener_(t,this.emitOnTarget_.bind(this,t))},r.prototype.disposeInternal=function(){this.removeListeners_(),this.proxiedEvents_=null,this.originEmitter_=null,this.targetEmitter_=null},r.prototype.emitOnTarget_=function(t){var n=[t].concat(e.slice(arguments,1));this.targetEmitter_.emit.apply(this.targetEmitter_,n)},r.prototype.proxyEvent=function(t){this.shouldProxyEvent_(t)&&this.tryToAddListener_(t)},r.prototype.removeListeners_=function(){for(var t=Object.keys(this.proxiedEvents_),e=0;e"+t,e.removeChild(e.firstChild);for(var n=document.createDocumentFragment();e.firstChild;)n.appendChild(e.firstChild);return n},l.contains=function(t,n){return e.isDocument(t)?t.documentElement.contains(n):t.contains(n)},l.delegate=function(t,n,r,o,a){var s=l.customEvents[n];return s&&s.delegate&&(n=s.originalEvent,o=s.handler.bind(s,o)),a&&(o=o.bind(),o.defaultListener_=!0),l.attachDelegateEvent_(t,n),e.isString(r)?l.addSelectorListener_(t,n,r,o):l.addElementListener_(r,n,o),new i(e.isString(r)?t:r,n,o,e.isString(r)?r:null)},l.enterDocument=function(t){t&&l.append(document.body,t)},l.exitDocument=function(t){t&&t.parentNode&&t.parentNode.removeChild(t)},l.handleDelegateEvent_=function(t){l.normalizeDelegateEvent_(t);for(var n=e.isDef(t[a])?t[a]:t.target,r=!0,i=t.currentTarget,o=t.currentTarget.parentNode,s=[];n&&n!==o&&!t.stopped;)t.delegateTarget=n,r&=l.triggerMatchedListeners_(i,n,t,s),n=n.parentNode;for(var c=0;c=0},l.isEmpty=function(t){return 0===t.childNodes.length},l.match=function(t,e){if(!t||1!==t.nodeType)return!1;var n=Element.prototype,r=n.matches||n.webkitMatchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector;return r?r.call(t,e):l.matchFallback_(t,e)},l.matchFallback_=function(t,e){for(var n=document.querySelectorAll(e,t.parentNode),r=0;r0?this.unhandledRejectionId_=0:0===a.UNHANDLED_REJECTION_DELAY&&(this.hadUnhandledRejection_=!1);try{var n=this;t.call(e,function(t){n.resolve_(a.State_.FULFILLED,t)},function(t){n.resolve_(a.State_.REJECTED,t)})}catch(r){this.resolve_(a.State_.REJECTED,r)}};o.UNHANDLED_REJECTION_DELAY=0,o.State_={PENDING:0,BLOCKED:1,FULFILLED:2,REJECTED:3},o.CallbackEntry_=null,o.resolve=function(t){return new o(function(e){e(t)})},o.reject=function(t){return new o(function(e,n){n(t)})},o.race=function(t){return new o(function(e,n){t.length||e(void 0);for(var r,i=0;r=t[i];i++)r.then(e,n)})},o.all=function(t){return new o(function(e,n){var r=t.length,o=[];if(!r)return void e(o);for(var a,s=function(t,n){r--,o[t]=n,0===r&&e(o)},l=function(t){n(t)},c=0;a=t[c];c++)a.then(i(s,c),l)})},o.firstFulfilled=function(t){return new o(function(e,n){var r=t.length,o=[];if(!r)return void e(void 0);for(var a,s=function(t){e(t)},l=function(t,e){r--,o[t]=e,0===r&&n(o)},c=0;a=t[c];c++)a.then(s,i(l,c))})},o.prototype.then=function(t,n,r){return this.addChildPromise_(e.isFunction(t)?t:null,e.isFunction(n)?n:null,r)},r.addImplementation(o),o.prototype.thenAlways=function(t,e){var n=function(){try{t.call(e)}catch(n){o.handleRejection_.call(null,n)}};return this.addCallbackEntry_({child:null,onRejected:n,onFulfilled:n}),this},o.prototype.thenCatch=function(t,e){return this.addChildPromise_(null,t,e)},o.prototype["catch"]=o.prototype.thenCatch,o.prototype.cancel=function(t){this.state_===o.State_.PENDING&&n.run(function(){var e=new o.CancellationError(t);e.IS_CANCELLATION_ERROR=!0,this.cancelInternal_(e)},this)},o.prototype.cancelInternal_=function(t){this.state_===o.State_.PENDING&&(this.parent_?this.parent_.cancelChild_(this,t):this.resolve_(o.State_.REJECTED,t))},o.prototype.cancelChild_=function(t,e){if(this.callbackEntries_){for(var n,r=0,i=-1,a=0;n=this.callbackEntries_[a];a++){var s=n.child;if(s&&(r++,s===t&&(i=a),i>=0&&r>1))break}if(i>=0)if(this.state_===o.State_.PENDING&&1===r)this.cancelInternal_(e);else{var l=this.callbackEntries_.splice(i,1)[0];this.executeCallback_(l,o.State_.REJECTED,e)}}},o.prototype.addCallbackEntry_=function(t){this.callbackEntries_&&this.callbackEntries_.length||this.state_!==o.State_.FULFILLED&&this.state_!==o.State_.REJECTED||this.scheduleCallbacks_(),this.callbackEntries_||(this.callbackEntries_=[]),this.callbackEntries_.push(t)},o.prototype.addChildPromise_=function(t,n,r){var i={child:null,onFulfilled:null,onRejected:null};return i.child=new o(function(o,a){i.onFulfilled=t?function(e){try{var n=t.call(r,e);o(n)}catch(i){a(i)}}:o,i.onRejected=n?function(t){try{var i=n.call(r,t);!e.isDef(i)&&t.IS_CANCELLATION_ERROR?a(t):o(i)}catch(s){a(s)}}:a}),i.child.parent_=this,this.addCallbackEntry_(i),i.child},o.prototype.unblockAndFulfill_=function(t){if(this.state_!==o.State_.BLOCKED)throw new Error("CancellablePromise is not blocked.");this.state_=o.State_.PENDING,this.resolve_(o.State_.FULFILLED,t)},o.prototype.unblockAndReject_=function(t){if(this.state_!==o.State_.BLOCKED)throw new Error("CancellablePromise is not blocked.");this.state_=o.State_.PENDING,this.resolve_(o.State_.REJECTED,t)},o.prototype.resolve_=function(t,n){if(this.state_===o.State_.PENDING){if(this===n)t=o.State_.REJECTED,n=new TypeError("CancellablePromise cannot resolve to itself");else{if(r.isImplementedBy(n))return n=n,this.state_=o.State_.BLOCKED,void n.then(this.unblockAndFulfill_,this.unblockAndReject_,this);if(e.isObject(n))try{var i=n.then;if(e.isFunction(i))return void this.tryThen_(n,i)}catch(a){t=o.State_.REJECTED,n=a}}this.result_=n,this.state_=t,this.scheduleCallbacks_(),t!==o.State_.REJECTED||n.IS_CANCELLATION_ERROR||o.addUnhandledRejection_(this,n)}},o.prototype.tryThen_=function(t,e){this.state_=o.State_.BLOCKED;var n=this,r=!1,i=function(t){r||(r=!0,n.unblockAndFulfill_(t))},a=function(t){r||(r=!0,n.unblockAndReject_(t))};try{e.call(t,i,a)}catch(s){a(s)}},o.prototype.scheduleCallbacks_=function(){this.executing_||(this.executing_=!0,n.run(this.executeCallbacks_,this))},o.prototype.executeCallbacks_=function(){for(;this.callbackEntries_&&this.callbackEntries_.length;){var t=this.callbackEntries_;this.callbackEntries_=[];for(var e=0;e0)for(t=this;t&&t.unhandledRejectionId_;t=t.parent_)clearTimeout(t.unhandledRejectionId_),t.unhandledRejectionId_=0;else if(0===o.UNHANDLED_REJECTION_DELAY)for(t=this;t&&t.hadUnhandledRejection_;t=t.parent_)t.hadUnhandledRejection_=!1},o.addUnhandledRejection_=function(t,e){o.UNHANDLED_REJECTION_DELAY>0?t.unhandledRejectionId_=setTimeout(function(){o.handleRejection_.call(null,e)},o.UNHANDLED_REJECTION_DELAY):0===o.UNHANDLED_REJECTION_DELAY&&(t.hadUnhandledRejection_=!0,n.run(function(){t.hadUnhandledRejection_&&o.handleRejection_.call(null,e)}))},o.handleRejection_=n.throwException,o.setUnhandledRejectionHandler=function(t){o.handleRejection_=t},o.CancellationError=function(e){function n(r){t.classCallCheck(this,n);var i=t.possibleConstructorReturn(this,e.call(this,r));return r&&(i.message=r),
+i}return t.inherits(n,e),n}(Error),o.CancellationError.prototype.name="cancel",this.sennaNamed.Promise=this.sennaNamed.Promise||{},this.sennaNamed.Promise.CancellablePromise=o,this.senna.Promise=o}.call(this),function(){var t={document:document,window:window};this.senna.globals=t}.call(this),function(){function t(t){var e=document.createElement("a");return e.href=t,{hash:e.hash,hostname:e.hostname,password:e.password,pathname:"/"===e.pathname[0]?e.pathname:"/"+e.pathname,port:e.port,protocol:e.protocol,search:e.search,username:e.username}}this.senna.parseFromAnchor=t}.call(this),function(){function t(t){return e.isFunction(URL)&&URL.length?new URL(t):n(t)}var e=this.sennaNamed.metal.core,n=this.senna.parseFromAnchor;this.senna.parse=t}.call(this),function(){var e=this.sennaNamed.metal.Disposable,n=Object.create,r=function(e){function r(){t.classCallCheck(this,r);var i=t.possibleConstructorReturn(this,e.call(this));return i.keys=n(null),i.values=n(null),i}return t.inherits(r,e),r.prototype.add=function(t,e){return this.keys[t.toLowerCase()]=t,this.values[t.toLowerCase()]=this.values[t.toLowerCase()]||[],this.values[t.toLowerCase()].push(e),this},r.prototype.clear=function(){return this.keys=n(null),this.values=n(null),this},r.prototype.contains=function(t){return t.toLowerCase()in this.values},r.prototype.disposeInternal=function(){this.values=null},r.prototype.get=function(t){var e=this.values[t.toLowerCase()];return e?e[0]:void 0},r.prototype.getAll=function(t){return this.values[t.toLowerCase()]},r.prototype.isEmpty=function(){return 0===this.size()},r.prototype.names=function(){var t=this;return Object.keys(this.values).map(function(e){return t.keys[e]})},r.prototype.remove=function(t){return delete this.keys[t.toLowerCase()],delete this.values[t.toLowerCase()],this},r.prototype.set=function(t,e){return this.keys[t.toLowerCase()]=t,this.values[t.toLowerCase()]=[e],this},r.prototype.size=function(){return this.names().length},r.prototype.toString=function(){return JSON.stringify(this.values)},r}(e);this.senna.MultiMap=r}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.sennaNamed.metal.string,r=this.senna.parse,i=this.senna.MultiMap,o=r,a=function(){function r(){var e=arguments.length<=0||void 0===arguments[0]?"":arguments[0];t.classCallCheck(this,r),this.url=r.parse(this.maybeAddProtocolAndHostname_(e))}return r.prototype.addParametersFromMultiMap=function(t){var e=this;return t.names().forEach(function(n){t.getAll(n).forEach(function(t){e.addParameterValue(n,t)})}),this},r.prototype.addParameterValue=function(t,n){return this.ensureQueryInitialized_(),e.isDef(n)&&(n=String(n)),this.query.add(t,n),this},r.prototype.addParameterValues=function(t,e){var n=this;return e.forEach(function(e){return n.addParameterValue(t,e)}),this},r.prototype.ensureQueryInitialized_=function(){var n=this;if(!this.query){this.query=new i;var o=this.url.search;o&&o.substring(1).split("&").forEach(function(i){var o=i.split("="),a=t.slicedToArray(o,2),s=a[0],l=a[1];e.isDef(l)&&(l=r.urlDecode(l)),n.addParameterValue(s,l)})}},r.prototype.getHash=function(){return this.url.hash||""},r.prototype.getHost=function(){var t=this.getHostname();if(t){var e=this.getPort();e&&"80"!==e&&(t+=":"+e)}return t},r.prototype.getHostname=function(){var t=this.url.hostname;return t===r.HOSTNAME_PLACEHOLDER?"":t},r.prototype.getOrigin=function(){var t=this.getHost();return t?this.getProtocol()+"//"+t:""},r.prototype.getParameterValue=function(t){return this.ensureQueryInitialized_(),this.query.get(t)},r.prototype.getParameterValues=function(t){return this.ensureQueryInitialized_(),this.query.getAll(t)},r.prototype.getParameterNames=function(){return this.ensureQueryInitialized_(),this.query.names()},r.getParseFn=function(){return o},r.prototype.getPathname=function(){return this.url.pathname},r.prototype.getPort=function(){return this.url.port},r.prototype.getProtocol=function(){return this.url.protocol},r.prototype.getSearch=function(){var t=this,n="",r="";return this.getParameterNames().forEach(function(n){t.getParameterValues(n).forEach(function(t){r+=n,e.isDef(t)&&(r+="="+encodeURIComponent(t)),r+="&"})}),r=r.slice(0,-1),r&&(n+="?"+r),n},r.prototype.hasParameter=function(t){return this.ensureQueryInitialized_(),this.query.contains(t)},r.prototype.makeUnique=function(){return this.setParameterValue(r.RANDOM_PARAM,n.getRandomString()),this},r.prototype.maybeAddProtocolAndHostname_=function(t){var e=t;if(-1===t.indexOf("://")&&0!==t.indexOf("javascript:"))switch(e=r.DEFAULT_PROTOCOL,"/"===t[0]&&"/"===t[1]||(e+="//"),t.charAt(0)){case".":case"?":case"#":e+=r.HOSTNAME_PLACEHOLDER,e+="/",e+=t;break;case"":case"/":"/"!==t[1]&&(e+=r.HOSTNAME_PLACEHOLDER),e+=t;break;default:e+=t}return e},r.normalizeObject=function(t){var e=t.pathname?t.pathname.length:0;return e>1&&"/"===t.pathname[e-1]&&(t.pathname=t.pathname.substr(0,e-1)),t},r.parse=function(t){return r.normalizeObject(o(t))},r.prototype.removeParameter=function(t){return this.ensureQueryInitialized_(),this.query.remove(t),this},r.prototype.removeUnique=function(){return this.removeParameter(r.RANDOM_PARAM),this},r.prototype.setHash=function(t){return this.url.hash=t,this},r.prototype.setHostname=function(t){return this.url.hostname=t,this},r.prototype.setParameterValue=function(t,e){return this.removeParameter(t),this.addParameterValue(t,e),this},r.prototype.setParameterValues=function(t,e){var n=this;return this.removeParameter(t),e.forEach(function(e){return n.addParameterValue(t,e)}),this},r.prototype.setPathname=function(t){return this.url.pathname=t,this},r.prototype.setPort=function(t){return this.url.port=t,this},r.setParseFn=function(t){o=t},r.prototype.setProtocol=function(t){return this.url.protocol=t,":"!==this.url.protocol[this.url.protocol.length-1]&&(this.url.protocol+=":"),this},r.prototype.toString=function(){var t="",e=this.getHost();return e&&(t+=this.getProtocol()+"//"),t+=e+this.getPathname()+this.getSearch()+this.getHash()},r.joinPaths=function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),r=1;e>r;r++)n[r-1]=arguments[r];return"/"===t.charAt(t.length-1)&&(t=t.substring(0,t.length-1)),n=n.map(function(t){return"/"===t.charAt(0)?t.substring(1):t}),[t].concat(n).join("/").replace(/\/$/,"")},r.urlDecode=function(t){return decodeURIComponent(t.replace(/\+/g," "))},r}();a.DEFAULT_PROTOCOL="http:",a.HOSTNAME_PLACEHOLDER="hostname"+Date.now(),a.RANDOM_PARAM="zx",this.senna.Uri=a}.call(this),function(){var e=this.senna.globals,n=this.senna.Uri,r=function(){function r(){t.classCallCheck(this,r)}return r.copyNodeAttributes=function(t,e){Array.prototype.slice.call(t.attributes).forEach(function(t){return e.setAttribute(t.name,t.value)})},r.getCurrentBrowserPath=function(){return this.getCurrentBrowserPathWithoutHash()+e.window.location.hash},r.getCurrentBrowserPathWithoutHash=function(){return e.window.location.pathname+e.window.location.search},r.getUrlPath=function(t){var e=new n(t);return e.getPathname()+e.getSearch()+e.getHash()},r.getUrlPathWithoutHash=function(t){var e=new n(t);return e.getPathname()+e.getSearch()},r.isCurrentBrowserPath=function(t){return t?r.getUrlPathWithoutHash(t)===this.getCurrentBrowserPathWithoutHash():!1},r.isHtml5HistorySupported=function(){return!(!e.window.history||!e.window.history.pushState)},r.clearNodeAttributes=function(t){Array.prototype.slice.call(t.attributes).forEach(function(e){return t.removeAttribute(e.name)})},r}();this.senna.utils=r}.call(this),function(){var e=this.sennaNamed.metal.core,n=function(){function n(r,i){if(t.classCallCheck(this,n),!e.isDefAndNotNull(r))throw new Error("Route path not specified.");if(!e.isFunction(i))throw new Error("Route handler is not a function.");this.handler=i,this.path=r}return n.prototype.getHandler=function(){return this.handler},n.prototype.getPath=function(){return this.path},n.prototype.matchesPath=function(t){var n=this.path;return e.isString(n)?t===n:e.isFunction(n)?n(t):n instanceof RegExp?t.search(n)>-1:!1},n}();this.senna.Route=n}.call(this),function(){var e=this.sennaNamed.metal.Disposable,n=function(e){function n(){t.classCallCheck(this,n);var r=t.possibleConstructorReturn(this,e.call(this));return r.cache=null,r.cacheable=!1,r}return t.inherits(n,e),n.prototype.addCache=function(t){return this.cacheable&&(this.cache=t),this},n.prototype.clearCache=function(){return this.cache=null,this},n.prototype.disposeInternal=function(){this.clearCache()},n.prototype.getCache=function(){return this.cache},n.prototype.isCacheable=function(){return this.cacheable},n.prototype.setCacheable=function(t){t||this.clearCache(),this.cacheable=t},n}(e);this.senna.Cacheable=n}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.sennaNamed.dom.globalEval,r=this.senna.Cacheable,i=this.senna.Promise,o=function(r){function o(){t.classCallCheck(this,o);var n=t.possibleConstructorReturn(this,r.call(this));return n.id=n.makeId_(e.getUid()),n.title=null,n}return t.inherits(o,r),o.prototype.activate=function(){},o.prototype.beforeDeactivate=function(){},o.prototype.beforeUpdateHistoryPath=function(t){return t},o.prototype.beforeUpdateHistoryState=function(t){return t},o.prototype.deactivate=function(){},o.prototype.disposeInternal=function(){r.prototype.disposeInternal.call(this)},o.prototype.evaluateScripts=function(t){return Object.keys(t).forEach(function(e){t[e].activeChild&&n.runScriptsInElement(t[e].activeChild)}),i.resolve()},o.prototype.evaluateStyles=function(){return i.resolve()},o.prototype.flip=function(t){var e=this,n=[];return Object.keys(t).forEach(function(r){var i=t[r],o=i.show(e.id);n.push(o)}),i.all(n)},o.prototype.getId=function(){return this.id},o.prototype.getSurfaceContent=function(){},o.prototype.getTitle=function(){return this.title},o.prototype.load=function(){return i.resolve()},o.prototype.makeId_=function(t){return"screen_"+t},o.prototype.setId=function(t){this.id=t},o.prototype.setTitle=function(t){this.title=t},o.prototype.toString=function(){return this.id},o}(r);o.isImplementedBy=function(t){return t instanceof o},this.senna.Screen=o}.call(this),function(){var e=this.senna.globals,n=this.sennaNamed.metal.core,r=this.sennaNamed.metal.Disposable,i=this.senna.dom,o=this.senna.Promise,a=function(r){function a(e){t.classCallCheck(this,a);var n=t.possibleConstructorReturn(this,r.call(this));if(!e)throw new Error("Surface element id not specified. A surface element requires a valid id.");return n.activeChild=null,n.defaultChild=null,n.element=null,n.id=e,n.transitionFn=null,n.defaultChild=n.getChild(a.DEFAULT),n.maybeWrapContentAsDefault_(),n.activeChild=n.defaultChild,n}return t.inherits(a,r),a.prototype.addContent=function(t,e){var r=this.defaultChild;n.isDefAndNotNull(e)&&(r=this.getChild(t),r?i.removeChildren(r):(r=this.createChild(t),this.transition(r,null)),i.append(r,e));var o=this.getElement();return o&&r&&i.append(o,r),r},a.prototype.createChild=function(t){var n=e.document.createElement("div");return n.setAttribute("id",this.makeId_(t)),n},a.prototype.getChild=function(t){return e.document.getElementById(this.makeId_(t))},a.prototype.getElement=function(){return this.element?this.element:(this.element=e.document.getElementById(this.id),this.element)},a.prototype.getId=function(){return this.id},a.prototype.getTransitionFn=function(){return this.transitionFn},a.prototype.makeId_=function(t){return this.id+"-"+t},a.prototype.maybeWrapContentAsDefault_=function(){var t=this.getElement();if(t&&!this.defaultChild){for(var n=e.document.createDocumentFragment();t.firstChild;)n.appendChild(t.firstChild);this.defaultChild=this.addContent(a.DEFAULT,n),this.transition(null,this.defaultChild)}},a.prototype.setId=function(t){this.id=t},a.prototype.setTransitionFn=function(t){this.transitionFn=t},a.prototype.show=function(t){var e=this.activeChild,n=this.getChild(t);return n||(n=this.defaultChild),this.activeChild=n,this.transition(e,n).thenAlways(function(){e&&e!==n&&i.exitDocument(e)})},a.prototype.remove=function(t){var e=this.getChild(t);e&&i.exitDocument(e)},a.prototype.toString=function(){return this.id},a.prototype.transition=function(t,e){var n=this.transitionFn||a.defaultTransition;return o.resolve(n.call(this,t,e))},a}(r);a.DEFAULT="default",a.defaultTransition=function(t,e){t&&(t.style.display="none",t.classList.remove("flipped")),e&&(e.style.display="block",e.classList.add("flipped"))},this.senna.Surface=a}.call(this),function(){var e=this.sennaNamed.metal.array,n=this.sennaNamed.metal.async,r=this.sennaNamed.metal.core,i=this.senna.dom,o=this.senna.Promise,a=this.sennaNamed.events.EventEmitter,s=this.sennaNamed.events.EventHandler,l=this.senna.utils,c=this.senna.globals,u=this.senna.Route,h=this.senna.Screen,p=this.senna.Surface,d=this.senna.Uri,f=function(a){function f(){t.classCallCheck(this,f);var e=t.possibleConstructorReturn(this,a.call(this));return e.activeScreen=null,e.activePath=null,e.allowPreventNavigate=!0,e.basePath="",e.captureScrollPositionFromScrollEvent=!0,e.defaultTitle=c.document.title,e.formSelector='form[enctype="multipart/form-data"]:not([data-senna-off])',e.linkSelector="a:not([data-senna-off])",e.loadingCssClass="senna-loading",e.nativeScrollRestorationSupported="scrollRestoration"in c.window.history,e.pendingNavigate=null,e.popstateScrollLeft=0,e.popstateScrollTop=0,e.redirectPath=null,e.routes=[],e.screens={},e.skipLoadPopstate=!1,e.surfaces={},e.updateScrollPosition=!0,e.appEventHandlers_=new s,e.appEventHandlers_.add(i.on(c.window,"scroll",e.onScroll_.bind(e)),i.on(c.window,"load",e.onLoad_.bind(e)),i.on(c.window,"popstate",e.onPopstate_.bind(e))),e.on("startNavigate",e.onStartNavigate_),e.on("beforeNavigate",e.onBeforeNavigate_),e.on("beforeNavigate",e.onBeforeNavigateDefault_,!0),e.setLinkSelector(e.linkSelector),e.setFormSelector(e.formSelector),e}return t.inherits(f,a),f.prototype.addRoutes=function(t){var e=this;return Array.isArray(t)||(t=[t]),t.forEach(function(t){t instanceof u||(t=new u(t.path,t.handler)),e.routes.push(t)}),this},f.prototype.addSurfaces=function(t){var e=this;return Array.isArray(t)||(t=[t]),t.forEach(function(t){r.isString(t)&&(t=new p(t)),e.surfaces[t.getId()]=t}),this},f.prototype.canNavigate=function(t){var e=l.getUrlPath(t),n=new d(t);return this.isLinkSameOrigin_(n.getHostname())&&this.isSameBasePath_(e)?!!this.findRoute(e):!1},f.prototype.clearScreensCache=function(){var t=this;Object.keys(this.screens).forEach(function(e){e===t.activePath?t.activeScreen.clearCache():t.removeScreen(e)})},f.prototype.createScreenInstance=function(t,e){if(!this.pendingNavigate&&t===this.activePath)return this.activeScreen;var n=this.screens[t];if(!n){var r=e.getHandler();n=r===h||h.isImplementedBy(r.prototype)?new r:r(e)||new h}return n},f.prototype.disposeInternal=function(){this.activeScreen&&this.removeScreen(this.activePath),this.clearScreensCache(),this.formEventHandler_.removeListener(),this.linkEventHandler_.removeListener(),this.appEventHandlers_.removeAllListeners(),a.prototype.disposeInternal.call(this)},f.prototype.dispatch=function(){return this.navigate(l.getCurrentBrowserPath(),!0)},f.prototype.doNavigate_=function(t,e){var n=this;if(this.activeScreen&&this.activeScreen.beforeDeactivate())return this.pendingNavigate=o.reject(new o.CancellationError("Cancelled by active screen")),this.pendingNavigate;var r=this.findRoute(t);if(!r)return this.pendingNavigate=o.reject(new o.CancellationError("No route for "+t)),this.pendingNavigate;this.stopPendingNavigate_();var i=this.createScreenInstance(t,r);return i.load(t).then(function(){n.activeScreen&&n.activeScreen.deactivate(),n.prepareNavigateHistory_(t,i,e),n.prepareNavigateSurfaces_(i,n.surfaces)}).then(function(){return i.evaluateStyles(n.surfaces)}).then(function(){return i.flip(n.surfaces)}).then(function(){return i.evaluateScripts(n.surfaces)}).then(function(){return n.syncScrollPositionSyncThenAsync_()}).then(function(){return n.finalizeNavigate_(t,i)})["catch"](function(e){throw n.handleNavigateError_(t,i,e),e})},f.prototype.finalizeNavigate_=function(t,e){e.activate(),this.activeScreen&&!this.activeScreen.isCacheable()&&this.activeScreen!==e&&this.removeScreen(this.activePath),this.activePath=t,this.activeScreen=e,this.screens[t]=e,this.pendingNavigate=null,c.capturedFormElement=null},f.prototype.findRoute=function(t){if(t.lastIndexOf("#")>-1&&l.isCurrentBrowserPath(t))return null;t=l.getUrlPathWithoutHash(t),t=l.getUrlPathWithoutHash(t.substr(this.basePath.length));for(var e=0;e0},f.prototype.isLinkSameOrigin_=function(t){return t===c.window.location.hostname},f.prototype.isSameBasePath_=function(t){return 0===t.indexOf(this.basePath)},f.prototype.lockHistoryScrollPosition_=function(){var t=c.window.history.state;if(t){var e=!1,r=function i(){c.document.removeEventListener("scroll",i,!1),e||(c.window.scrollTo(t.scrollLeft,t.scrollTop),e=!0)};n.nextTick(r),c.document.addEventListener("scroll",r,!1)}},f.prototype.maybeDisableNativeScrollRestoration=function(){this.nativeScrollRestorationSupported&&(this.nativeScrollRestoration_=c.window.history.scrollRestoration,c.window.history.scrollRestoration="manual")},f.prototype.maybeNavigate_=function(t,e){if(this.canNavigate(t)){c.capturedFormElement=e.capturedFormElement;var n=!1;try{this.navigate(l.getUrlPath(t))}catch(r){n=!0}n||e.preventDefault()}},f.prototype.maybeRepositionScrollToHashedAnchor=function(){var t=c.window.location.hash;if(t){var e=c.document.getElementById(t.substring(1));e&&c.window.scrollTo(e.offsetLeft,e.offsetTop)}},f.prototype.maybeRestoreNativeScrollRestoration=function(){this.nativeScrollRestorationSupported&&this.nativeScrollRestoration_&&(c.window.history.scrollRestoration=this.nativeScrollRestoration_)},f.prototype.navigate=function(t,e){if(!l.isHtml5HistorySupported())throw new Error("HTML5 History is not supported. Senna will not intercept navigation.");return t===this.activePath&&(e=!0),this.emit("beforeNavigate",{path:t,replaceHistory:!!e}),this.pendingNavigate},f.prototype.onBeforeNavigate_=function(t){c.capturedFormElement&&(t.form=c.capturedFormElement)},f.prototype.onBeforeNavigateDefault_=function(t){this.pendingNavigate&&this.pendingNavigate.path===t.path||this.emit("startNavigate",{form:t.form,path:t.path,replaceHistory:t.replaceHistory})},f.prototype.onDocClickDelegate_=function(t){t.altKey||t.ctrlKey||t.metaKey||t.shiftKey||t.button||this.maybeNavigate_(t.delegateTarget.href,t)},f.prototype.onDocSubmitDelegate_=function(t){var e=t.delegateTarget;"get"!==e.method&&(t.capturedFormElement=e,this.maybeNavigate_(e.action,t))},f.prototype.onLoad_=function(){var t=this;this.skipLoadPopstate=!0,setTimeout(function(){t.skipLoadPopstate=!1},0),this.maybeRepositionScrollToHashedAnchor()},f.prototype.onPopstate_=function(t){if(!this.skipLoadPopstate){var e=t.state;return e?void(e.senna&&(this.popstateScrollTop=e.scrollTop,this.popstateScrollLeft=e.scrollLeft,this.nativeScrollRestorationSupported||this.lockHistoryScrollPosition_(),this.navigate(e.path,!0))):void(c.window.location.hash?(this.redirectPath&&!l.isCurrentBrowserPath(this.redirectPath)&&this.reloadPage(),this.maybeRepositionScrollToHashedAnchor()):this.reloadPage())}},f.prototype.onScroll_=function(){this.captureScrollPositionFromScrollEvent&&this.saveHistoryCurrentPageScrollPosition_()},f.prototype.onStartNavigate_=function(t){var e=this;this.maybeDisableNativeScrollRestoration(),this.captureScrollPositionFromScrollEvent=!1,i.addClasses(c.document.documentElement,this.loadingCssClass);var n={form:t.form,path:t.path};this.pendingNavigate=this.doNavigate_(t.path,t.replaceHistory)["catch"](function(t){throw n.error=t,t}).thenAlways(function(){e.pendingNavigate||(i.removeClasses(c.document.documentElement,e.loadingCssClass),e.maybeRestoreNativeScrollRestoration(),e.captureScrollPositionFromScrollEvent=!0),e.emit("endNavigate",n)}),this.pendingNavigate.path=t.path},f.prototype.prefetch=function(t){var e=this,n=this.findRoute(t);if(!n)return o.reject(new o.CancellationError("No route for "+t));var r=this.createScreenInstance(t,n);return r.load(t).then(function(){return e.screens[t]=r})["catch"](function(n){throw e.handleNavigateError_(t,r,n),n})},f.prototype.prepareNavigateHistory_=function(t,e,n){var i=e.getTitle();r.isString(i)||(i=this.getDefaultTitle());var o=e.beforeUpdateHistoryPath(t),a={form:r.isDefAndNotNull(c.capturedFormElement),redirectPath:o,path:t,senna:!0,scrollTop:0,scrollLeft:0};n&&(a.scrollTop=this.popstateScrollTop,a.scrollLeft=this.popstateScrollLeft),this.updateHistory_(i,o,e.beforeUpdateHistoryState(a),n),this.redirectPath=o},f.prototype.prepareNavigateSurfaces_=function(t,e){Object.keys(e).forEach(function(n){var r=t.getSurfaceContent(n);e[n].addContent(t.getId(),r)})},f.prototype.reloadPage=function(){c.window.location.reload()},f.prototype.removeRoute=function(t){return e.remove(this.routes,t)},f.prototype.removeScreen=function(t){var e=this,n=this.screens[t];n&&(Object.keys(this.surfaces).forEach(function(t){return e.surfaces[t].remove(n.getId())}),n.dispose(),delete this.screens[t])},f.prototype.saveHistoryCurrentPageScrollPosition_=function(){var t=c.window.history.state;t&&t.senna&&(t.scrollTop=c.window.pageYOffset,t.scrollLeft=c.window.pageXOffset,c.window.history.replaceState(t,null,null))},f.prototype.setAllowPreventNavigate=function(t){this.allowPreventNavigate=t},f.prototype.setBasePath=function(t){this.basePath=t},f.prototype.setDefaultTitle=function(t){this.defaultTitle=t},f.prototype.setFormSelector=function(t){this.formSelector=t,this.formEventHandler_&&this.formEventHandler_.removeListener(),this.formEventHandler_=i.delegate(document,"submit",this.formSelector,this.onDocSubmitDelegate_.bind(this),this.allowPreventNavigate)},f.prototype.setLinkSelector=function(t){this.linkSelector=t,this.linkEventHandler_&&this.linkEventHandler_.removeListener(),this.linkEventHandler_=i.delegate(document,"click",this.linkSelector,this.onDocClickDelegate_.bind(this),this.allowPreventNavigate)},f.prototype.setLoadingCssClass=function(t){this.loadingCssClass=t},f.prototype.setUpdateScrollPosition=function(t){this.updateScrollPosition=t},f.prototype.stopPendingNavigate_=function(){this.pendingNavigate&&(this.pendingNavigate.cancel("Cancel pending navigation"),this.pendingNavigate=null)},f.prototype.syncScrollPositionSyncThenAsync_=function(){var t=this,e=c.window.history.state;if(e){var r=e.scrollTop,i=e.scrollLeft,a=function(){t.updateScrollPosition&&c.window.scrollTo(i,r)};return new o(function(t){return a()&n.nextTick(function(){return a()&t()})})}},f.prototype.updateHistory_=function(t,e,n,r){r?c.window.history.replaceState(n,t,e):c.window.history.pushState(n,t,e),c.document.title=t},f}(a);this.senna.App=f}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.senna.Uri,r=this.sennaNamed.Promise.CancellablePromise,i=function(){function i(){t.classCallCheck(this,i)}return i.parseResponseHeaders=function(t){var e=[];if(!t)return e;for(var n=t.split("\r\n"),r=0;r0){var o=n[r].substring(0,i),a=n[r].substring(i+2);e.push({name:o,value:a})}}return e},i.request=function o(t,i,a,s,l,c,u,h){var o=new XMLHttpRequest,p=new r(function(t,e){o.onload=function(){return o.aborted?void o.onerror():void t(o)},o.onerror=function(){var t=new Error("Request error");t.request=o,e(t)}}).thenCatch(function(t){throw o.abort(),t}).thenAlways(function(){clearTimeout(d)});if(l&&(t=new n(t).addParametersFromMultiMap(l).toString()),o.open(i,t,!u),h&&(o.withCredentials=!0),s&&s.names().forEach(function(t){o.setRequestHeader(t,s.getAll(t).join(", "))}),o.send(e.isDef(a)?a:null),e.isDefAndNotNull(c))var d=setTimeout(function(){p.cancel("Request timeout")},c);return p},i}();this.senna.Ajax=i}.call(this),function(){var e=function n(){t.classCallCheck(this,n)};e.INVALID_STATUS="Invalid status code",e.REQUEST_ERROR="Request error",e.REQUEST_TIMEOUT="Request timeout",this.senna.errors=e}.call(this),function(){var e=function(){function e(){t.classCallCheck(this,e)}return e.getNativeUserAgent=function(){var t=e.globals.window.navigator;if(t){var n=t.userAgent;if(n)return n}return""},e.matchUserAgent=function(t){return-1!==e.userAgent.indexOf(t)},e.testUserAgent=function(t){e.userAgent=t,e.isOpera=e.matchUserAgent("Opera")||e.matchUserAgent("OPR"),e.isIe=e.matchUserAgent("Trident")||e.matchUserAgent("MSIE"),e.isEdge=e.matchUserAgent("Edge"),e.isIeOrEdge=e.isIe||e.isEdge,e.isChrome=(e.matchUserAgent("Chrome")||e.matchUserAgent("CriOS"))&&!e.isOpera&&!e.isEdge,e.isSafari=e.matchUserAgent("Safari")&&!(e.isChrome||e.isOpera||e.isEdge),e.isFirefox=e.matchUserAgent("Firefox")},e}();e.globals={window:window},e.testUserAgent(e.getNativeUserAgent()),this.senna.UA=e}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.senna.Ajax,r=this.senna.MultiMap,i=this.senna.Promise,o=this.senna.errors,a=this.senna.utils,s=this.senna.globals,l=this.senna.Screen,c=this.senna.Uri,u=this.senna.UA,h=function(l){function h(){t.classCallCheck(this,h);var e=t.possibleConstructorReturn(this,l.call(this));return e.cacheable=!0,e.httpHeaders={"X-PJAX":"true","X-Requested-With":"XMLHttpRequest"},e.httpMethod=h.GET,e.request=null,e.timeout=3e4,e}return t.inherits(h,l),h.prototype.assertValidResponseStatusCode=function(t){if(!this.isValidResponseStatusCode(t)){var e=new Error(o.INVALID_STATUS);throw e.invalidStatus=!0,e}},h.prototype.beforeUpdateHistoryPath=function(t){var e=this.getRequestPath();return e&&e!==t?e:t},h.prototype.beforeUpdateHistoryState=function(t){return t.senna&&t.form&&t.redirectPath===t.path?null:t},h.prototype.formatLoadPath=function(t){return u.isIeOrEdge&&this.httpMethod===h.GET?new c(t).makeUnique().toString():t},h.prototype.getHttpHeaders=function(){return this.httpHeaders},h.prototype.getHttpMethod=function(){return this.httpMethod},h.prototype.getRequestPath=function(){var t=this.getRequest();if(t){var e=t.requestPath,n=this.maybeExtractResponseUrlFromRequest(t);return n&&(e=n),u.isIeOrEdge&&this.httpMethod===h.GET&&(e=new c(e).removeUnique().toString()),a.getUrlPath(e)}return null},h.prototype.getRequest=function(){return this.request},h.prototype.getTimeout=function(){return this.timeout},h.prototype.isValidResponseStatusCode=function(t){return t>=200&&399>=t},h.prototype.load=function(t){var a=this,l=this.getCache();if(e.isDefAndNotNull(l))return i.resolve(l);var c=null,p=this.httpMethod,d=new r;Object.keys(this.httpHeaders).forEach(function(t){return d.add(t,a.httpHeaders[t])}),s.capturedFormElement&&(c=new FormData(s.capturedFormElement),p=h.POST,u.isIeOrEdge&&d.add("If-None-Match",'"0"'));var f=this.formatLoadPath(t);return n.request(f,p,c,d,null,this.timeout).then(function(t){return a.setRequest(t),a.assertValidResponseStatusCode(t.status),p===h.GET&&a.isCacheable()&&a.addCache(t.responseText),t.requestPath=f,t.responseText})["catch"](function(t){switch(t.message){case o.REQUEST_TIMEOUT:t.timeout=!0;break;case o.REQUEST_ERROR:t.requestError=!0}throw t})},h.prototype.maybeExtractResponseUrlFromRequest=function(t){var e=t.responseURL;return e?e:t.getResponseHeader(h.X_REQUEST_URL_HEADER)},h.prototype.setHttpHeaders=function(t){this.httpHeaders=t},h.prototype.setHttpMethod=function(t){this.httpMethod=t.toLowerCase()},h.prototype.setRequest=function(t){this.request=t},h.prototype.setTimeout=function(t){this.timeout=t},h}(l);h.GET="get",h.POST="post",h.X_REQUEST_URL_HEADER="X-Request-URL",this.senna.RequestScreen=h}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.sennaNamed.dom.dom,r=this.sennaNamed.dom.globalEval,i=this.sennaNamed.dom.globalEvalStyles,o=this.senna.Promise,a=this.senna.globals,s=this.senna.RequestScreen,l=this.senna.Surface,c=this.senna.UA,u=this.senna.Uri,h=this.senna.utils,p=function(s){function p(){t.classCallCheck(this,p);var e=t.possibleConstructorReturn(this,s.call(this));return e.titleSelector="title",e}return t.inherits(p,s),p.prototype.activate=function(){s.prototype.activate.call(this),this.releaseVirtualDocument(),this.pendingStyles=null},p.prototype.allocateVirtualDocumentForContent=function(t){this.virtualDocument||(this.virtualDocument=a.document.createElement("html")),this.copyNodeAttributesFromContent_(t,this.virtualDocument),this.virtualDocument.innerHTML=t},p.prototype.appendStyleIntoDocument_=function(t){var e=n.match(t,p.selectors.stylesTemporary);if(e&&(this.pendingStyles.push(t),c.isIe&&t.href&&(t.href=new u(t.href).makeUnique().toString())),t.id){var r=a.document.getElementById(t.id);if(r)return void r.parentNode.insertBefore(t,r.nextSibling)}a.document.head.appendChild(t)},p.prototype.assertSameBodyIdInVirtualDocument=function(){var t=this.virtualDocument.querySelector("body");a.document.body.id||(a.document.body.id="senna_surface_"+e.getUid()),t&&(t.id=a.document.body.id)},p.prototype.copyNodeAttributesFromContent_=function(t,e){t=t.replace(/[<]\s*html/gi,"/gi,"/senna>"),e.innerHTML=t;var n=e.querySelector("senna");n&&(h.clearNodeAttributes(e),h.copyNodeAttributes(n,e))},p.prototype.disposeInternal=function(){this.disposePendingStyles(),s.prototype.disposeInternal.call(this)},p.prototype.disposePendingStyles=function(){this.pendingStyles&&this.pendingStyles.forEach(function(t){return n.exitDocument(t)})},p.prototype.evaluateScripts=function(t){var e=this,n=this.evaluateTrackedResources_(r.runScriptsInElement,p.selectors.scripts,p.selectors.scriptsTemporary,p.selectors.scriptsPermanent);return n.then(function(){return s.prototype.evaluateScripts.call(e,t)})},p.prototype.evaluateStyles=function(t){var e=this;this.pendingStyles=[];var n=this.evaluateTrackedResources_(i.runStylesInElement,p.selectors.styles,p.selectors.stylesTemporary,p.selectors.stylesPermanent,this.appendStyleIntoDocument_.bind(this));return n.then(function(){return s.prototype.evaluateStyles.call(e,t)})},p.prototype.evaluateTrackedResources_=function(t,e,r,i,a){var s=this,l=this.virtualQuerySelectorAll_(e),c=this.querySelectorAll_(r),u=this.querySelectorAll_(i);u.forEach(function(t){var e=s.getResourceKey_(t);e&&(p.permanentResourcesInDoc[e]=!0)});var h=n.buildFragment();return l.forEach(function(t){var e=s.getResourceKey_(t);p.permanentResourcesInDoc[e]||h.appendChild(t),e&&n.match(t,i)&&(p.permanentResourcesInDoc[e]=!0)}),new o(function(e){t(h,function(){c.forEach(function(t){return n.exitDocument(t)}),e()},a)})},p.prototype.flip=function(t){var e=this;return s.prototype.flip.call(this,t).then(function(){h.clearNodeAttributes(document.documentElement),h.copyNodeAttributes(e.virtualDocument,document.documentElement)})},p.prototype.getResourceKey_=function(t){return t.id||t.href||t.src||""},p.prototype.getSurfaceContent=function(t){var e=this.virtualDocument.querySelector("#"+t);if(e){var n=e.querySelector("#"+t+"-"+l.DEFAULT);return n?n.innerHTML:e.innerHTML}},p.prototype.getTitleSelector=function(){return this.titleSelector},p.prototype.load=function(t){var e=this;return s.prototype.load.call(this,t).then(function(t){return e.allocateVirtualDocumentForContent(t),e.resolveTitleFromVirtualDocument(),e.assertSameBodyIdInVirtualDocument(),t})},p.prototype.virtualQuerySelectorAll_=function(t){return Array.prototype.slice.call(this.virtualDocument.querySelectorAll(t))},p.prototype.querySelectorAll_=function(t){return Array.prototype.slice.call(a.document.querySelectorAll(t))},p.prototype.releaseVirtualDocument=function(){
+this.virtualDocument=null},p.prototype.resolveTitleFromVirtualDocument=function(){var t=this.virtualDocument.querySelector(this.titleSelector);t&&this.setTitle(t.innerHTML.trim())},p.prototype.setTitleSelector=function(t){this.titleSelector=t},p}(s);p.selectors={scripts:"script[data-senna-track]",scriptsPermanent:'script[data-senna-track="permanent"]',scriptsTemporary:'script[data-senna-track="temporary"]',styles:"style[data-senna-track],link[data-senna-track]",stylesPermanent:'style[data-senna-track="permanent"],link[data-senna-track="permanent"]',stylesTemporary:'style[data-senna-track="temporary"],link[data-senna-track="temporary"]'},p.permanentResourcesInDoc={},this.senna.HtmlScreen=p}.call(this),function(){var t=this.senna.App,e=this.senna.HtmlScreen,n=this.senna.RequestScreen,r=this.senna.Route,i=this.senna.Screen;this.senna.senna=t,this.sennaNamed.senna=this.sennaNamed.senna||{},this.sennaNamed.senna.App=t,this.sennaNamed.senna.HtmlScreen=e,this.sennaNamed.senna.Route=r,this.sennaNamed.senna.RequestScreen=n,this.sennaNamed.senna.Screen=i}.call(this),function(){this.senna.dataAttributes={basePath:"data-senna-base-path",linkSelector:"data-senna-link-selector",loadingCssClass:"data-senna-loading-css-class",senna:"data-senna",dispatch:"data-senna-dispatch",surface:"data-senna-surface",updateScrollPosition:"data-senna-update-scroll-position"}}.call(this),function(){var e=this.sennaNamed.metal.core,n=this.sennaNamed.metal.object,r=this.sennaNamed.metal.Disposable,i=this.senna.dataAttributes,o=this.senna.globals,a=this.senna.App,s=this.senna.HtmlScreen,l=this.senna.Route,c=function(r){function c(){t.classCallCheck(this,c);var e=t.possibleConstructorReturn(this,r.call(this));return e.app=null,e.baseElement=null,e}return t.inherits(c,r),c.prototype.handle=function(){if(!e.isElement(this.baseElement))throw new Error("Senna data attribute handler base element not set or invalid, try setting a valid element that contains a `data-senna` attribute.");if(this.baseElement.hasAttribute(i.senna)){if(this.app)throw new Error("Senna app was already initialized.");this.app=new a,this.maybeAddRoutes_(),this.maybeAddSurfaces_(),this.maybeSetBasePath_(),this.maybeSetLinkSelector_(),this.maybeSetLoadingCssClass_(),this.maybeSetUpdateScrollPosition_(),this.maybeDispatch_()}},c.prototype.disposeInternal=function(){this.app&&this.app.dispose()},c.prototype.getApp=function(){return this.app},c.prototype.getBaseElement=function(){return this.baseElement},c.prototype.maybeAddRoutes_=function(){var t=this,e='link[rel="senna-route"]';this.querySelectorAllAsArray_(e).forEach(function(e){return t.maybeParseLinkRoute_(e)}),this.app.hasRoutes()||this.app.addRoutes(new l(/.*/,s))},c.prototype.maybeAddSurfaces_=function(){var t=this,e="["+i.surface+"]";this.querySelectorAllAsArray_(e).forEach(function(e){t.updateElementIdIfSpecialSurface_(e),t.app.addSurfaces(e.id)})},c.prototype.maybeDispatch_=function(){this.baseElement.hasAttribute(i.dispatch)&&this.app.dispatch()},c.prototype.maybeParseLinkRoute_=function(t){var e=new l(this.maybeParseLinkRoutePath_(t),this.maybeParseLinkRouteHandler_(t));this.app.addRoutes(e)},c.prototype.maybeParseLinkRouteHandler_=function(t){var r=t.getAttribute("type");return e.isDefAndNotNull(r)&&(r=n.getObjectByName(r)),r},c.prototype.maybeParseLinkRoutePath_=function(t){var n=t.getAttribute("href");return e.isDefAndNotNull(n)&&0===n.indexOf("regex:")&&(n=new RegExp(n.substring(6))),n},c.prototype.maybeSetBasePath_=function(){var t=this.baseElement.getAttribute(i.basePath);e.isDefAndNotNull(t)&&this.app.setBasePath(t)},c.prototype.maybeSetLinkSelector_=function(){var t=this.baseElement.getAttribute(i.linkSelector);e.isDefAndNotNull(t)&&this.app.setLinkSelector(t)},c.prototype.maybeSetLoadingCssClass_=function(){var t=this.baseElement.getAttribute(i.loadingCssClass);e.isDefAndNotNull(t)&&this.app.setLoadingCssClass(t)},c.prototype.maybeSetUpdateScrollPosition_=function(){var t=this.baseElement.getAttribute(i.updateScrollPosition);e.isDefAndNotNull(t)&&("false"===t?this.app.setUpdateScrollPosition(!1):this.app.setUpdateScrollPosition(!0))},c.prototype.querySelectorAllAsArray_=function(t){return Array.prototype.slice.call(o.document.querySelectorAll(t))},c.prototype.updateElementIdIfSpecialSurface_=function(t){t.id||t!==o.document.body||(t.id="senna_surface_"+e.getUid())},c.prototype.setBaseElement=function(t){this.baseElement=t},c}(r);this.senna.AppDataAttributeHandler=c}.call(this),function(){var t=this.senna.globals,e=this.senna.AppDataAttributeHandler,n=new e;t.document.addEventListener("DOMContentLoaded",function(){n.setBaseElement(t.document.body),n.handle()}),this.senna.dataAttributeHandler=n}.call(this)}).call(this);
\ No newline at end of file
diff --git a/build/globals/senna.js b/build/globals/senna.js
index cdaa70b..b9e6166 100644
--- a/build/globals/senna.js
+++ b/build/globals/senna.js
@@ -1,7 +1,7 @@
/**
* Senna.js - A blazing-fast Single Page Application engine
* @author Eduardo Lundgren
- * @version v1.2.0
+ * @version v1.3.0
* @link http://sennajs.com
* @license BSD-3-Clause
*/
@@ -154,15 +154,21 @@ babelHelpers;
* mutated with an unique id. Consecutive calls with the same object
* reference won't mutate the object again, instead the current object uid
* returns. See {@link core.UID_PROPERTY}.
- * @type {opt_object} Optional object to be mutated with the uid. If not
- * specified this method only returns the uid.
+ * @param {Object=} opt_object Optional object to be mutated with the uid. If
+ * not specified this method only returns the uid.
+ * @param {boolean=} opt_noInheritance Optional flag indicating if this
+ * object's uid property can be inherited from parents or not.
* @throws {Error} when invoked to indicate the method should be overridden.
*/
- core.getUid = function getUid(opt_object) {
+ core.getUid = function getUid(opt_object, opt_noInheritance) {
if (opt_object) {
- return opt_object[core.UID_PROPERTY] || (opt_object[core.UID_PROPERTY] = core.uniqueIdCounter_++);
+ var id = opt_object[core.UID_PROPERTY];
+ if (opt_noInheritance && !opt_object.hasOwnProperty(core.UID_PROPERTY)) {
+ id = null;
+ }
+ return id || (opt_object[core.UID_PROPERTY] = core.uniqueIdCounter_++);
}
return core.uniqueIdCounter_++;
};
@@ -980,6 +986,35 @@ babelHelpers;
}).call(this);
'use strict';
+(function () {
+ var METAL_DATA = '__metal_data__';
+
+ this.senna.metalData = function () {
+ function thisSennaMetalData() {
+ babelHelpers.classCallCheck(this, thisSennaMetalData);
+ }
+
+ /**
+ * Gets Metal.js's data for the given element.
+ * @param {!Element} element
+ * @return {!Object}
+ */
+
+ thisSennaMetalData.get = function get(element) {
+ if (!element[METAL_DATA]) {
+ element[METAL_DATA] = {
+ delegating: {},
+ listeners: {}
+ };
+ }
+ return element[METAL_DATA];
+ };
+
+ return thisSennaMetalData;
+ }();
+}).call(this);
+'use strict';
+
(function () {
var Disposable = this.sennaNamed.metal.Disposable;
@@ -1776,6 +1811,64 @@ babelHelpers;
}).call(this);
'use strict';
+(function () {
+ var array = this.sennaNamed.metal.array;
+ var core = this.sennaNamed.metal.core;
+ var metalData = this.senna.metalData;
+ var EventHandle = this.sennaNamed.events.EventHandle;
+
+ /**
+ * This is a special EventHandle, that is responsible for dom delegated events
+ * (only the ones that receive a target element, not a selector string).
+ * @extends {EventHandle}
+ */
+
+ var DomDelegatedEventHandle = function (_EventHandle) {
+ babelHelpers.inherits(DomDelegatedEventHandle, _EventHandle);
+
+ /**
+ * The constructor for `DomDelegatedEventHandle`.
+ * @param {!Event} emitter Element the event was subscribed to.
+ * @param {string} event The name of the event that was subscribed to.
+ * @param {!Function} listener The listener subscribed to the event.
+ * @param {string=} opt_selector An optional selector used when delegating
+ * the event.
+ * @constructor
+ */
+
+ function DomDelegatedEventHandle(emitter, event, listener, opt_selector) {
+ babelHelpers.classCallCheck(this, DomDelegatedEventHandle);
+
+ var _this = babelHelpers.possibleConstructorReturn(this, _EventHandle.call(this, emitter, event, listener));
+
+ _this.selector_ = opt_selector;
+ return _this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+
+
+ DomDelegatedEventHandle.prototype.removeListener = function removeListener() {
+ var data = metalData.get(this.emitter_);
+ var selector = this.selector_;
+ var arr = core.isString(selector) ? data.delegating[this.event_].selectors : data.listeners;
+ var key = core.isString(selector) ? selector : this.event_;
+
+ array.remove(arr[key] || [], this.listener_);
+ if (arr[key] && arr[key].length === 0) {
+ delete arr[key];
+ }
+ };
+
+ return DomDelegatedEventHandle;
+ }(EventHandle);
+
+ this.senna.DomDelegatedEventHandle = DomDelegatedEventHandle;
+}).call(this);
+'use strict';
+
(function () {
var EventHandle = this.sennaNamed.events.EventHandle;
@@ -1826,8 +1919,18 @@ babelHelpers;
(function () {
var core = this.sennaNamed.metal.core;
var object = this.sennaNamed.metal.object;
+ var metalData = this.senna.metalData;
+ var DomDelegatedEventHandle = this.senna.DomDelegatedEventHandle;
var DomEventHandle = this.senna.DomEventHandle;
+
+ var NEXT_TARGET = '__metal_next_target__';
+ var USE_CAPTURE = {
+ blur: true,
+ focus: true,
+ scroll: true
+ };
+
var dom = function () {
function dom() {
babelHelpers.classCallCheck(this, dom);
@@ -1894,6 +1997,71 @@ babelHelpers;
}
};
+ /**
+ * Adds an event listener to the given element, to be triggered via delegate.
+ * @param {!Element} element
+ * @param {string} eventName
+ * @param {!function()} listener
+ * @protected
+ */
+
+
+ dom.addElementListener_ = function addElementListener_(element, eventName, listener) {
+ var data = metalData.get(element);
+ dom.addToArr_(data.listeners, eventName, listener);
+ };
+
+ /**
+ * Adds an event listener to the given element, to be triggered via delegate
+ * selectors.
+ * @param {!Element} element
+ * @param {string} eventName
+ * @param {string} selector
+ * @param {!function()} listener
+ * @protected
+ */
+
+
+ dom.addSelectorListener_ = function addSelectorListener_(element, eventName, selector, listener) {
+ var data = metalData.get(element);
+ dom.addToArr_(data.delegating[eventName].selectors, selector, listener);
+ };
+
+ /**
+ * Adds a value to an array inside an object, creating it first if it doesn't
+ * yet exist.
+ * @param {!Array} arr
+ * @param {string} key
+ * @param {*} value
+ * @protected
+ */
+
+
+ dom.addToArr_ = function addToArr_(arr, key, value) {
+ if (!arr[key]) {
+ arr[key] = [];
+ }
+ arr[key].push(value);
+ };
+
+ /**
+ * Attaches a delegate listener, unless there's already one attached.
+ * @param {!Element} element
+ * @param {string} eventName
+ * @protected
+ */
+
+
+ dom.attachDelegateEvent_ = function attachDelegateEvent_(element, eventName) {
+ var data = metalData.get(element);
+ if (!data.delegating[eventName]) {
+ data.delegating[eventName] = {
+ handle: dom.on(element, eventName, dom.handleDelegateEvent_, !!USE_CAPTURE[eventName]),
+ selectors: {}
+ };
+ }
+ };
+
/**
* Gets the closest element up the tree from the given element (including
* itself) that matches the specified selector, or null if none match.
@@ -1973,25 +2141,43 @@ babelHelpers;
/**
* Listens to the specified event on the given DOM element, but only calls the
- * callback with the event when it triggered by elements that match the given
- * selector.
- * @param {!Element} element The container DOM element to listen to the event on.
+ * given callback listener when it's triggered by elements that match the
+ * given selector or target element.
+ * @param {!Element} element The DOM element the event should be listened on.
* @param {string} eventName The name of the event to listen to.
- * @param {string} selector The selector that matches the child elements that
- * the event should be triggered for.
- * @param {!function(!Object)} callback Function to be called when the event is
- * triggered. It will receive the normalized event object.
- * @return {!DomEventHandle} Can be used to remove the listener.
+ * @param {!Element|string} selectorOrTarget Either an element or css selector
+ * that should match the event for the listener to be triggered.
+ * @param {!function(!Object)} callback Function to be called when the event
+ * is triggered. It will receive the normalized event object.
+ * @param {boolean=} opt_default Optional flag indicating if this is a default
+ * listener. That means that it would only be executed after all non
+ * default listeners, and only if the event isn't prevented via
+ * `preventDefault`.
+ * @return {!EventHandle} Can be used to remove the listener.
*/
- dom.delegate = function delegate(element, eventName, selector, callback) {
+ dom.delegate = function delegate(element, eventName, selectorOrTarget, callback, opt_default) {
var customConfig = dom.customEvents[eventName];
if (customConfig && customConfig.delegate) {
eventName = customConfig.originalEvent;
callback = customConfig.handler.bind(customConfig, callback);
}
- return dom.on(element, eventName, dom.handleDelegateEvent_.bind(null, selector, callback));
+
+ if (opt_default) {
+ // Wrap callback so we don't set property directly on it.
+ callback = callback.bind();
+ callback.defaultListener_ = true;
+ }
+
+ dom.attachDelegateEvent_(element, eventName);
+ if (core.isString(selectorOrTarget)) {
+ dom.addSelectorListener_(element, eventName, selectorOrTarget, callback);
+ } else {
+ dom.addElementListener_(selectorOrTarget, eventName, callback);
+ }
+
+ return new DomDelegatedEventHandle(core.isString(selectorOrTarget) ? element : selectorOrTarget, eventName, callback, core.isString(selectorOrTarget) ? selectorOrTarget : null);
};
/**
@@ -2017,37 +2203,38 @@ babelHelpers;
};
/**
- * This is called when an event is triggered by a delegate listener (see
- * `dom.delegate` for more details).
- * @param {string} selector The selector or element that matches the child
- * elements that the event should be triggered for.
- * @param {!function(!Object)} callback Function to be called when the event
- * is triggered. It will receive the normalized event object.
+ * This is called when an event is triggered by a delegate listener. All
+ * matching listeners of this event type from `target` to `currentTarget` will
+ * be triggered.
* @param {!Event} event The event payload.
* @return {boolean} False if at least one of the triggered callbacks returns
- * false, or true otherwise.
+ * false, or true otherwise.
+ * @protected
*/
- dom.handleDelegateEvent_ = function handleDelegateEvent_(selector, callback, event) {
+ dom.handleDelegateEvent_ = function handleDelegateEvent_(event) {
dom.normalizeDelegateEvent_(event);
+ var currElement = core.isDef(event[NEXT_TARGET]) ? event[NEXT_TARGET] : event.target;
+ var ret = true;
+ var container = event.currentTarget;
+ var limit = event.currentTarget.parentNode;
+ var defFns = [];
- var currentElement = event.target;
- var returnValue = true;
+ while (currElement && currElement !== limit && !event.stopped) {
+ event.delegateTarget = currElement;
+ ret &= dom.triggerMatchedListeners_(container, currElement, event, defFns);
+ currElement = currElement.parentNode;
+ }
- while (currentElement && !event.stopped) {
- if (core.isString(selector) && dom.match(currentElement, selector)) {
- event.delegateTarget = currentElement;
- returnValue &= callback(event);
- }
- if (currentElement === event.currentTarget) {
- break;
- }
- currentElement = currentElement.parentNode;
+ for (var i = 0; i < defFns.length && !event.defaultPrevented; i++) {
+ event.delegateTarget = defFns[i].element;
+ ret &= defFns[i].fn(event);
}
- event.delegateTarget = null;
- return returnValue;
+ event.delegateTarget = null;
+ event[NEXT_TARGET] = limit;
+ return ret;
};
/**
@@ -2337,6 +2524,7 @@ babelHelpers;
dom.stopImmediatePropagation_ = function stopImmediatePropagation_() {
this.stopped = true;
+ this.stoppedImmediate = true;
Event.prototype.stopImmediatePropagation.call(this);
};
@@ -2476,6 +2664,66 @@ babelHelpers;
element.dispatchEvent(eventObj);
};
+ /**
+ * Triggers the given listeners array.
+ * @param {Array} Array of collected values.\n\t * TODO(*): Rethink superclass loop.\n\t */\n\tstatic collectSuperClassesProperty(constructor, propertyName) {\n\t\tvar propertyValues = [constructor[propertyName]];\n\t\twhile (constructor.__proto__ && !constructor.__proto__.isPrototypeOf(Function)) {\n\t\t\tconstructor = constructor.__proto__;\n\t\t\tpropertyValues.push(constructor[propertyName]);\n\t\t}\n\t\treturn propertyValues;\n\t}\n\n\t/**\n\t * Gets the name of the given function. If the current browser doesn't\n\t * support the `name` property, this will calculate it from the function's\n\t * content string.\n\t * @param {!function()} fn\n\t * @return {string}\n\t */\n\tstatic getFunctionName(fn) {\n\t\tif (!fn.name) {\n\t\t\tvar str = fn.toString();\n\t\t\tfn.name = str.substring(9, str.indexOf('('));\n\t\t}\n\t\treturn fn.name;\n\t}\n\n\t/**\n\t * Gets an unique id. If `opt_object` argument is passed, the object is\n\t * mutated with an unique id. Consecutive calls with the same object\n\t * reference won't mutate the object again, instead the current object uid\n\t * returns. See {@link core.UID_PROPERTY}.\n\t * @type {opt_object} Optional object to be mutated with the uid. If not\n\t * specified this method only returns the uid.\n\t * @throws {Error} when invoked to indicate the method should be overridden.\n\t */\n\tstatic getUid(opt_object) {\n\t\tif (opt_object) {\n\t\t\treturn opt_object[core.UID_PROPERTY] ||\n\t\t\t\t(opt_object[core.UID_PROPERTY] = core.uniqueIdCounter_++);\n\t\t}\n\t\treturn core.uniqueIdCounter_++;\n\t}\n\n\t/**\n\t * The identity function. Returns its first argument.\n\t * @param {*=} opt_returnValue The single value that will be returned.\n\t * @return {?} The first argument.\n\t */\n\tstatic identityFunction(opt_returnValue) {\n\t\treturn opt_returnValue;\n\t}\n\n\t/**\n\t * Returns true if the specified value is a boolean.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is boolean.\n\t */\n\tstatic isBoolean(val) {\n\t\treturn typeof val === 'boolean';\n\t}\n\n\t/**\n\t * Returns true if the specified value is not undefined.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is defined.\n\t */\n\tstatic isDef(val) {\n\t\treturn val !== undefined;\n\t}\n\n\t/**\n\t * Returns true if value is not undefined or null.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isDefAndNotNull(val) {\n\t\treturn core.isDef(val) && !core.isNull(val);\n\t}\n\n\t/**\n\t * Returns true if value is a document.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isDocument(val) {\n\t\treturn val && typeof val === 'object' && val.nodeType === 9;\n\t}\n\n\t/**\n\t * Returns true if value is a dom element.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isElement(val) {\n\t\treturn val && typeof val === 'object' && val.nodeType === 1;\n\t}\n\n\t/**\n\t * Returns true if the specified value is a function.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is a function.\n\t */\n\tstatic isFunction(val) {\n\t\treturn typeof val === 'function';\n\t}\n\n\t/**\n\t * Returns true if value is null.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isNull(val) {\n\t\treturn val === null;\n\t}\n\n\t/**\n\t * Returns true if the specified value is a number.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is a number.\n\t */\n\tstatic isNumber(val) {\n\t\treturn typeof val === 'number';\n\t}\n\n\t/**\n\t * Returns true if value is a window.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isWindow(val) {\n\t\treturn val !== null && val === val.window;\n\t}\n\n\t/**\n\t * Returns true if the specified value is an object. This includes arrays\n\t * and functions.\n\t * @param {?} val Variable to test.\n\t * @return {boolean} Whether variable is an object.\n\t */\n\tstatic isObject(val) {\n\t\tvar type = typeof val;\n\t\treturn type === 'object' && val !== null || type === 'function';\n\t}\n\n\t/**\n\t * Returns true if value is a Promise.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isPromise(val) {\n\t\treturn val && typeof val === 'object' && typeof val.then === 'function';\n\t}\n\n\t/**\n\t * Returns true if value is a string.\n\t * @param {*} val\n\t * @return {Boolean}\n\t */\n\tstatic isString(val) {\n\t\treturn typeof val === 'string';\n\t}\n\n\t/**\n\t * Merges the values of a static property a class with the values of that\n\t * property for all its super classes, and stores it as a new static\n\t * property of that class. If the static property already existed, it won't\n\t * be recalculated.\n\t * @param {!function()} constructor Class constructor.\n\t * @param {string} propertyName Property name to be collected.\n\t * @param {function(*, *):*=} opt_mergeFn Function that receives an array filled\n\t * with the values of the property for the current class and all its super classes.\n\t * Should return the merged value to be stored on the current class.\n\t * @return {boolean} Returns true if merge happens, false otherwise.\n\t */\n\tstatic mergeSuperClassesProperty(constructor, propertyName, opt_mergeFn) {\n\t\tvar mergedName = propertyName + '_MERGED';\n\t\tif (constructor.hasOwnProperty(mergedName)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar merged = core.collectSuperClassesProperty(constructor, propertyName);\n\t\tif (opt_mergeFn) {\n\t\t\tmerged = opt_mergeFn(merged);\n\t\t}\n\t\tconstructor[mergedName] = merged;\n\t\treturn true;\n\t}\n\n\t/**\n\t * Null function used for default values of callbacks, etc.\n\t * @return {void} Nothing.\n\t */\n\tstatic nullFunction() {}\n}\n\n/**\n * Unique id property prefix.\n * @type {String}\n * @protected\n */\ncore.UID_PROPERTY = 'core_' + ((Math.random() * 1e9) >>> 0);\n\n/**\n * Counter for unique id.\n * @type {Number}\n * @private\n */\ncore.uniqueIdCounter_ = 1;\n\nexport default core;\n","'use strict';\n\nimport core from '../core';\n\nclass array {\n\t/**\n\t * Checks if the given arrays have the same content.\n\t * @param {!Array<*>} arr1\n\t * @param {!Array<*>} arr2\n\t * @return {boolean}\n\t */\n\tstatic equal(arr1, arr2) {\n\t\tif (arr1.length !== arr2.length) {\n\t\t\treturn false;\n\t\t}\n\t\tfor (var i = 0; i < arr1.length; i++) {\n\t\t\tif (arr1[i] !== arr2[i]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns the first value in the given array that isn't undefined.\n\t * @param {!Array} arr\n\t * @return {*}\n\t */\n\tstatic firstDefinedValue(arr) {\n\t\tfor (var i = 0; i < arr.length; i++) {\n\t\t\tif (arr[i] !== undefined) {\n\t\t\t\treturn arr[i];\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Transforms the input nested array to become flat.\n\t * @param {Array.<*|Array.<*>>} arr Nested array to flatten.\n\t * @param {Array.<*>} opt_output Optional output array.\n\t * @return {Array.<*>} Flat array.\n\t */\n\tstatic flatten(arr, opt_output) {\n\t\tvar output = opt_output || [];\n\t\tfor (var i = 0; i < arr.length; i++) {\n\t\t\tif (Array.isArray(arr[i])) {\n\t\t\t\tarray.flatten(arr[i], output);\n\t\t\t} else {\n\t\t\t\toutput.push(arr[i]);\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t}\n\n\t/**\n\t * Removes the first occurrence of a particular value from an array.\n\t * @param {Array.} arr Array from which to remove value.\n\t * @param {T} obj Object to remove.\n\t * @return {boolean} True if an element was removed.\n\t * @template T\n\t */\n\tstatic remove(arr, obj) {\n\t\tvar i = arr.indexOf(obj);\n\t\tvar rv;\n\t\tif ( (rv = i >= 0) ) {\n\t\t\tarray.removeAt(arr, i);\n\t\t}\n\t\treturn rv;\n\t}\n\n\t/**\n\t * Removes from an array the element at index i\n\t * @param {Array} arr Array or array like object from which to remove value.\n\t * @param {number} i The index to remove.\n\t * @return {boolean} True if an element was removed.\n\t */\n\tstatic removeAt(arr, i) {\n\t\treturn Array.prototype.splice.call(arr, i, 1).length === 1;\n\t}\n\n\t/**\n\t * Slices the given array, just like Array.prototype.slice, but this\n\t * is faster and working on all array-like objects (like arguments).\n\t * @param {!Object} arr Array-like object to slice.\n\t * @param {number} start The index that should start the slice.\n\t * @param {number=} opt_end The index where the slice should end, not\n\t * included in the final array. If not given, all elements after the\n\t * start index will be included.\n\t * @return {!Array}\n\t */\n\tstatic slice(arr, start, opt_end) {\n\t\tvar sliced = [];\n\t\tvar end = core.isDef(opt_end) ? opt_end : arr.length;\n\t\tfor (var i = start; i < end; i++) {\n\t\t\tsliced.push(arr[i]);\n\t\t}\n\t\treturn sliced;\n\t}\n}\n\nexport default array;\n","/*!\n * Polyfill from Google's Closure Library.\n * Copyright 2013 The Closure Library Authors. All Rights Reserved.\n */\n\n'use strict';\n\nvar async = {};\n\n\n/**\n * Throw an item without interrupting the current execution context. For\n * example, if processing a group of items in a loop, sometimes it is useful\n * to report an error while still allowing the rest of the batch to be\n * processed.\n * @param {*} exception\n */\nasync.throwException = function(exception) {\n\t// Each throw needs to be in its own context.\n\tasync.nextTick(function() {\n\t\tthrow exception;\n\t});\n};\n\n\n/**\n * Fires the provided callback just before the current callstack unwinds, or as\n * soon as possible after the current JS execution context.\n * @param {function(this:THIS)} callback\n * @param {THIS=} opt_context Object to use as the \"this value\" when calling\n * the provided function.\n * @template THIS\n */\nasync.run = function(callback, opt_context) {\n\tif (!async.run.workQueueScheduled_) {\n\t\t// Nothing is currently scheduled, schedule it now.\n\t\tasync.nextTick(async.run.processWorkQueue);\n\t\tasync.run.workQueueScheduled_ = true;\n\t}\n\n\tasync.run.workQueue_.push(\n\t\tnew async.run.WorkItem_(callback, opt_context));\n};\n\n\n/** @private {boolean} */\nasync.run.workQueueScheduled_ = false;\n\n\n/** @private {!Array.} */\nasync.run.workQueue_ = [];\n\n/**\n * Run any pending async.run work items. This function is not intended\n * for general use, but for use by entry point handlers to run items ahead of\n * async.nextTick.\n */\nasync.run.processWorkQueue = function() {\n\t// NOTE: additional work queue items may be pushed while processing.\n\twhile (async.run.workQueue_.length) {\n\t\t// Don't let the work queue grow indefinitely.\n\t\tvar workItems = async.run.workQueue_;\n\t\tasync.run.workQueue_ = [];\n\t\tfor (var i = 0; i < workItems.length; i++) {\n\t\t\tvar workItem = workItems[i];\n\t\t\ttry {\n\t\t\t\tworkItem.fn.call(workItem.scope);\n\t\t\t} catch (e) {\n\t\t\t\tasync.throwException(e);\n\t\t\t}\n\t\t}\n\t}\n\n\t// There are no more work items, reset the work queue.\n\tasync.run.workQueueScheduled_ = false;\n};\n\n\n/**\n * @constructor\n * @final\n * @struct\n * @private\n *\n * @param {function()} fn\n * @param {Object|null|undefined} scope\n */\nasync.run.WorkItem_ = function(fn, scope) {\n\t/** @const */\n\tthis.fn = fn;\n\t/** @const */\n\tthis.scope = scope;\n};\n\n\n/**\n * Fires the provided callbacks as soon as possible after the current JS\n * execution context. setTimeout(…, 0) always takes at least 5ms for legacy\n * reasons.\n * @param {function(this:SCOPE)} callback Callback function to fire as soon as\n * possible.\n * @param {SCOPE=} opt_context Object in whose scope to call the listener.\n * @template SCOPE\n */\nasync.nextTick = function(callback, opt_context) {\n\tvar cb = callback;\n\tif (opt_context) {\n\t\tcb = callback.bind(opt_context);\n\t}\n\tcb = async.nextTick.wrapCallback_(cb);\n\t// Introduced and currently only supported by IE10.\n\t// Verify if variable is defined on the current runtime (i.e., node, browser).\n\t// Can't use typeof enclosed in a function (such as core.isFunction) or an\n\t// exception will be thrown when the function is called on an environment\n\t// where the variable is undefined.\n\tif (typeof setImmediate === 'function') {\n\t\tsetImmediate(cb);\n\t\treturn;\n\t}\n\t// Look for and cache the custom fallback version of setImmediate.\n\tif (!async.nextTick.setImmediate_) {\n\t\tasync.nextTick.setImmediate_ = async.nextTick.getSetImmediateEmulator_();\n\t}\n\tasync.nextTick.setImmediate_(cb);\n};\n\n\n/**\n * Cache for the setImmediate implementation.\n * @type {function(function())}\n * @private\n */\nasync.nextTick.setImmediate_ = null;\n\n\n/**\n * Determines the best possible implementation to run a function as soon as\n * the JS event loop is idle.\n * @return {function(function())} The \"setImmediate\" implementation.\n * @private\n */\nasync.nextTick.getSetImmediateEmulator_ = function() {\n\t// Create a private message channel and use it to postMessage empty messages\n\t// to ourselves.\n\tvar Channel;\n\n\t// Verify if variable is defined on the current runtime (i.e., node, browser).\n\t// Can't use typeof enclosed in a function (such as core.isFunction) or an\n\t// exception will be thrown when the function is called on an environment\n\t// where the variable is undefined.\n\tif (typeof MessageChannel === 'function') {\n\t\tChannel = MessageChannel;\n\t}\n\n\t// If MessageChannel is not available and we are in a browser, implement\n\t// an iframe based polyfill in browsers that have postMessage and\n\t// document.addEventListener. The latter excludes IE8 because it has a\n\t// synchronous postMessage implementation.\n\tif (typeof Channel === 'undefined' && typeof window !== 'undefined' &&\n\t\twindow.postMessage && window.addEventListener) {\n\t\t/** @constructor */\n\t\tChannel = function() {\n\t\t\t// Make an empty, invisible iframe.\n\t\t\tvar iframe = document.createElement('iframe');\n\t\t\tiframe.style.display = 'none';\n\t\t\tiframe.src = '';\n\t\t\tdocument.documentElement.appendChild(iframe);\n\t\t\tvar win = iframe.contentWindow;\n\t\t\tvar doc = win.document;\n\t\t\tdoc.open();\n\t\t\tdoc.write('');\n\t\t\tdoc.close();\n\t\t\tvar message = 'callImmediate' + Math.random();\n\t\t\tvar origin = win.location.protocol + '//' + win.location.host;\n\t\t\tvar onmessage = function(e) {\n\t\t\t\t// Validate origin and message to make sure that this message was\n\t\t\t\t// intended for us.\n\t\t\t\tif (e.origin !== origin && e.data !== message) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.port1.onmessage();\n\t\t\t}.bind(this);\n\t\t\twin.addEventListener('message', onmessage, false);\n\t\t\tthis.port1 = {};\n\t\t\tthis.port2 = {\n\t\t\t\tpostMessage: function() {\n\t\t\t\t\twin.postMessage(message, origin);\n\t\t\t\t}\n\t\t\t};\n\t\t};\n\t}\n\tif (typeof Channel !== 'undefined') {\n\t\tvar channel = new Channel();\n\t\t// Use a fifo linked list to call callbacks in the right order.\n\t\tvar head = {};\n\t\tvar tail = head;\n\t\tchannel.port1.onmessage = function() {\n\t\t\thead = head.next;\n\t\t\tvar cb = head.cb;\n\t\t\thead.cb = null;\n\t\t\tcb();\n\t\t};\n\t\treturn function(cb) {\n\t\t\ttail.next = {\n\t\t\t\tcb: cb\n\t\t\t};\n\t\t\ttail = tail.next;\n\t\t\tchannel.port2.postMessage(0);\n\t\t};\n\t}\n\t// Implementation for IE6-8: Script elements fire an asynchronous\n\t// onreadystatechange event when inserted into the DOM.\n\tif (typeof document !== 'undefined' && 'onreadystatechange' in\n\t\tdocument.createElement('script')) {\n\t\treturn function(cb) {\n\t\t\tvar script = document.createElement('script');\n\t\t\tscript.onreadystatechange = function() {\n\t\t\t\t// Clean up and call the callback.\n\t\t\t\tscript.onreadystatechange = null;\n\t\t\t\tscript.parentNode.removeChild(script);\n\t\t\t\tscript = null;\n\t\t\t\tcb();\n\t\t\t\tcb = null;\n\t\t\t};\n\t\t\tdocument.documentElement.appendChild(script);\n\t\t};\n\t}\n\t// Fall back to setTimeout with 0. In browsers this creates a delay of 5ms\n\t// or more.\n\treturn function(cb) {\n\t\tsetTimeout(cb, 0);\n\t};\n};\n\n\n/**\n * Helper function that is overrided to protect callbacks with entry point\n * monitor if the application monitors entry points.\n * @param {function()} callback Callback function to fire as soon as possible.\n * @return {function()} The wrapped callback.\n * @private\n */\nasync.nextTick.wrapCallback_ = function(opt_returnValue) {\n\treturn opt_returnValue;\n};\n\nexport default async;\n","'use strict';\n\n/**\n * Disposable utility. When inherited provides the `dispose` function to its\n * subclass, which is responsible for disposing of any object references\n * when an instance won't be used anymore. Subclasses should override\n * `disposeInternal` to implement any specific disposing logic.\n * @constructor\n */\nclass Disposable {\n\tconstructor() {\n\t\t/**\n\t\t * Flag indicating if this instance has already been disposed.\n\t\t * @type {boolean}\n\t\t * @protected\n\t\t */\n\t\tthis.disposed_ = false;\n\t}\n\n\t/**\n\t * Disposes of this instance's object references. Calls `disposeInternal`.\n\t */\n\tdispose() {\n\t\tif (!this.disposed_) {\n\t\t\tthis.disposeInternal();\n\t\t\tthis.disposed_ = true;\n\t\t}\n\t}\n\n\t/**\n\t * Subclasses should override this method to implement any specific\n\t * disposing logic (like clearing references and calling `dispose` on other\n\t * disposables).\n\t */\n\tdisposeInternal() {}\n\n\t/**\n\t * Checks if this instance has already been disposed.\n\t * @return {boolean}\n\t */\n\tisDisposed() {\n\t\treturn this.disposed_;\n\t}\n}\n\nexport default Disposable;\n","'use strict';\n\nclass object {\n\t/**\n\t * Copies all the members of a source object to a target object.\n\t * @param {Object} target Target object.\n\t * @param {...Object} var_args The objects from which values will be copied.\n\t * @return {Object} Returns the target object reference.\n\t */\n\tstatic mixin(target) {\n\t\tvar key, source;\n\t\tfor (var i = 1; i < arguments.length; i++) {\n\t\t\tsource = arguments[i];\n\t\t\tfor (key in source) {\n\t\t\t\ttarget[key] = source[key];\n\t\t\t}\n\t\t}\n\t\treturn target;\n\t}\n\n\t/**\n\t * Returns an object based on its fully qualified external name.\n\t * @param {string} name The fully qualified name.\n\t * @param {object=} opt_obj The object within which to look; default is\n\t * window.\n\t * @return {?} The value (object or primitive) or, if not found, undefined.\n\t */\n\tstatic getObjectByName(name, opt_obj) {\n\t\tvar scope = opt_obj || window;\n\t\tvar parts = name.split('.');\n\t\treturn parts.reduce((part, key) => part[key], scope);\n\t}\n\n\t/**\n\t * Returns a new object with the same keys as the given one, but with\n\t * their values set to the return values of the specified function.\n\t * @param {!Object} obj\n\t * @param {!function(string, *)} fn\n\t * @return {!Object}\n\t */\n\tstatic map(obj, fn) {\n\t\tvar mappedObj = {};\n\t\tvar keys = Object.keys(obj);\n\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\tmappedObj[keys[i]] = fn(keys[i], obj[keys[i]]);\n\t\t}\n\t\treturn mappedObj;\n\t}\n\n\t/**\n\t * Checks if the two given objects are equal. This is done via a shallow\n\t * check, including only the keys directly contained by the 2 objects.\n\t * @return {boolean}\n\t */\n\tstatic shallowEqual(obj1, obj2) {\n\t\tif (obj1 === obj2) {\n\t\t\treturn true;\n\t\t}\n\n\t\tvar keys1 = Object.keys(obj1);\n\t\tvar keys2 = Object.keys(obj2);\n\t\tif (keys1.length !== keys2.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (var i = 0; i < keys1.length; i++) {\n\t\t\tif (obj1[keys1[i]] !== obj2[keys1[i]]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n\nexport default object;\n","'use strict';\n\nclass string {\n\t/**\n\t * Removes the breaking spaces from the left and right of the string and\n\t * collapses the sequences of breaking spaces in the middle into single spaces.\n\t * The original and the result strings render the same way in HTML.\n\t * @param {string} str A string in which to collapse spaces.\n\t * @return {string} Copy of the string with normalized breaking spaces.\n\t */\n\tstatic collapseBreakingSpaces(str) {\n\t\treturn str.replace(/[\\t\\r\\n ]+/g, ' ').replace(/^[\\t\\r\\n ]+|[\\t\\r\\n ]+$/g, '');\n\t}\n\n\t/**\n\t* Escapes characters in the string that are not safe to use in a RegExp.\n\t* @param {*} str The string to escape. If not a string, it will be casted\n\t* to one.\n\t* @return {string} A RegExp safe, escaped copy of {@code s}.\n\t*/\n\tstatic escapeRegex(str) {\n\t\treturn String(str)\n\t\t\t.replace(/([-()\\[\\]{}+?*.$\\^|,:#>}\n\t\t * @protected\n\t\t */\n\t\tthis.events_ = [];\n\n\t\t/**\n\t\t * The maximum number of listeners allowed for each event type. If the number\n\t\t * becomes higher than the max, a warning will be issued.\n\t\t * @type {number}\n\t\t * @protected\n\t\t */\n\t\tthis.maxListeners_ = 10;\n\n\t\t/**\n\t\t * Configuration option which determines if an event facade should be sent\n\t\t * as a param of listeners when emitting events. If set to true, the facade\n\t\t * will be passed as the first argument of the listener.\n\t\t * @type {boolean}\n\t\t * @protected\n\t\t */\n\t\tthis.shouldUseFacade_ = false;\n\t}\n\n\t/**\n\t * Adds a listener to the end of the listeners array for the specified events.\n\t * @param {!(Array|string)} events\n\t * @param {!Function} listener\n\t * @param {boolean} opt_default Flag indicating if this listener is a default\n\t * action for this event. Default actions are run last, and only if no previous\n\t * listener call `preventDefault()` on the received event facade.\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\taddListener(events, listener, opt_default) {\n\t\tthis.validateListener_(listener);\n\n\t\tevents = this.normalizeEvents_(events);\n\t\tfor (var i = 0; i < events.length; i++) {\n\t\t\tthis.addSingleListener_(events[i], listener, opt_default);\n\t\t}\n\n\t\treturn new EventHandle(this, events, listener);\n\t}\n\n\t/**\n\t * Adds a listener to the end of the listeners array for a single event.\n\t * @param {string} event\n\t * @param {!Function} listener\n\t * @param {boolean} opt_default Flag indicating if this listener is a default\n\t * action for this event. Default actions are run last, and only if no previous\n\t * listener call `preventDefault()` on the received event facade.\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t * @param {Function=} opt_origin The original function that was added as a\n\t * listener, if there is any.\n\t * @protected\n\t */\n\taddSingleListener_(event, listener, opt_default, opt_origin) {\n\t\tthis.emit('newListener', event, listener);\n\n\t\tif (!this.events_[event]) {\n\t\t\tthis.events_[event] = [];\n\t\t}\n\t\tthis.events_[event].push({\n\t\t\tdefault: opt_default,\n\t\t\tfn: listener,\n\t\t\torigin: opt_origin\n\t\t});\n\n\t\tvar listeners = this.events_[event];\n\t\tif (listeners.length > this.maxListeners_ && !listeners.warned) {\n\t\t\tconsole.warn(\n\t\t\t\t'Possible EventEmitter memory leak detected. %d listeners added ' +\n\t\t\t\t'for event %s. Use emitter.setMaxListeners() to increase limit.',\n\t\t\t\tlisteners.length,\n\t\t\t\tevent\n\t\t\t);\n\t\t\tlisteners.warned = true;\n\t\t}\n\t}\n\n\t/**\n\t * Disposes of this instance's object references.\n\t * @override\n\t */\n\tdisposeInternal() {\n\t\tthis.events_ = [];\n\t}\n\n\t/**\n\t * Execute each of the listeners in order with the supplied arguments.\n\t * @param {string} event\n\t * @param {*} opt_args [arg1], [arg2], [...]\n\t * @return {boolean} Returns true if event had listeners, false otherwise.\n\t */\n\temit(event) {\n\t\tvar args = array.slice(arguments, 1);\n\t\tvar listeners = (this.events_[event] || []).concat();\n\n\t\tvar facade;\n\t\tif (this.getShouldUseFacade()) {\n\t\t\tfacade = {\n\t\t\t\tpreventDefault: function() {\n\t\t\t\t\tfacade.preventedDefault = true;\n\t\t\t\t},\n\t\t\t\ttarget: this,\n\t\t\t\ttype: event\n\t\t\t};\n\t\t\targs.push(facade);\n\t\t}\n\n\t\tvar defaultListeners = [];\n\t\tfor (var i = 0; i < listeners.length; i++) {\n\t\t\tif (listeners[i].default) {\n\t\t\t\tdefaultListeners.push(listeners[i]);\n\t\t\t} else {\n\t\t\t\tlisteners[i].fn.apply(this, args);\n\t\t\t}\n\t\t}\n\t\tif (!facade || !facade.preventedDefault) {\n\t\t\tfor (var j = 0; j < defaultListeners.length; j++) {\n\t\t\t\tdefaultListeners[j].fn.apply(this, args);\n\t\t\t}\n\t\t}\n\n\n\t\tif (event !== '*') {\n\t\t\tthis.emit.apply(this, ['*', event].concat(args));\n\t\t}\n\n\t\treturn listeners.length > 0;\n\t}\n\n\t/**\n\t * Gets the configuration option which determines if an event facade should\n\t * be sent as a param of listeners when emitting events. If set to true, the\n\t * facade will be passed as the first argument of the listener.\n\t * @return {boolean}\n\t */\n\tgetShouldUseFacade() {\n\t\treturn this.shouldUseFacade_;\n\t}\n\n\t/**\n\t * Returns an array of listeners for the specified event.\n\t * @param {string} event\n\t * @return {Array} Array of listeners.\n\t */\n\tlisteners(event) {\n\t\treturn (this.events_[event] || []).map(listener => listener.fn);\n\t}\n\n\t/**\n\t * Adds a listener that will be invoked a fixed number of times for the\n\t * events. After each event is triggered the specified amount of times, the\n\t * listener is removed for it.\n\t * @param {!(Array|string)} events\n\t * @param {number} amount The amount of times this event should be listened\n\t * to.\n\t * @param {!Function} listener\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\tmany(events, amount, listener) {\n\t\tevents = this.normalizeEvents_(events);\n\t\tfor (var i = 0; i < events.length; i++) {\n\t\t\tthis.many_(events[i], amount, listener);\n\t\t}\n\n\t\treturn new EventHandle(this, events, listener);\n\t}\n\n\t/**\n\t * Adds a listener that will be invoked a fixed number of times for a single\n\t * event. After the event is triggered the specified amount of times, the\n\t * listener is removed.\n\t * @param {string} event\n\t * @param {number} amount The amount of times this event should be listened\n\t * to.\n\t * @param {!Function} listener\n\t * @protected\n\t */\n\tmany_(event, amount, listener) {\n\t\tvar self = this;\n\n\t\tif (amount <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tfunction handlerInternal() {\n\t\t\tif (--amount === 0) {\n\t\t\t\tself.removeListener(event, handlerInternal);\n\t\t\t}\n\t\t\tlistener.apply(self, arguments);\n\t\t}\n\n\t\tself.addSingleListener_(event, handlerInternal, false, listener);\n\t}\n\n\t/**\n\t * Checks if a listener object matches the given listener function. To match,\n\t * it needs to either point to that listener or have it as its origin.\n\t * @param {!Object} listenerObj\n\t * @param {!Function} listener\n\t * @return {boolean}\n\t * @protected\n\t */\n\tmatchesListener_(listenerObj, listener) {\n\t\treturn listenerObj.fn === listener ||\n\t\t\t(listenerObj.origin && listenerObj.origin === listener);\n\t}\n\n\t/**\n\t * Converts the parameter to an array if only one event is given.\n\t * @param {!(Array|string)} events\n\t * @return {!Array}\n\t * @protected\n\t */\n\tnormalizeEvents_(events) {\n\t\treturn core.isString(events) ? [events] : events;\n\t}\n\n\t/**\n\t * Removes a listener for the specified events.\n\t * Caution: changes array indices in the listener array behind the listener.\n\t * @param {!(Array|string)} events\n\t * @param {!Function} listener\n\t * @return {!Object} Returns emitter, so calls can be chained.\n\t */\n\toff(events, listener) {\n\t\tthis.validateListener_(listener);\n\n\t\tevents = this.normalizeEvents_(events);\n\t\tfor (var i = 0; i < events.length; i++) {\n\t\t\tvar listenerObjs = this.events_[events[i]] || [];\n\t\t\tthis.removeMatchingListenerObjs_(listenerObjs, listener);\n\t\t}\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds a listener to the end of the listeners array for the specified events.\n\t * @param {!(Array|string)} events\n\t * @param {!Function} listener\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\ton() {\n\t\treturn this.addListener.apply(this, arguments);\n\t}\n\n\t/**\n\t * Adds a one time listener for the events. This listener is invoked only the\n\t * next time each event is fired, after which it is removed.\n\t * @param {!(Array|string)} events\n\t * @param {!Function} listener\n\t * @return {!EventHandle} Can be used to remove the listener.\n\t */\n\tonce(events, listener) {\n\t\treturn this.many(events, 1, listener);\n\t}\n\n\t/**\n\t * Removes all listeners, or those of the specified events. It's not a good\n\t * idea to remove listeners that were added elsewhere in the code,\n\t * especially when it's on an emitter that you didn't create.\n\t * @param {(Array|string)=} opt_events\n\t * @return {!Object} Returns emitter, so calls can be chained.\n\t */\n\tremoveAllListeners(opt_events) {\n\t\tif (opt_events) {\n\t\t\tvar events = this.normalizeEvents_(opt_events);\n\t\t\tfor (var i = 0; i < events.length; i++) {\n\t\t\t\tthis.events_[events[i]] = null;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.events_ = {};\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes all listener objects from the given array that match the given\n\t * listener function.\n\t * @param {!Array.