Skip to content

Commit

Permalink
Normalize referrer and lookupString, add config flag
Browse files Browse the repository at this point in the history
* The referrer from Ember is not an absolute specifier. Do some string
  munging to clean it up. We would like this to be a build step
  on Ember template compilation at some point.
* Ember tries to namespace components with `components/` as a specifier
  namespace. Drop that, since MU rules say to look in the components
  collection anyway.
* Resolve with only a bare type and a referrer to look up route
  templates.
* Bump @glimmer/resolver
  • Loading branch information
iezer authored and mixonic committed Jul 2, 2017
1 parent d153cc8 commit 5f425d6
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 44 deletions.
7 changes: 1 addition & 6 deletions mu-trees/addon/ember-config.js
Expand Up @@ -29,12 +29,7 @@ export default function generateConfig(name) {
router: { definitiveCollection: 'main' },
serializer: { definitiveCollection: 'models' },
service: { definitiveCollection: 'services' },
template: {
definitiveCollection: 'routes',
fallbackCollectionPrefixes: {
'components': 'components'
}
},
template: { definitiveCollection: 'components' },
transform: { definitiveCollection: 'transforms' },
view: { definitiveCollection: 'views' },
'-view-registry': { definitiveCollection: 'main' },
Expand Down
64 changes: 39 additions & 25 deletions mu-trees/addon/resolvers/glimmer-wrapper/index.js
Expand Up @@ -15,6 +15,8 @@ const Resolver = DefaultResolver.extend({
init() {
this._super(...arguments);

this._configRootName = this.config.app.rootName || 'app';

if (!this.glimmerModuleRegistry) {
this.glimmerModuleRegistry = new RequireJSRegistry(this.config, 'src');
}
Expand All @@ -24,38 +26,50 @@ const Resolver = DefaultResolver.extend({

normalize: null,

resolve(lookupString) {
/*
* Ember paritals are looked up as templates. Here we replace the template
* resolution with a partial resolute when appropriate. Try to keep this
* code as "pay-go" as possible.
*/
resolve(lookupString, referrer) {

if (lookupString.indexOf('template:') === 0) {
lookupString = this._templateToPartial(lookupString);
}
return this._resolve(lookupString);
},
if (lookupString.indexOf('template:components/') === 0) {
/*
* Ember components require their lookupString to be massaged. Make this
* as "pay-go" as possible.
*/
if (referrer) {
// make absolute
let parts = referrer.split(':src/ui/');
referrer = `${parts[0]}:/${this._configRootName}/${parts[1]}`;
referrer = referrer.split('/template.hbs')[0];
}

_resolve(lookupString) {
return this._glimmerResolver.resolve(lookupString);
},
lookupString = lookupString.replace('components/', '');
} else if (lookupString.indexOf('template:') === 0) {
/*
* Ember partials are looked up as templates. Here we replace the template
* resolution with a partial resolute when appropriate. Try to keep this
* code as "pay-go" as possible.
*/
let match = TEMPLATE_TO_PARTIAL.exec(lookupString);
if (match) {
let namespace = match[1] || '';
let name = match[2];

/*
* templates may actually be partial lookups, so consider them as possibly
* such and return the correct lookupString.
*/
_templateToPartial(lookupString) {
let match = TEMPLATE_TO_PARTIAL.exec(lookupString);
if (!match) {
return lookupString;
lookupString = `partial:${namespace}${name}`;
} else {
if (referrer) {
throw new Error(`Cannot look up a route template ${lookupString} with a referrer`);
}
let parts = lookupString.split(':');
lookupString = `template`;
referrer = `route:/${this._configRootName}/routes/${parts[1]}`;
}
}

let namespace = match[1] || '';
let name = match[2];
return this._resolve(lookupString, referrer);
},

return `partial:${namespace}${name}`;
_resolve(lookupString, referrer) {
return this._glimmerResolver.resolve(lookupString, referrer);
}

});

export default Resolver;
7 changes: 1 addition & 6 deletions mu-trees/tests/unit/module-registries/requirejs-test.js
Expand Up @@ -12,12 +12,7 @@ export let config = {
service: { definitiveCollection: 'services' },
route: { definitiveCollection: 'routes' },
router: { definitiveCollection: 'main' },
template: {
definitiveCollection: 'routes',
fallbackCollectionPrefixes: {
'components': 'components'
}
}
template: { definitiveCollection: 'components' }
},
collections: {
'main': {
Expand Down
156 changes: 153 additions & 3 deletions mu-trees/tests/unit/resolvers/glimmer-wrapper/basic-test.js
Expand Up @@ -288,9 +288,14 @@ test('Can not resolve a top level template of a non-definitive type', function(a
});

assert.equal(
resolver.resolve('template:my-input', 'template:/app/routes/posts'),
resolver.resolve('template:components/my-input', 'template:/app/routes/posts'),
undefined,
'relative module specifier with source resolved'
'route collection module not resolved'
);
assert.equal(
resolver.resolve('template:components/my-input', 'template:src/ui/routes/posts'),
undefined,
'route collection module not resolved'
);
});

Expand Down Expand Up @@ -320,7 +325,42 @@ test('Can resolve a top level template of a definitive type', function(assert) {
});

assert.equal(
resolver.resolve('template:my-input', 'template:/app/routes/posts'),
resolver.resolve('template:components/my-input', 'template:/app/routes/posts'),
template,
'relative module specifier with source resolved'
);
assert.equal(
resolver.resolve('template:components/my-input', 'template:src/ui/routes/posts'),
template,
'relative module specifier with source resolved'
);
});

test('Can resolve component template', function(assert) {
let template = {};
let resolver = this.resolverForEntries({
app: {
name: 'example-app'
},
types: {
template: { definitiveCollection: 'components' }
},
collections: {
components: {
group: 'ui',
types: [ 'template' ]
},
routes: {
group: 'ui',
types: [ 'template' ]
}
}
}, {
'template:/app/components/my-input': template
});

assert.equal(
resolver.resolve('template:components/my-input'),
template,
'relative module specifier with source resolved'
);
Expand Down Expand Up @@ -352,3 +392,113 @@ test('Can resolve a partial', function(assert) {
'partial resolved'
);
});

test('Can resolve private component template', function(assert) {
let template = {};
let notTemplate = {};
let resolver = this.resolverForEntries({
app: {
name: 'example-app'
},
types: {
template: { definitiveCollection: 'components' }
},
collections: {
components: {
group: 'ui',
types: [ 'template' ]
},
routes: {
group: 'ui',
types: [ 'template' ],
privateCollections: ['components']
}
}
}, {
'template:/app/routes/my-page/my-input': notTemplate,
'template:/app/routes/my-page/-components/my-input': template
});


assert.equal(
resolver.resolve('template:components/my-input', 'template:src/ui/routes/my-page'),
template,
'relative module specifier with source resolved w/ normalization'
);
});

test('Can resolve template in a route correctly', function(assert) {
let routeTemplate = {};
let componentTemplate = {};
let resolver = this.resolverForEntries({
app: {
name: 'example-app'
},
types: {
route: { definitiveCollection: 'routes' },
template: { definitiveCollection: 'components' }
},
collections: {
components: {
group: 'ui',
types: [ 'template' ]
},
routes: {
group: 'ui',
types: [ 'template' ],
privateCollections: ['components']
}
}
}, {
'template:/app/routes/my-page': routeTemplate,
'template:/app/components/my-page': componentTemplate
});

assert.equal(
resolver.resolve('template:my-page'),
routeTemplate,
'relative module found in routes'
);
assert.equal(
resolver.resolve('template:components/my-page'),
componentTemplate,
'relative module found in routes'
);
});

test('Does not fall back when resolving route', function(assert) {
let componentTemplate = {};
let resolver = this.resolverForEntries({
app: {
name: 'example-app'
},
types: {
route: { definitiveCollection: 'routes' },
template: { definitiveCollection: 'components' }
},
collections: {
components: {
group: 'ui',
types: [ 'template' ]
},
routes: {
group: 'ui',
types: [ 'template' ],
privateCollections: ['components']
}
}
}, {
'template:/app/components/my-page': componentTemplate
});

assert.equal(
resolver.resolve('template:my-page'),
undefined,
'relative module found in routes'
);
assert.equal(
resolver.resolve('template:components/my-page'),
componentTemplate,
'relative module found in routes'
);
});
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -40,7 +40,7 @@
"ember-addon"
],
"dependencies": {
"@glimmer/resolver": "^0.3.0",
"@glimmer/resolver": "0.4.0",
"babel-plugin-debug-macros": "^0.1.1",
"broccoli-funnel": "^1.1.0",
"broccoli-merge-trees": "^2.0.0",
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Expand Up @@ -6,9 +6,9 @@
version "0.2.0"
resolved "https://registry.yarnpkg.com/@glimmer/di/-/di-0.2.0.tgz#73bfd4a6ee4148a80bf092e8a5d29bcac9d4ce7e"

"@glimmer/resolver@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@glimmer/resolver/-/resolver-0.3.0.tgz#65451a2195259ce26518715631c38dd7c144e821"
"@glimmer/resolver@0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@glimmer/resolver/-/resolver-0.4.0.tgz#7fe8709342064f144c14c06088d6dc4070ad7d1d"
dependencies:
"@glimmer/di" "^0.2.0"

Expand Down

0 comments on commit 5f425d6

Please sign in to comment.