From 04db211177d7d7950018881eaf34f08d698e3f06 Mon Sep 17 00:00:00 2001 From: Mark David Avery Date: Thu, 30 May 2019 12:10:51 -0700 Subject: [PATCH] fix(loading-route-styleNamespaces): we needed to hack around and add in some extra hooks to take care of loading routes --- addon/initializers/route-styles.js | 13 ++++++-- addon/instance-initializers/route-styles.js | 30 +++++++++++-------- addon/utils/init-route-styles.js | 20 +++++++------ tests/acceptance/loading-state-test.js | 23 ++++++++++++++ .../dummy/app/loading-state/base/styles.scss | 3 ++ .../dummy/app/loading-state/base/template.hbs | 2 ++ .../loading-state/waiting-loading/styles.scss | 3 ++ .../waiting-loading/template.hbs | 1 + .../dummy/app/loading-state/waiting/route.js | 9 ++++++ .../app/loading-state/waiting/styles.scss | 3 ++ .../app/loading-state/waiting/template.hbs | 1 + tests/dummy/app/router.js | 5 ++++ 12 files changed, 89 insertions(+), 24 deletions(-) create mode 100644 tests/acceptance/loading-state-test.js create mode 100644 tests/dummy/app/loading-state/base/styles.scss create mode 100644 tests/dummy/app/loading-state/base/template.hbs create mode 100644 tests/dummy/app/loading-state/waiting-loading/styles.scss create mode 100644 tests/dummy/app/loading-state/waiting-loading/template.hbs create mode 100644 tests/dummy/app/loading-state/waiting/route.js create mode 100644 tests/dummy/app/loading-state/waiting/styles.scss create mode 100644 tests/dummy/app/loading-state/waiting/template.hbs diff --git a/addon/initializers/route-styles.js b/addon/initializers/route-styles.js index 8b422ad..29bc42f 100644 --- a/addon/initializers/route-styles.js +++ b/addon/initializers/route-styles.js @@ -6,8 +6,17 @@ import initRouteStyles from '../utils/init-route-styles'; Router.reopen({ didTransition(routes) { this._super(...arguments); - initRouteStyles(getOwner(this), routes); - } + initRouteStyles(getOwner(this), routes.map(route => route.name)); + }, + + intermediateTransitionTo() { + this._super(...arguments); + const routes = this._routerMicrolib.currentHandlerInfos; + const routeNames = routes.map(route => route._handler.routeName.replace(/_loading$/, '-loading')) + + initRouteStyles(getOwner(this), routeNames); + }, + }); export function initialize() {} diff --git a/addon/instance-initializers/route-styles.js b/addon/instance-initializers/route-styles.js index 68e75f4..2c86cbf 100644 --- a/addon/instance-initializers/route-styles.js +++ b/addon/instance-initializers/route-styles.js @@ -4,24 +4,28 @@ import initRouteStyles from '../utils/init-route-styles'; export function initialize(appInstance) { let router = appInstance.lookup('service:router'); router.on('routeDidChange', function(transition) { - let routeInfos = []; - let to = transition.to; - - while (to) { - routeInfos.push(to); - to = to.parent; - } - - routeInfos.reverse(); + initRouteStyles(appInstance, nestedRouteNames(transition.to)); + }); - if (routeInfos.length === 0) { - routeInfos = transition.routeInfos; + router.on('routeWillChange', function(transition) { + if (/_loading$/.test(transition.to.name) && transition.isActive) { + const routeNames = nestedRouteNames(transition.to) + // loading route names are set with an _loading even though + // their path is -loading + .map(name => name.replace(/_loading$/, '-loading')); + initRouteStyles(appInstance, routeNames); } - - initRouteStyles(appInstance, routeInfos); }); } +function nestedRouteNames(route, routeNames = []) { + routeNames.push(route.name); + if (route.parent) { + return nestedRouteNames(route.parent, routeNames); + } + return routeNames; +} + export default { initialize }; diff --git a/addon/utils/init-route-styles.js b/addon/utils/init-route-styles.js index af2ecca..4f2a8bf 100644 --- a/addon/utils/init-route-styles.js +++ b/addon/utils/init-route-styles.js @@ -1,16 +1,18 @@ import podNames from 'ember-component-css/pod-names'; -export default function initRouteStyles(owner, routes) { +export default function initRouteStyles(owner, routeNames) { const classes = []; - for (let i = 0; i < routes.length; i++) { - let route = routes[i]; - let currentPath = route.name.replace(/\./g, '/'); + for (let i = 0; i < routeNames.length; i++) { + const routeName = routeNames[i]; + const styleNamespace = podNames[routeName.replace(/\./g, '/')]; - if (podNames[currentPath]) { - owner - .lookup(`controller:${route.name}`) - .set('styleNamespace', podNames[currentPath]); - classes.push(podNames[currentPath]); + if (styleNamespace) { + classes.push(styleNamespace); + + const controller = owner.lookup(`controller:${routeName}`); + if (controller) { + controller.set('styleNamespace', styleNamespace); + } } } diff --git a/tests/acceptance/loading-state-test.js b/tests/acceptance/loading-state-test.js new file mode 100644 index 0000000..10bb710 --- /dev/null +++ b/tests/acceptance/loading-state-test.js @@ -0,0 +1,23 @@ +import { test } from 'qunit'; +import moduleForAcceptance from '../../tests/helpers/module-for-acceptance'; +import { scheduleOnce } from '@ember/runloop'; + +moduleForAcceptance(`Acceptance | Unique Paths`); + +test('loading state is styled', function(assert) { + visit(`/loading-state/base`); + + andThen(function() { + click(find('a')); + assert.equal(find('h1').css('color'), 'rgb(0, 0, 14)'); + + scheduleOnce('afterRender', function() { + assert.equal(find('h2').css('color'), 'rgb(1, 0, 13)'); + }); + + }); + + andThen(function() { + assert.equal(find('h3').css('color'), 'rgb(0, 0, 13)'); + }) +}); diff --git a/tests/dummy/app/loading-state/base/styles.scss b/tests/dummy/app/loading-state/base/styles.scss new file mode 100644 index 0000000..7919e30 --- /dev/null +++ b/tests/dummy/app/loading-state/base/styles.scss @@ -0,0 +1,3 @@ +h1 { + color: rgb(0, 0, 14); +} diff --git a/tests/dummy/app/loading-state/base/template.hbs b/tests/dummy/app/loading-state/base/template.hbs new file mode 100644 index 0000000..94fb6d9 --- /dev/null +++ b/tests/dummy/app/loading-state/base/template.hbs @@ -0,0 +1,2 @@ +

base

+{{link-to "waiting" "loading-state.waiting"}} diff --git a/tests/dummy/app/loading-state/waiting-loading/styles.scss b/tests/dummy/app/loading-state/waiting-loading/styles.scss new file mode 100644 index 0000000..587ca11 --- /dev/null +++ b/tests/dummy/app/loading-state/waiting-loading/styles.scss @@ -0,0 +1,3 @@ +h2 { + color: rgb(1, 0, 13); +} diff --git a/tests/dummy/app/loading-state/waiting-loading/template.hbs b/tests/dummy/app/loading-state/waiting-loading/template.hbs new file mode 100644 index 0000000..eeb0cac --- /dev/null +++ b/tests/dummy/app/loading-state/waiting-loading/template.hbs @@ -0,0 +1 @@ +

loading

diff --git a/tests/dummy/app/loading-state/waiting/route.js b/tests/dummy/app/loading-state/waiting/route.js new file mode 100644 index 0000000..84d99d8 --- /dev/null +++ b/tests/dummy/app/loading-state/waiting/route.js @@ -0,0 +1,9 @@ +import Route from '@ember/routing/route'; +import { later } from '@ember/runloop'; +import RSVP from 'rsvp'; + +export default Route.extend({ + model() { + return new RSVP.Promise(resolve => later(resolve, 500)); + } +}); diff --git a/tests/dummy/app/loading-state/waiting/styles.scss b/tests/dummy/app/loading-state/waiting/styles.scss new file mode 100644 index 0000000..10c07d0 --- /dev/null +++ b/tests/dummy/app/loading-state/waiting/styles.scss @@ -0,0 +1,3 @@ +h3 { + color: rgb(0, 0, 13); +} diff --git a/tests/dummy/app/loading-state/waiting/template.hbs b/tests/dummy/app/loading-state/waiting/template.hbs new file mode 100644 index 0000000..53e6102 --- /dev/null +++ b/tests/dummy/app/loading-state/waiting/template.hbs @@ -0,0 +1 @@ +

loaded

diff --git a/tests/dummy/app/router.js b/tests/dummy/app/router.js index 89048ed..31e5e29 100644 --- a/tests/dummy/app/router.js +++ b/tests/dummy/app/router.js @@ -38,6 +38,11 @@ Router.map(function() { this.route('scss'); this.route('less'); }); + + this.route('loading-state', function() { + this.route('base'); + this.route('waiting'); + }); }); export default Router;