Skip to content
This repository was archived by the owner on Apr 4, 2019. It is now read-only.

Commit 2bb1391

Browse files
committed
Clean up scope handling
This commit refactors the internal scope handling of templates so that the concept of a scope, including block parameters, is rigorous. It also stops leaking the caller's scope into a helper call. This commit has two primary changes: * The internal "scope" is now broken up into `self` and `locals`. Block helpers now receive `options.template.yield`, which is used like `options.template.yield([ optional, block, params ])`. If block parameters are supplied, HTMLBars will ask the host to create a new scope frame, and the `locals` hash will be populated with the yielded parameters. It is still possible to shift the `self` by using `options.template.render(newSelf, [ optional, block, params ])`, which will always create a new scope frame. Since self-shifting helpers are intended to be rare, `yield` is the new path, and encapsulates all of the scoping details. * Helpers and block helpers no longer receive the `self` as `this`, because they are intended to be analogous to functions. Functions do not have access to the scope of the caller O_o. Note that hooks, which are used by the host to implement the scoping semantics, of course still have access to the scope.
1 parent 13257d7 commit 2bb1391

File tree

7 files changed

+158
-117
lines changed

7 files changed

+158
-117
lines changed

packages/htmlbars-compiler/lib/hydration-javascript-compiler.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ prototype.compile = function(opcodes, options) {
2929
this.hooks = {};
3030
this.statements = [];
3131
this.expressionStack = [];
32-
this.augmentContext = [];
32+
this.locals = [];
3333
this.hasOpenBoundary = false;
3434
this.hasCloseBoundary = false;
3535

@@ -46,7 +46,7 @@ prototype.compile = function(opcodes, options) {
4646
hydrateMorphsProgram: '',
4747
fragmentProcessingProgram: '',
4848
statements: this.statements,
49-
augmentContext: this.augmentContext,
49+
locals: this.locals,
5050
hasMorphs: false
5151
};
5252

@@ -148,7 +148,7 @@ prototype.pushConcatHook = function() {
148148
};
149149

150150
prototype.printSetHook = function(name) {
151-
this.augmentContext.push(name);
151+
this.locals.push(name);
152152
};
153153

154154
prototype.printBlockHook = function(templateId, inverseId) {

packages/htmlbars-compiler/lib/template-compiler.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ TemplateCompiler.prototype.endProgram = function(program, programDepth) {
122122
return indent+' '+JSON.stringify(s);
123123
}).join(",\n");
124124

125-
var augmentContext = JSON.stringify(hydrationPrograms.augmentContext);
125+
var locals = JSON.stringify(hydrationPrograms.locals);
126126

127127
var templates = this.childTemplates.map(function(_, index) {
128128
return 'child' + index;
@@ -140,7 +140,7 @@ TemplateCompiler.prototype.endProgram = function(program, programDepth) {
140140
indent+' buildRenderNodes: ' + hydrationPrograms.createMorphsProgram + ',\n' +
141141
indent+' statements: [\n' + statements + '\n' +
142142
indent+' ],\n' +
143-
indent+' augmentContext: ' + augmentContext + ',\n' +
143+
indent+' locals: ' + locals + ',\n' +
144144
indent+' templates: [' + templates + ']\n' +
145145
indent+' };\n' +
146146
indent+'}())';

packages/htmlbars-compiler/tests/dirtying-test.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ test("a simple implementation of a dirtying rerender", function() {
4949
state.condition = normalized;
5050

5151
if (normalized) {
52-
return options.template.render(this);
52+
return options.template.yield();
5353
} else {
54-
return options.inverse.render(this);
54+
return options.inverse.yield();
5555
}
5656
}
5757
});
@@ -86,7 +86,7 @@ test("a simple implementation of a dirtying rerender", function() {
8686

8787
test("block helpers whose template has a morph at the edge", function() {
8888
registerHelper('id', function(params, hash, options) {
89-
return options.template.render(this);
89+
return options.template.yield();
9090
});
9191

9292
var template = compile("{{#id}}{{value}}{{/id}}");
@@ -137,7 +137,7 @@ test("clean content doesn't get blown away", function() {
137137
};
138138

139139
object.value = "hello";
140-
textRenderNode.isDirty = true;
140+
result.dirty();
141141
result.revalidate();
142142
});
143143

@@ -160,7 +160,7 @@ test("helper calls follow the normal dirtying rules", function() {
160160

161161
var textRenderNode = result.root.childNodes[0];
162162

163-
textRenderNode.isDirty = true;
163+
result.dirty();
164164
result.revalidate();
165165

166166
equalTokens(result.fragment, '<div>GOODBYE</div>');
@@ -171,7 +171,7 @@ test("helper calls follow the normal dirtying rules", function() {
171171

172172
// Checks normalized value, not raw value
173173
object.value = "GoOdByE";
174-
textRenderNode.isDirty = true;
174+
result.dirty();
175175
result.revalidate();
176176
});
177177

@@ -189,7 +189,7 @@ test("attribute nodes follow the normal dirtying rules", function() {
189189

190190
var attrRenderNode = result.root.childNodes[0];
191191

192-
attrRenderNode.isDirty = true;
192+
result.dirty();
193193
result.revalidate();
194194

195195
equalTokens(result.fragment, "<div class='universe'>hello</div>");
@@ -199,7 +199,7 @@ test("attribute nodes follow the normal dirtying rules", function() {
199199
};
200200

201201
object.value = "universe";
202-
attrRenderNode.isDirty = true;
202+
result.dirty();
203203
result.revalidate();
204204
});
205205

@@ -217,7 +217,7 @@ test("attribute nodes w/ concat follow the normal dirtying rules", function() {
217217

218218
var attrRenderNode = result.root.childNodes[0];
219219

220-
attrRenderNode.isDirty = true;
220+
result.dirty();
221221
result.revalidate();
222222

223223
equalTokens(result.fragment, "<div class='hello universe'>hello</div>");
@@ -227,6 +227,6 @@ test("attribute nodes w/ concat follow the normal dirtying rules", function() {
227227
};
228228

229229
object.value = "universe";
230-
attrRenderNode.isDirty = true;
230+
result.dirty();
231231
result.revalidate();
232232
});

0 commit comments

Comments
 (0)