From 0940eb46cba43f50505a9003503452d11bacf0dd Mon Sep 17 00:00:00 2001 From: Jason Chambers Date: Mon, 4 May 2015 14:23:09 +0700 Subject: [PATCH 1/2] Add bubbling core-signal events in addition to element based events In order to make supporting elements, access to the app-router events is needed. Sending core-signal events allows elements that are ignorant of the rest of the application still respond meaningfully to these events. This is needed for elements such as page tracking, comment plug-ins where the provider requires a singleton call, or other sitewide changes based on route changes. --- src/app-router.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/app-router.js b/src/app-router.js index f4aa7e2..955978d 100644 --- a/src/app-router.js +++ b/src/app-router.js @@ -166,17 +166,19 @@ } }; - // fire(type, detail, node) - Fire a new CustomEvent(type, detail) on the node + // fire(type, detail, node, bubble) - Fire a new CustomEvent(type, detail) on the node + // + // If bubble is true (default false if undefined) then the event will bubble // // listen with document.querySelector('app-router').addEventListener(type, function(event) { // event.detail, event.preventDefault() // }) - function fire(type, detail, node) { + function fire(type, detail, node, bubble) { // create a CustomEvent the old way for IE9/10 support var event = document.createEvent('CustomEvent'); // initCustomEvent(type, bubbles, cancelable, detail) - event.initCustomEvent(type, false, true, detail); + event.initCustomEvent(type, !!bubble, true, detail); // returns false when event.preventDefault() is called, true otherwise return node.dispatchEvent(event); @@ -200,6 +202,7 @@ if (!fire('state-change', eventDetail, router)) { return; } + fire('core-signal', {name: 'state-change', data: eventDetail}, router, true); // find the first matching route var route = router.firstElementChild; @@ -212,6 +215,7 @@ } fire('not-found', eventDetail, router); + fire('core-signal', {name: 'not-found', data: eventDetail}, router, true); } // Activate the route @@ -237,6 +241,7 @@ if (!fire('activate-route-start', eventDetail, route)) { return; } + fire('core-signal', {name: 'activate-route-start', data: eventDetail}, router, true); // keep track of the route currently being loaded router.loadingRoute = route; @@ -275,6 +280,7 @@ fire('activate-route-end', eventDetail, router); fire('activate-route-end', eventDetail, eventDetail.route); + fire('core-signal', {name: 'activate-route-end', data: eventDetail}, router, true); } // Import and activate a custom element or template @@ -361,6 +367,7 @@ eventDetail.model = model; fire('before-data-binding', eventDetail, router); fire('before-data-binding', eventDetail, eventDetail.route); + fire('core-signal', {name: 'before-data-binding', data: eventDetail}, router, true); return eventDetail.model; } @@ -414,6 +421,7 @@ fire('activate-route-end', eventDetail, router); fire('activate-route-end', eventDetail, eventDetail.route); + fire('core-signal', {name: 'activate-route-end', data: eventDetail}, router, true); } // Remove the route's content From e12b73c494b93a986f0a07bd0fdc7b701ca3893f Mon Sep 17 00:00:00 2001 From: Jason Chambers Date: Mon, 4 May 2015 14:23:19 +0700 Subject: [PATCH 2/2] Build result from: Add bubbling core-signal events in addition to element based events --- app-router.html | 2 +- app-router.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app-router.html b/app-router.html index 1f31905..3da8280 100644 --- a/app-router.html +++ b/app-router.html @@ -1,4 +1,4 @@ diff --git a/app-router.js b/app-router.js index 0676214..40c3817 100644 --- a/app-router.js +++ b/app-router.js @@ -1,2 +1,2 @@ // @license Copyright (C) 2015 Erik Ringsmuth - MIT license -!function(t,e){function a(t,a,i){var r=e.createEvent("CustomEvent");return r.initCustomEvent(t,!1,!0,a),i.dispatchEvent(r)}function i(e){var i=m.parseUrl(t.location.href,e.getAttribute("mode"));if(i.hash!==A.hash&&i.path===A.path&&i.search===A.search&&i.isHashPath===A.isHashPath)return g(i.hash),void 0;A=i;var n={path:i.path};if(a("state-change",n,e)){for(var s=e.firstElementChild;s;){if("APP-ROUTE"===s.tagName&&m.testRoute(s.getAttribute("path"),i.path,e.getAttribute("trailingSlash"),s.hasAttribute("regex")))return r(e,s,i),void 0;s=s.nextSibling}a("not-found",n,e)}}function r(t,e,i){if(e.hasAttribute("redirect"))return t.go(e.getAttribute("redirect"),{replace:!0}),void 0;if(e!==t.activeRoute||"noop"!==e.getAttribute("onUrlChange")){var r={path:i.path,route:e,oldRoute:t.activeRoute};a("activate-route-start",r,t)&&a("activate-route-start",r,e)&&(t.loadingRoute=e,e===t.activeRoute&&"updateModel"===e.getAttribute("onUrlChange")?n(t,e,i,r):e.hasAttribute("import")?s(t,e.getAttribute("import"),e,i,r):e.hasAttribute("element")?u(t,e.getAttribute("element"),e,i,r):e.firstElementChild&&"TEMPLATE"===e.firstElementChild.tagName&&(e.isInlineTemplate=!0,h(t,e.firstElementChild,e,i,r)))}}function n(t,e,i,r){var n=l(t,e,i,r);e.hasAttribute("template")||e.isInlineTemplate?c(e.lastElementChild.templateInstance.model,n):c(e.firstElementChild,n),a("activate-route-end",r,t),a("activate-route-end",r,r.route)}function s(t,a,i,r,n){function s(){u.loaded=!0,o(t,u,a,i,r,n)}var u;b.hasOwnProperty(a)?(u=b[a],u.loaded?o(t,u,a,i,r,n):u.addEventListener("load",s)):(u=e.createElement("link"),u.setAttribute("rel","import"),u.setAttribute("href",a),u.setAttribute("async","async"),u.addEventListener("load",s),u.loaded=!1,e.head.appendChild(u),b[a]=u)}function o(t,e,a,i,r,n){if(i.importLink=e,i===t.loadingRoute)if(i.hasAttribute("template")){var s,o=i.getAttribute("template");s=o?e.import.getElementById(o):e.import.querySelector("template"),h(t,s,i,r,n)}else u(t,i.getAttribute("element")||a.split("/").slice(-1)[0].replace(".html",""),i,r,n)}function u(t,a,i,r,n){var s=e.createElement(a),o=l(t,i,r,n);c(s,o),p(t,s,r,n)}function h(t,a,i,r,n){var s;if("createInstance"in a){var o=l(t,i,r,n);s=a.createInstance(o)}else s=e.importNode(a.content,!0);p(t,s,r,n)}function l(t,e,i,r){var n=m.routeArguments(e.getAttribute("path"),i.path,i.search,e.hasAttribute("regex"),"auto"===t.getAttribute("typecast"));return(e.hasAttribute("bindRouter")||t.hasAttribute("bindRouter"))&&(n.router=t),r.model=n,a("before-data-binding",r,t),a("before-data-binding",r,r.route),r.model}function c(t,e){for(var a in e)e.hasOwnProperty(a)&&(t[a]=e[a])}function p(t,e,i,r){d(t.previousRoute),t.previousRoute=t.activeRoute,t.activeRoute=t.loadingRoute,t.loadingRoute=null,t.previousRoute&&t.previousRoute.removeAttribute("active"),t.activeRoute.setAttribute("active","active"),t.hasAttribute("core-animated-pages")&&r.route!==r.oldRoute||d(t.previousRoute),t.activeRoute.appendChild(e),t.hasAttribute("core-animated-pages")&&(t.coreAnimatedPages.selected=t.activeRoute.getAttribute("path")),i.hash&&!t.hasAttribute("core-animated-pages")&&g(i.hash),a("activate-route-end",r,t),a("activate-route-end",r,r.route)}function d(t){if(t){var e=t.firstChild;for(t.isInlineTemplate&&(e=t.querySelector("template").nextSibling);e;){var a=e;e=e.nextSibling,t.removeChild(a)}}}function g(t){t&&setTimeout(function(){var a=e.querySelector("html /deep/ "+t)||e.querySelector('html /deep/ [name="'+t.substring(1)+'"]');a&&a.scrollIntoView&&a.scrollIntoView(!0)},0)}function v(t,e,a,i,r){var n=t[e],s=a[i];if("**"===n&&e===t.length-1)return!0;if("undefined"==typeof n||"undefined"==typeof s)return n===s;if(n===s||"*"===n||":"===n.charAt(0))return":"===n.charAt(0)&&"undefined"!=typeof r&&(r[n.substring(1)]=a[i]),v(t,e+1,a,i+1,r);if("**"===n)for(var o=i;o