aurelia-templating
Version:
An extensible HTML templating engine supporting databinding, custom elements, attached behaviors and more.
105 lines (86 loc) • 3.19 kB
text/typescript
import {metadata, Origin} from 'aurelia-metadata';
import {RelativeViewStrategy, ConventionalViewStrategy, StaticViewStrategy, viewStrategy, NoViewStrategy, ViewStrategy } from './view-strategy';
/**
* Locates a view for an object.
*/
export class ViewLocator {
/**
* The metadata key for storing/finding view strategies associated with an class/object.
*/
static viewStrategyMetadataKey = 'aurelia:view-strategy';
/**
* Gets the view strategy for the value.
* @param value The value to locate the view strategy for.
* @return The located ViewStrategy instance.
*/
getViewStrategy(value: any): ViewStrategy {
if (!value) {
return null;
}
if (typeof value === 'object' && 'getViewStrategy' in value) {
let origin = Origin.get(value.constructor);
value = value.getViewStrategy();
if (typeof value === 'string') {
value = new RelativeViewStrategy(value);
}
viewStrategy.assert(value);
if (origin.moduleId) {
(value as RelativeViewStrategy).makeRelativeTo(origin.moduleId);
}
return value;
}
if (typeof value === 'string') {
value = new RelativeViewStrategy(value);
}
if (viewStrategy.validate(value)) {
return value;
}
if (typeof value !== 'function') {
value = value.constructor;
}
// static view strategy
if ('$view' in value) {
let c = value.$view;
let view;
c = typeof c === 'function' ? c.call(value) : c;
if (c === null) {
view = new NoViewStrategy();
} else {
view = c instanceof StaticViewStrategy ? c : new StaticViewStrategy(c);
}
metadata.define(ViewLocator.viewStrategyMetadataKey, view, value);
return view;
}
let origin = Origin.get(value);
let strategy = metadata.get(ViewLocator.viewStrategyMetadataKey, value) as ViewStrategy & { moduleId?: string; };
if (!strategy) {
if (!origin.moduleId) {
throw new Error('Cannot determine default view strategy for object.\n' + value);
}
strategy = this.createFallbackViewStrategy(origin);
} else if (origin.moduleId) {
strategy.moduleId = origin.moduleId;
}
return strategy;
}
/**
* Creates a fallback View Strategy. Used when unable to locate a configured strategy.
* The default implementation returns and instance of ConventionalViewStrategy.
* @param origin The origin of the view model to return the strategy for.
* @return The fallback ViewStrategy.
*/
createFallbackViewStrategy(origin: Origin): ViewStrategy {
return new ConventionalViewStrategy(this, origin);
}
/**
* Conventionally converts a view model origin to a view url.
* Used by the ConventionalViewStrategy.
* @param origin The origin of the view model to convert.
* @return The view url.
*/
convertOriginToViewUrl(origin: Origin): string {
let moduleId = origin.moduleId;
let id = (moduleId.endsWith('.js') || moduleId.endsWith('.ts')) ? moduleId.substring(0, moduleId.length - 3) : moduleId;
return id + '.html';
}
}