Skip to content

Commit

Permalink
feat(compiler): Support $baseUrl in HTML attributes when loading a te…
Browse files Browse the repository at this point in the history
…mplate.

Angular fetches template HTML files outside of the browser's normal parsing flow. As a result, URLs in template files are interpreted relative to the root application, when the components defined by the template files are inserted into the DOM. This change enables a template author to prefix URLs with the string $baseUrl, which will be replaced with the relative base path of the template file.

So for an example template loaded from /component/foo/template.html:

<img src="$baseUrl/logo.png" />

becomes:

<img src="/component/foo/logo.png" />

Addresses angular#2384.
  • Loading branch information
alxhub committed Jul 17, 2015
1 parent 19e4ee8 commit 12baf15
Showing 1 changed file with 35 additions and 1 deletion.
36 changes: 35 additions & 1 deletion modules/angular2/src/render/dom/compiler/view_loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export class ViewLoader {
private _loadHtml(view: ViewDefinition): Promise<any /* element */> {
let html;


// Load the HTML
if (isPresent(view.template)) {
html = PromiseWrapper.resolve(view.template);
Expand All @@ -82,9 +83,17 @@ export class ViewLoader {
throw new BaseException('View should have either the templateUrl or template property set');
}

// Inline the style tags from the html
return html.then(html => {
var tplEl = DOM.createTemplate(html);

// Replace $baseUrl with the base url for the template
let templateAbsUrl = view.templateAbsUrl;
if (isPresent(templateAbsUrl) && templateAbsUrl.indexOf("/") >= 0) {
let baseUrl = templateAbsUrl.substring(0, templateAbsUrl.lastIndexOf("/"));
this._substituteBaseUrl(DOM.content(tplEl), baseUrl);
}

// Inline the style tags from the html
let styleEls = DOM.querySelectorAll(DOM.content(tplEl), 'STYLE');

let promises: List<Promise<string>> = [];
Expand All @@ -99,6 +108,31 @@ export class ViewLoader {
});
}

/**
* Replace all occurrences of $baseUrl in the attributes of an element and its
* children with the base URL of the template.
*
* @param element The element to process
* @param baseUrl The base URL of the template.
* @private
*/
private _substituteBaseUrl(element, baseUrl: string): void {
if (DOM.isElementNode(element)) {
var attrs = DOM.attributeMap(element);
MapWrapper.forEach(attrs, (v, k) => {
if (v && v.indexOf('$baseUrl') > -1) {
DOM.setAttribute(element, k, v.replace(/\$baseUrl/gi, baseUrl));
}
});
}
let children = DOM.childNodes(element);
for (let i = 0; i < children.length; i++) {
if (DOM.isElementNode(children[i])) {
this._substituteBaseUrl(children[i], baseUrl);
}
}
}

/**
* Inlines a style element.
*
Expand Down

0 comments on commit 12baf15

Please sign in to comment.