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-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 454f7c0..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 lookupTemplate.call(layout, tmpl); - else if (region === 'main' && content) { - return content; - } 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(); @@ -301,23 +303,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') - // 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; - } - else { + return lookupTemplate.call(self, tmplName); + } else { return self['yield']; } }; @@ -372,3 +359,51 @@ 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); + console.log(id, 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 319bcb8..0000000 --- a/overrides.js +++ /dev/null @@ -1,104 +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) { - 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; - } - 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; - - 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'); });