Bug 705074 - All uses of DOMTemplate should use new template function; r=dcamp

This commit is contained in:
Joe Walker 2011-12-08 12:39:04 +00:00
parent 9c77c343f1
commit aae7876045
4 changed files with 64 additions and 17 deletions

View File

@ -22,7 +22,7 @@ function runTest(index) {
holder.innerHTML = options.template;
info('Running ' + options.name);
new Templater().processNode(holder, options.data);
template(holder, options.data, options.options);
if (typeof options.result == 'string') {
is(holder.innerHTML, options.result, options.name);
@ -88,6 +88,7 @@ var tests = [
function() { return {
name: 'returnDom',
template: '<div id="ex2">${__element.ownerDocument.createTextNode(\'pass 2\')}</div>',
options: { allowEval: true },
data: {},
result: '<div id="ex2">pass 2</div>'
};},
@ -102,6 +103,7 @@ var tests = [
function() { return {
name: 'ifTrue',
template: '<p if="${name !== \'jim\'}">hello ${name}</p>',
options: { allowEval: true },
data: { name: 'fred' },
result: '<p>hello fred</p>'
};},
@ -109,6 +111,7 @@ var tests = [
function() { return {
name: 'ifFalse',
template: '<p if="${name !== \'jim\'}">hello ${name}</p>',
options: { allowEval: true },
data: { name: 'jim' },
result: ''
};},
@ -116,6 +119,7 @@ var tests = [
function() { return {
name: 'simpleLoop',
template: '<p foreach="index in ${[ 1, 2, 3 ]}">${index}</p>',
options: { allowEval: true },
data: {},
result: '<p>1</p><p>2</p><p>3</p>'
};},
@ -127,6 +131,7 @@ var tests = [
result: '123'
};},
// Bug 692028: DOMTemplate memory leak with asynchronous arrays
// Bug 692031: DOMTemplate async loops do not drop the loop element
function() { return {
name: 'asyncLoopElement',
@ -150,6 +155,7 @@ var tests = [
function() { return {
name: 'useElement',
template: '<p id="pass9">${adjust(__element)}</p>',
options: { allowEval: true },
data: {
adjust: function(element) {
is('pass9', element.id, 'useElement adjust');
@ -167,6 +173,7 @@ var tests = [
later: 'inline'
};},
// Bug 692028: DOMTemplate memory leak with asynchronous arrays
function() { return {
name: 'asyncArray',
template: '<p foreach="i in ${delayed}">${i}</p>',
@ -183,6 +190,7 @@ var tests = [
later: '<p>4</p><p>5</p><p>6</p>'
};},
// Bug 692028: DOMTemplate memory leak with asynchronous arrays
function() { return {
name: 'asyncBoth',
template: '<p foreach="i in ${delayed}">${i}</p>',
@ -195,6 +203,38 @@ var tests = [
},
result: '<span></span>',
later: '<p>4</p><p>5</p><p>6</p>'
};},
// Bug 701762: DOMTemplate fails when ${foo()} returns undefined
function() { return {
name: 'functionReturningUndefiend',
template: '<p>${foo()}</p>',
options: { allowEval: true },
data: {
foo: function() {}
},
result: '<p>undefined</p>'
};},
// Bug 702642: DOMTemplate is relatively slow when evaluating JS ${}
function() { return {
name: 'propertySimple',
template: '<p>${a.b.c}</p>',
data: { a: { b: { c: 'hello' } } },
result: '<p>hello</p>'
};},
function() { return {
name: 'propertyPass',
template: '<p>${Math.max(1, 2)}</p>',
options: { allowEval: true },
result: '<p>2</p>'
};},
function() { return {
name: 'propertyFail',
template: '<p>${Math.max(1, 2)}</p>',
result: '<p>${Math.max(1, 2)}</p>'
};}
];

View File

@ -214,7 +214,10 @@ CssHtmlTree.processTemplate = function CssHtmlTree_processTemplate(aTemplate,
// All the templater does is to populate a given DOM tree with the given
// values, so we need to clone the template first.
let duplicated = aTemplate.cloneNode(true);
new Templater().processNode(duplicated, aData);
// See https://github.com/mozilla/domtemplate/blob/master/README.md
// for docs on the template() function
template(duplicated, aData, { allowEval: true });
while (duplicated.firstChild) {
aDestination.appendChild(duplicated.firstChild);
}

View File

@ -92,10 +92,10 @@ XPCOMUtils.defineLazyGetter(this, "NetUtil", function () {
return obj.NetUtil;
});
XPCOMUtils.defineLazyGetter(this, "Templater", function () {
XPCOMUtils.defineLazyGetter(this, "template", function () {
var obj = {};
Cu.import("resource:///modules/devtools/Templater.jsm", obj);
return obj.Templater;
return obj.template;
});
XPCOMUtils.defineLazyGetter(this, "PropertyPanel", function () {
@ -6865,6 +6865,8 @@ GcliTerm.prototype = {
output + '</div>').firstChild;
}
// See https://github.com/mozilla/domtemplate/blob/master/README.md
// for docs on the template() function
let element = this.document.createRange().createContextualFragment(
'<richlistitem xmlns="' + XUL_NS + '" clipboardText="${clipboardText}"' +
' timestamp="${timestamp}" id="${id}" class="hud-msg-node">' +
@ -6879,7 +6881,7 @@ GcliTerm.prototype = {
let hud = HUDService.getHudReferenceById(this.hudId);
let timestamp = ConsoleUtils.timestamp();
new Templater().processNode(element, {
template(element, {
iconContainerStyle: "margin-left=" + (hud.groupDepth * GROUP_INDENT) + "px",
output: output,
timestamp: timestamp,

View File

@ -5058,8 +5058,7 @@ var help = exports;
var canon = require('gcli/canon');
var util = require('gcli/util');
var l10n = require('gcli/l10n');
var Templater = require('gcli/ui/domtemplate').Templater;
var domtemplate = require('gcli/ui/domtemplate');
var helpCss = require('text!gcli/commands/help.css');
var helpStyle = undefined;
@ -5103,7 +5102,8 @@ help.startup = function() {
var match = canon.getCommand(args.search);
if (match) {
var clone = helpManTemplate.cloneNode(true);
new Templater().processNode(clone, getManTemplateData(match, context));
domtemplate.template(clone, getManTemplateData(match, context),
{ stack: 'help_man.html' });
return clone;
}
@ -5112,7 +5112,8 @@ help.startup = function() {
parent.appendChild(helpIntroTemplate.cloneNode(true));
}
parent.appendChild(helpListTemplate.cloneNode(true));
new Templater().processNode(parent, getListTemplateData(args, context));
domtemplate.template(parent, getListTemplateData(args, context),
{ allowEval: true, stack: 'help_intro.html | help_list.html' });
return parent;
}
};
@ -5243,8 +5244,9 @@ function getManTemplateData(command, context) {
define('gcli/ui/domtemplate', ['require', 'exports', 'module' ], function(require, exports, module) {
Components.utils.import("resource:///modules/devtools/Templater.jsm");
exports.Templater = Templater;
var obj = {};
Components.utils.import('resource:///modules/devtools/Templater.jsm', obj);
exports.template = obj.template;
});
define("text!gcli/commands/help.css", [], void 0);
@ -6141,7 +6143,7 @@ var dom = require('gcli/util').dom;
var Status = require('gcli/types').Status;
var getField = require('gcli/ui/field').getField;
var Templater = require('gcli/ui/domtemplate').Templater;
var domtemplate = require('gcli/ui/domtemplate');
var editorCss = require('text!gcli/ui/arg_fetch.css');
var argFetchHtml = require('text!gcli/ui/arg_fetch.html');
@ -6170,7 +6172,6 @@ function ArgFetcher(options) {
// We cache the fields we create so we can destroy them later
this.fields = [];
this.tmpl = new Templater();
// Populated by template
this.okElement = null;
@ -6227,7 +6228,8 @@ ArgFetcher.prototype.onCommandChange = function(ev) {
this.fields = [];
var reqEle = this.reqTempl.cloneNode(true);
this.tmpl.processNode(reqEle, this);
domtemplate.template(reqEle, this,
{ allowEval: true, stack: 'arg_fetch.html' });
dom.clearElement(this.element);
this.element.appendChild(reqEle);
@ -6282,7 +6284,7 @@ ArgFetcher.prototype.getInputFor = function(assignment) {
return newField.element;
}
catch (ex) {
// This is called from within Templater which can make tracing errors hard
// This is called from within template() which can make tracing errors hard
// so we log here if anything goes wrong
console.error(ex);
return '';
@ -7068,7 +7070,7 @@ var Conversion = require('gcli/types').Conversion;
var Argument = require('gcli/argument').Argument;
var canon = require('gcli/canon');
var Templater = require('gcli/ui/domtemplate').Templater;
var domtemplate = require('gcli/ui/domtemplate');
var menuCss = require('text!gcli/ui/menu.css');
var menuHtml = require('text!gcli/ui/menu.html');
@ -7151,7 +7153,7 @@ Menu.prototype.show = function(items, error) {
}
var options = this.optTempl.cloneNode(true);
new Templater().processNode(options, this);
domtemplate.template(options, this, { allowEval: true, stack: 'menu.html' });
dom.clearElement(this.element);
this.element.appendChild(options);