Permalink
Browse files

Fix UI._templateInstance() to look at surrounding template.

Previously we were using the current component to retrieve the template
instance, but what we actually want is the template instance of the
surrounding component that is a template.
  • Loading branch information...
1 parent 40e45ca commit b84c7662f3adebb6067e5d4eb434bdd4a6538a6c Emily Stark committed Jun 17, 2014
Showing with 41 additions and 10 deletions.
  1. +2 −2 packages/spacebars-tests/template_tests.html
  2. +16 −3 packages/spacebars-tests/template_tests.js
  3. +23 −5 packages/ui/base.js
@@ -780,7 +780,7 @@
</template>
<template name="spacebars_test_template_instance_helper">
- {{foo}}
+ {{#with true}}{{foo}}{{/with}}
</template>
<template name="spacebars_test_with_cleanup">
@@ -807,4 +807,4 @@
{{/if}}
{{/with}}
{{/each}}
-</template>
+</template>
@@ -2115,6 +2115,17 @@ Tinytest.add(
}
);
+// XXX This is for traversing empty text nodes and should be removed
+// on blaze-refactor.
+var getSiblingText = function (node, siblingNum) {
+ var sibling = node;
+ for (var i = 0; i < siblingNum; i++) {
+ if (sibling)
+ sibling = sibling.nextSibling;
+ }
+ return $(sibling).text();
+};
+
Tinytest.add(
"spacebars - access template instance from helper, " +
"template instance is kept up-to-date",
@@ -2132,11 +2143,13 @@ Tinytest.add(
rv.set("first");
Deps.flush();
// `nextSibling` because the first node is an empty text node.
- test.equal($(instanceFromHelper.firstNode.nextSibling).text(), "first");
+ test.equal(getSiblingText(instanceFromHelper.firstNode, 4),
+ "first");
rv.set("second");
Deps.flush();
- test.equal($(instanceFromHelper.firstNode.nextSibling).text(), "second");
+ test.equal(getSiblingText(instanceFromHelper.firstNode, 4),
+ "second");
// UI._templateInstance() should throw when called from not within a
// helper.
@@ -2208,4 +2221,4 @@ Tinytest.add(
Deps.flush();
test.equal(canonicalizeHtml(div.innerHTML), "parent");
}
-);
+);
View
@@ -206,6 +206,16 @@ findComponentWithProp = function (id, comp) {
return null;
};
+var findHelperHostComponent = function (comp) {
@avital
avital Jun 18, 2014 Contributor

Can we add a short comment here?

+ while (comp) {
+ if (comp.__helperHost) {
+ return comp;
+ }
+ comp = comp.parent;
+ }
+ return null;
+};
+
findComponentWithHelper = function (id, comp) {
while (comp) {
if (comp.__helperHost) {
@@ -354,17 +364,25 @@ UI._javascriptUrlsAllowed = function () {
};
UI._templateInstance = function () {
- var component = currentComponent.get();
- if (! component) {
+ var currentComp = currentComponent.get();
+ if (! currentComp) {
throw new Error("You can only call UI._templateInstance() from within" +
" a helper function.");
}
+ // Find the enclosing component that is a template. (`currentComp`
+ // could be, for example, an #if or #with, and we want the component
+ // that is the surrounding template.)
+ var template = findHelperHostComponent(currentComp);
+ if (! template) {
+ throw new Error("Current component is not inside a template?");
+ }
+
// Lazily update the template instance for this helper, and do it only
// once.
if (! currentTemplateInstance) {
- updateTemplateInstance(component);
- currentTemplateInstance = component.templateInstance;
+ updateTemplateInstance(template);
+ currentTemplateInstance = template.templateInstance;
}
return currentTemplateInstance;
};
@@ -388,4 +406,4 @@ UI._parentData = function (numLevels) {
}
return getComponentData(component);
-};
+};

0 comments on commit b84c766

Please sign in to comment.