From 7bc1e023c135057538adc2b19bda4ffb884b0a1b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 1 May 2014 16:23:55 +1000 Subject: [PATCH 1/5] Revert "Add some comments for the new __passthrough property." This reverts commit 42db5f574ca692b8a03f492c5ee0624f60a3fb51. --- layout.js | 10 ---------- overrides.js | 4 ---- 2 files changed, 14 deletions(-) diff --git a/layout.js b/layout.js index 454f7c0..be84ce3 100644 --- a/layout.js +++ b/layout.js @@ -304,16 +304,6 @@ Layout = UI.Component.extend({ var tmpl = lookupTemplate.call(self, tmplName); // it's a component if (typeof tmpl.instantiate === 'function') - // See how __pasthrough is used in overrides.js - // findComponentWithHelper. If __passthrough is true - // then we'll continue past this component in looking - // up a helper method. This allows this use case: - // tmpl.__passthrough = true; return tmpl; } diff --git a/overrides.js b/overrides.js index 319bcb8..da899ff 100644 --- a/overrides.js +++ b/overrides.js @@ -32,10 +32,6 @@ findComponentWithHelper = function (id, comp) { if (comp.__helperHost) { if (typeof comp[id] !== 'undefined') return comp; - - // if __pasthrough == true on the component we will continue - // looking up the parent chain to find a component with the - // property of . Otherwise just halt right now and return null. else if (! comp.__passthrough) return null; } From 9c1e2e6c5745aa93c02a0ff8c1bc7043ddca148b Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 1 May 2014 16:24:02 +1000 Subject: [PATCH 2/5] Revert "Get rid of spurious logs" This reverts commit 6ecda8e0493c7b0034bc3618fa09a3ec3ce5dfff. --- overrides.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/overrides.js b/overrides.js index da899ff..b9c6b0d 100644 --- a/overrides.js +++ b/overrides.js @@ -29,6 +29,7 @@ var findComponentOfKind = function (kind, comp) { // added a '__passthrough' property that allows helpers through findComponentWithHelper = function (id, comp) { while (comp) { + console.log(comp) if (comp.__helperHost) { if (typeof comp[id] !== 'undefined') return comp; @@ -47,6 +48,7 @@ UI.Component.lookup = function (id, opts) { var self = this; var comp, result; + console.log(id) if (id === 'yield') { throw new Error("Sorry, would you mind using {{> yield}} instead of {{yield}}? It helps the Blaze engine."); } else if (id === 'contentFor') { From 28f8116db850317d0aea25914d0a19a118e4606a Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 1 May 2014 16:24:06 +1000 Subject: [PATCH 3/5] Revert "Allow helpers to work inside `{{#Layout`s." This reverts commit 742448ddff7f05ff02a7d49082b4667d5ecf2998. --- layout.js | 49 ++++++++++++++++++++++++- overrides.js | 102 --------------------------------------------------- package.js | 1 - 3 files changed, 48 insertions(+), 104 deletions(-) delete mode 100644 overrides.js diff --git a/layout.js b/layout.js index be84ce3..2475f20 100644 --- a/layout.js +++ b/layout.js @@ -304,7 +304,7 @@ Layout = UI.Component.extend({ var tmpl = lookupTemplate.call(self, tmplName); // it's a component if (typeof tmpl.instantiate === 'function') - tmpl.__passthrough = true; + tmpl.__helperHost = false; return tmpl; } else { @@ -362,3 +362,50 @@ BlazeUIManager.prototype = { UI.DomRange.insert(this.render(props, parentComponent).dom, parentDom || document.body); } }; + +var findComponentOfKind = function (kind, comp) { + while (comp) { + if (comp.kind === kind) + return comp; + comp = comp.parent; + } + return null; +}; + +// Override {{> yield}} and {{#contentFor}} to find the closest +// enclosing layout +var origLookup = UI.Component.lookup; +UI.Component.lookup = function (id, opts) { + if (id === 'yield') { + throw new Error("Sorry, would you mind using {{> yield}} instead of {{yield}}? It helps the Blaze engine."); + } else if (id === 'contentFor') { + var layout = findComponentOfKind('Layout', this); + if (!layout) + throw new Error("Couldn't find a Layout component in the rendered component tree"); + else { + return layout[id]; + } + } else { + return origLookup.apply(this, arguments); + } +}; + +var origLookupTemplate = UI.Component.lookupTemplate; +UI.Component.lookupTemplate = function (id, opts) { + if (id === 'yield') { + var layout = findComponentOfKind('Layout', this); + if (!layout) + throw new Error("Couldn't find a Layout component in the rendered component tree"); + else { + return layout[id]; + } + } else { + return origLookupTemplate.apply(this, arguments); + } +}; + +if (Package['iron-router']) { + Package['iron-router'].Router.configure({ + uiManager: new BlazeUIManager + }); +} diff --git a/overrides.js b/overrides.js deleted file mode 100644 index b9c6b0d..0000000 --- a/overrides.js +++ /dev/null @@ -1,102 +0,0 @@ -// some temporary overrides of blaze which hopefully will be resolved in core soon. - -findComponentWithProp = function (id, comp) { - while (comp) { - if (typeof comp[id] !== 'undefined') - return comp; - comp = comp.parent; - } - return null; -}; - -getComponentData = function (comp) { - comp = findComponentWithProp('data', comp); - return (comp ? - (typeof comp.data === 'function' ? - comp.data() : comp.data) : - null); -}; - -var findComponentOfKind = function (kind, comp) { - while (comp) { - if (comp.kind === kind) - return comp; - comp = comp.parent; - } - return null; -}; - -// added a '__passthrough' property that allows helpers through -findComponentWithHelper = function (id, comp) { - while (comp) { - console.log(comp) - if (comp.__helperHost) { - if (typeof comp[id] !== 'undefined') - return comp; - else if (! comp.__passthrough) - return null; - } - comp = comp.parent; - } - return null; -}; - -// Override {{> yield}} and {{#contentFor}} to find the closest -// enclosing layout -var origLookup = UI.Component.lookup; -UI.Component.lookup = function (id, opts) { - var self = this; - var comp, result; - - console.log(id) - if (id === 'yield') { - throw new Error("Sorry, would you mind using {{> yield}} instead of {{yield}}? It helps the Blaze engine."); - } else if (id === 'contentFor') { - var layout = findComponentOfKind('Layout', this); - if (!layout) - throw new Error("Couldn't find a Layout component in the rendered component tree"); - else { - result = layout[id]; - } - - // found a property or method of a component - // (`self` or one of its ancestors) - } else if (! /^\./.test(id) && (comp = findComponentWithHelper(id, self))) { - result = comp[id]; - - } else { - return origLookup.apply(this, arguments); - } - - if (typeof result === 'function' && ! result._isEmboxedConstant) { - // Wrap the function `result`, binding `this` to `getComponentData(self)`. - // This creates a dependency when the result function is called. - // Don't do this if the function is really just an emboxed constant. - return function (/*arguments*/) { - var data = getComponentData(self); - return result.apply(data === null ? {} : data, arguments); - }; - } else { - return result; - }; -}; - -var origLookupTemplate = UI.Component.lookupTemplate; -UI.Component.lookupTemplate = function (id, opts) { - if (id === 'yield') { - var layout = findComponentOfKind('Layout', this); - if (!layout) - throw new Error("Couldn't find a Layout component in the rendered component tree"); - else { - return layout[id]; - } - } else { - return origLookupTemplate.apply(this, arguments); - } -}; - -if (Package['iron-router']) { - Package['iron-router'].Router.configure({ - uiManager: new BlazeUIManager - }); -} diff --git a/package.js b/package.js index 8a4aaaa..3bb805c 100644 --- a/package.js +++ b/package.js @@ -11,7 +11,6 @@ Package.on_use(function (api) { api.use('deps-ext'); api.add_files('layout.js', 'client'); - api.add_files('overrides.js', 'client'); api.export('Layout', 'client'); }); From 6dac94c3e60c329d4f18f06abedb75698bc4c951 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 30 Apr 2014 17:09:54 +1000 Subject: [PATCH 4/5] Got rid of `__helperHost` hack and use `UI.InTemplateScope` instead. This is the "correct" way to do it, and the way that Spacebars does it for template includes and `UI.contentBlock` --- examples/simple/simple.html | 24 +++++++++++++++--------- layout.js | 13 ++++--------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/examples/simple/simple.html b/examples/simple/simple.html index 4c29c70..d86fe11 100644 --- a/examples/simple/simple.html +++ b/examples/simple/simple.html @@ -7,16 +7,22 @@ diff --git a/layout.js b/layout.js index 2475f20..f83bd9a 100644 --- a/layout.js +++ b/layout.js @@ -222,9 +222,9 @@ Layout = UI.Component.extend({ var tmpl = regions.get(region); if (tmpl) - return lookupTemplate.call(layout, tmpl); + return UI.InTemplateScope(layout, lookupTemplate.call(layout, tmpl)); else if (region === 'main' && content) { - return content; + return UI.InTemplateScope(layout, content); } else return null; @@ -301,13 +301,8 @@ Layout = UI.Component.extend({ if (tmplName === '_defaultLayout') return self._defaultLayout; else if (tmplName) { - var tmpl = lookupTemplate.call(self, tmplName); - // it's a component - if (typeof tmpl.instantiate === 'function') - tmpl.__helperHost = false; - return tmpl; - } - else { + return lookupTemplate.call(self, tmplName); + } else { return self['yield']; } }; From 5e15ffa33b9b0fd4da976850292b43e62df73fd3 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Thu, 1 May 2014 17:15:15 +1000 Subject: [PATCH 5/5] Added test + use UI.InTemplateScope. --- layout-test.html | 17 +++++++++++++++++ layout-test.js | 13 +++++++++++++ layout.js | 33 ++++++++++++++++++--------------- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/layout-test.html b/layout-test.html index c9f3f26..2fc83bc 100644 --- a/layout-test.html +++ b/layout-test.html @@ -48,9 +48,26 @@ {{/Layout}} + + + + + \ No newline at end of file diff --git a/layout-test.js b/layout-test.js index 24daac8..677ef90 100644 --- a/layout-test.js +++ b/layout-test.js @@ -98,6 +98,19 @@ Tinytest.add('layout - default main region using Layout template', function (tes }); }); +Tinytest.add('layout - default main region using Layout template should pickup data from context', function (test) { + withRenderedComponent(Template.DefaultMainRegionWithData, function (cmp, screen) { + test.equal(screen.innerHTML.compact(), 'layoutgood', 'default main region should be __content and inherit data'); + }); +}); + +Tinytest.add('layout - contentFor region using Layout template should pickup data from context', function (test) { + console.log('here') + withRenderedComponent(Template.ContentForWithData, function (cmp, screen) { + test.equal(screen.innerHTML.compact(), 'good', 'region should be contentFor and inherit data'); + }); +}); + Tinytest.add('layout - dynamic yield regions', function (test) { withRenderedLayout({template: 'LayoutWithTwoYields'}, function (layout, screen) { var renderedCount = 1; diff --git a/layout.js b/layout.js index f83bd9a..52053e7 100644 --- a/layout.js +++ b/layout.js @@ -69,7 +69,13 @@ var lookupTemplate = function (name) { throw new Error("BlazeLayout: You must pass a name to lookupTemplate"); if (contentBlocksByRegion[name]) { - result = contentBlocksByRegion[name]; + console.log(self, self.parent) + if (self.parent) + result = UI.InTemplateScope(self, contentBlocksByRegion[name]); + else + // XXX: this is really only for the test where we render the layout in + // isolation, without a parent. @cmather -- we should fix this. + result = contentBlocksByRegion[name]; } else if ((comp = findComponentWithProp(name, self))) { result = comp[name]; } else if (_.has(Template, name)) { @@ -107,8 +113,7 @@ Layout = UI.Component.extend({ var data = Deps.nonreactive(function () { return self.get(); }); var dataDep = new Deps.Dependency; var regions = this._regions = new ReactiveDict; - var content = this.__content; - + // a place to put content defined like this: // {{#contentFor region="footer"}}content{{/contentFor}} // this will be searched in the lookup chain. @@ -220,12 +225,9 @@ Layout = UI.Component.extend({ var regions = layout._regions; // create a reactive dep var tmpl = regions.get(region); - + if (tmpl) - return UI.InTemplateScope(layout, lookupTemplate.call(layout, tmpl)); - else if (region === 'main' && content) { - return UI.InTemplateScope(layout, content); - } + return lookupTemplate.call(layout, tmpl); else return null; }; @@ -260,15 +262,9 @@ Layout = UI.Component.extend({ var self = this; var region = self.region; - var contentBlocksByRegion = layout._contentBlocksByRegion; - - if (contentBlocksByRegion[region]) { - delete contentBlocksByRegion[region]; - } - // store away the content block so we can find it during lookup // which happens in the yield function. - contentBlocksByRegion[region] = self.__content; + layout._contentBlocksByRegion[region] = self.__content; // this will just set the region to itself but when the lookupTemplate // function searches it will check contentBlocksByRegion first, so we'll @@ -293,6 +289,12 @@ Layout = UI.Component.extend({ // computation. so if the template changes // the layout is re-endered. return function () { + // store away the main content block so we can find it during lookup too + if (self.__content) { + self._contentBlocksByRegion.main = self.__content; + self.setRegion('main', 'main'); + } + // reactive var tmplName = self.template(); @@ -375,6 +377,7 @@ UI.Component.lookup = function (id, opts) { throw new Error("Sorry, would you mind using {{> yield}} instead of {{yield}}? It helps the Blaze engine."); } else if (id === 'contentFor') { var layout = findComponentOfKind('Layout', this); + console.log(id, layout, this) if (!layout) throw new Error("Couldn't find a Layout component in the rendered component tree"); else {