mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Unify template obj and template callback this.
The `template` arg in `eventHandler(event, template)` and the `this`
in all three of {create,render,destroy} are now an object with
methods `find`,`findAll` assigned at creation time (closures) and
properties `firstNode`, `lastNode`, and `data` (the handlebars data)
set upon each callback. No other props are set and the app is free
to scribble on this object.
Only subtlety is that we can't support find/findAll/firstNode/lastNode
in create/destroy callback. In this case, find/findAll throw an error
and firstNode/lastNode are reliably null.
Added landmark.hasDom().
This commit is contained in:
@@ -214,18 +214,11 @@ Template.circles.disabled = function () {
|
||||
'' : 'disabled="disabled"';
|
||||
};
|
||||
|
||||
Template.circles.render = function (template) {
|
||||
Template.circles.render = function () {
|
||||
var self = this;
|
||||
self.node = template.find("svg");
|
||||
self.node = self.find("svg");
|
||||
|
||||
// XXX you really want to have template.data here. anything else is
|
||||
// obnoxious. it's plenty well defined and it's useful.
|
||||
var data = Spark.getDataContext(template._range.firstNode());
|
||||
|
||||
// XXX why doesn't this work?
|
||||
// var data = Spark.getDataContext(template.find("svg"));
|
||||
// this does:
|
||||
// Spark.getDataContext(template.find("svg").parentNode)
|
||||
var data = self.data;
|
||||
|
||||
if (! self.handle) {
|
||||
// XXX template.firstRender would be handy here
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
// timer' button again. the problem is almost certainly in atFlushTime
|
||||
// (not hard to see what it is.)
|
||||
|
||||
// XXX test hasDom(). Test `template` object more.
|
||||
|
||||
(function() {
|
||||
|
||||
Spark = {};
|
||||
@@ -958,6 +960,9 @@ _.extend(Spark.Landmark.prototype, {
|
||||
var r = this._range;
|
||||
return DomUtils.findAllClipped(r.containerNode(), selector,
|
||||
r.firstNode(), r.lastNode());
|
||||
},
|
||||
hasDom: function () {
|
||||
return !! this._range;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1036,8 +1041,10 @@ Spark.createLandmark = function (options, htmlFunc) {
|
||||
destroyCallback: options.destroy || function () {},
|
||||
landmark: landmark,
|
||||
finalize: function () {
|
||||
if (! this.superceded)
|
||||
if (! this.superceded) {
|
||||
this.landmark._range = null;
|
||||
this.destroyCallback.call(this.landmark);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1223,7 +1223,6 @@ Tinytest.add("spark - labeled landmarks", function (test) {
|
||||
5, function () { return "hi" + dep(9);}
|
||||
);});});});});});});}));
|
||||
});
|
||||
console.log(html);
|
||||
return html;
|
||||
}));
|
||||
|
||||
|
||||
@@ -29,13 +29,15 @@
|
||||
|
||||
_.extend(Handlebars._default_helpers, {
|
||||
isolate: function (options) {
|
||||
var data = this;
|
||||
return Spark.isolate(function () {
|
||||
return options.fn(this);
|
||||
return options.fn(data);
|
||||
});
|
||||
},
|
||||
constant: function (options) {
|
||||
var data = this;
|
||||
return Spark.createLandmark({ constant: true }, function () {
|
||||
return options.fn(this);
|
||||
return options.fn(data);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -46,17 +48,23 @@
|
||||
var templateInstanceData = {};
|
||||
|
||||
var templateObjFromLandmark = function (landmark) {
|
||||
var template = {
|
||||
find: function (selector) {
|
||||
return landmark.find(selector);
|
||||
},
|
||||
findAll: function (selector) {
|
||||
return landmark.findAll(selector);
|
||||
},
|
||||
firstNode: landmark.firstNode(),
|
||||
lastNode: landmark.lastNode(),
|
||||
data: templateInstanceData[landmark.id]
|
||||
};
|
||||
var template = templateInstanceData[landmark.id] || (
|
||||
templateInstanceData[landmark.id] = {
|
||||
// set these once
|
||||
find: function (selector) {
|
||||
if (! landmark.hasDom())
|
||||
throw new Error("Template not in DOM");
|
||||
return landmark.find(selector);
|
||||
},
|
||||
findAll: function (selector) {
|
||||
if (! landmark.hasDom())
|
||||
throw new Error("Template not in DOM");
|
||||
return landmark.findAll(selector);
|
||||
}
|
||||
});
|
||||
// set these each time
|
||||
template.firstNode = landmark.hasDom() ? landmark.firstNode() : null;
|
||||
template.lastNode = landmark.hasDom() ? landmark.lastNode() : null;
|
||||
return template;
|
||||
};
|
||||
|
||||
@@ -73,18 +81,18 @@
|
||||
var html = Spark.createLandmark({
|
||||
preserve: tmpl.preserve || {},
|
||||
create: function () {
|
||||
templateInstanceData[this.id] = {};
|
||||
tmpl.create &&
|
||||
tmpl.create.call(templateInstanceData[this.id]);
|
||||
var template = templateObjFromLandmark(this);
|
||||
template.data = data;
|
||||
tmpl.create && tmpl.create.call(template);
|
||||
},
|
||||
render: function () {
|
||||
tmpl.render &&
|
||||
tmpl.render.call(templateInstanceData[this.id],
|
||||
templateObjFromLandmark(this));
|
||||
var template = templateObjFromLandmark(this);
|
||||
template.data = data;
|
||||
tmpl.render && tmpl.render.call(template);
|
||||
},
|
||||
destroy: function () {
|
||||
tmpl.destroy &&
|
||||
tmpl.destroy.call(templateInstanceData[this.id]);
|
||||
tmpl.destroy.call(templateObjFromLandmark(this));
|
||||
delete templateInstanceData[this.id];
|
||||
}
|
||||
}, function (landmark) {
|
||||
|
||||
@@ -502,9 +502,9 @@ Tinytest.add("templating - matching in list", function (test) {
|
||||
var buf = [];
|
||||
_.extend(Template.test_listmatching_a1, {
|
||||
create: function () { buf.push('+'); },
|
||||
render: function (template) {
|
||||
var letter = DomUtils.rangeToHtml(template.firstNode,
|
||||
template.lastNode).match(/\S+/)[0];
|
||||
render: function () {
|
||||
var letter = DomUtils.rangeToHtml(this.firstNode,
|
||||
this.lastNode).match(/\S+/)[0];
|
||||
buf.push('*'+letter);
|
||||
},
|
||||
destroy: function () { buf.push('-'); }
|
||||
@@ -577,19 +577,38 @@ Tinytest.add("templating - template arg", function (test) {
|
||||
template.find('i').innerHTML =
|
||||
(template.findAll('*').length)+"-element";
|
||||
template.lastNode.innerHTML += ' (the secret is '+
|
||||
template.data.secret+')';
|
||||
template.secret+')';
|
||||
}
|
||||
};
|
||||
|
||||
Template.test_template_arg_a.render = function (template) {
|
||||
Template.test_template_arg_a.create = function() {
|
||||
var self = this;
|
||||
test.isFalse(self.firstNode);
|
||||
test.isFalse(self.lastNode);
|
||||
test.throws(function () { return self.find("*"); });
|
||||
test.throws(function () { return self.findAll("*"); });
|
||||
};
|
||||
|
||||
Template.test_template_arg_a.render = function () {
|
||||
var template = this;
|
||||
template.firstNode.innerHTML = 'Greetings';
|
||||
template.lastNode.innerHTML = 'Line';
|
||||
template.find('i').innerHTML =
|
||||
(template.findAll('b').length)+"-bold";
|
||||
template.data.secret = "strawberry pie";
|
||||
template.secret = "strawberry "+template.data.food;
|
||||
};
|
||||
|
||||
var div = OnscreenDiv(Spark.render(Template.test_template_arg_a));
|
||||
Template.test_template_arg_a.destroy = function() {
|
||||
var self = this;
|
||||
test.isFalse(self.firstNode);
|
||||
test.isFalse(self.lastNode);
|
||||
test.throws(function () { return self.find("*"); });
|
||||
test.throws(function () { return self.findAll("*"); });
|
||||
};
|
||||
|
||||
var div = OnscreenDiv(Spark.render(function () {
|
||||
return Template.test_template_arg_a({food: "pie"});
|
||||
}));
|
||||
|
||||
test.equal(div.text(), "Foo Bar Baz");
|
||||
Meteor.flush();
|
||||
|
||||
Reference in New Issue
Block a user