From 79ead1fefbaf9d9474272f063de6b42aa7949a78 Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Thu, 29 Dec 2011 11:43:14 -0600 Subject: [PATCH] Add Builder.subview / Template.subview --- spec/stdlib/template-spec.coffee | 19 +++++++++++++------ spec/stdlib/template/builder-spec.coffee | 22 ++++++++++++++++++++++ src/stdlib/template.coffee | 3 +++ src/stdlib/template/builder.coffee | 13 ++++++++++++- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/spec/stdlib/template-spec.coffee b/spec/stdlib/template-spec.coffee index c4d9e4824..bb0368879 100644 --- a/spec/stdlib/template-spec.coffee +++ b/spec/stdlib/template-spec.coffee @@ -2,15 +2,21 @@ Template = require 'template' describe "Template", -> describe "toView", -> - Foo = null view = null beforeEach -> - class Foo extends Template + subviewTemplate = class extends Template + content: (params) -> + @div => + @h2 params.title + @div "I am a subview" + + template = class extends Template content: (attrs) -> @div => @h1 attrs.title @list() + @subview 'subview', subviewTemplate, title: "Subview" list: -> @ol => @@ -24,10 +30,7 @@ describe "Template", -> li1Clicked: ->, li2Keypressed: -> - view = Foo.build(title: "Zebra") - - afterEach -> - delete window.Foo + view = template.build(title: "Zebra") describe ".build(attributes)", -> it "generates markup based on the content method", -> @@ -45,6 +48,10 @@ describe "Template", -> expect(view.li1).toMatchSelector "li.foo:contains(one)" expect(view.li2).toMatchSelector "li.bar:contains(two)" + it "constructs and wires outlets for subviews", -> + expect(view.subview).toExist() + expect(view.subview.find('h2:contains(Subview)')).toExist() + it "binds events for elements with event name attributes", -> spyOn(view, 'li1Clicked').andCallFake (event, elt) -> expect(event.type).toBe 'click' diff --git a/spec/stdlib/template/builder-spec.coffee b/spec/stdlib/template/builder-spec.coffee index ea055a5f7..cfe272174 100644 --- a/spec/stdlib/template/builder-spec.coffee +++ b/spec/stdlib/template/builder-spec.coffee @@ -1,4 +1,5 @@ Builder = require 'template/builder' +Template = require 'template' describe "Builder", -> builder = null @@ -39,3 +40,24 @@ describe "Builder", -> builder.tag 'br', id: 'foo' expect(builder.toHtml()).toBe '
' + describe ".subview(name, template, attrs)", -> + template = null + + beforeEach -> + template = class extends Template + content: (params) -> + @div => + @h2 params.title + @div "I am a subview" + + it "inserts a view built from the given template with the given params", -> + builder.tag 'div', -> + builder.tag 'h1', "Superview" + builder.subview 'sub', template, title: "Subview" + + fragment = builder.toFragment() + expect(fragment.find("h1:contains(Superview)")).toExist() + expect(fragment.find("h2:contains(Subview)")).toExist() + subview = fragment.find('div[outlet=sub]') + expect(subview).toMatchSelector ':has(h2):contains(I am a subview)' + diff --git a/src/stdlib/template.coffee b/src/stdlib/template.coffee index 77f359c6c..7e945109a 100644 --- a/src/stdlib/template.coffee +++ b/src/stdlib/template.coffee @@ -36,6 +36,9 @@ class Template @content(attributes) @builder.toHtml() + subview: (args...) -> + @builder.subview.apply(@builder, args) + wireOutlets: (view) -> view.find('[outlet]').each -> elt = $(this) diff --git a/src/stdlib/template/builder.coffee b/src/stdlib/template/builder.coffee index 080b3e3e3..76204affe 100644 --- a/src/stdlib/template/builder.coffee +++ b/src/stdlib/template/builder.coffee @@ -25,7 +25,9 @@ class Builder _.map(@document, (x) -> x.toHtml()).join('') toFragment: -> - $(@toHtml()) + fragment = $(@toHtml()) + fn(fragment) for fn in @postProcessingFns + fragment tag: (name, args...) -> options = @extractOptions(args) @@ -39,6 +41,13 @@ class Builder @text(options.text) if options.text @document.push(new CloseTag(name)) + subview: (outletName, template, params) -> + subviewId = ++@subviewCount + @tag 'div', subview: subviewId + @postProcessingFns.push (view) -> + subview = template.build(params) + subview.attr('outlet', outletName) + view.find("div[subview=#{subviewId}]").replaceWith(subview) elementIsVoid: (name) -> name in @constructor.elements.void @@ -56,5 +65,7 @@ class Builder @document.push(new Text(string)) reset: -> + @subviewCount = 0 @document = [] + @postProcessingFns = []