From bd79d9cd5d6aa741daae23cc9d1bd326c9d5fa09 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 27 Dec 2011 16:43:28 -0600 Subject: [PATCH] Builder correctly generates void (self-closing) tags. --- spec/stdlib/template/builder-spec.coffee | 4 +++ src/stdlib/template/builder.coffee | 35 +++++++++++++++++------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/spec/stdlib/template/builder-spec.coffee b/spec/stdlib/template/builder-spec.coffee index fddbbb9a8..deb3af743 100644 --- a/spec/stdlib/template/builder-spec.coffee +++ b/spec/stdlib/template/builder-spec.coffee @@ -35,3 +35,7 @@ fdescribe "Builder", -> expect(fragment.attr('id')).toBe('foo') expect(fragment.attr('class')).toBe('bar') + it "can generate self-closing tags", -> + builder.tag 'br', id: 'foo' + expect(builder.toHtml()).toBe('
') + diff --git a/src/stdlib/template/builder.coffee b/src/stdlib/template/builder.coffee index f86e6a102..819842bc7 100644 --- a/src/stdlib/template/builder.coffee +++ b/src/stdlib/template/builder.coffee @@ -6,6 +6,18 @@ Text = require 'template/text' module.exports = class Builder + @elements: + normal: 'a abbr address article aside audio b bdi bdo blockquote body button + canvas caption cite code colgroup datalist dd del details dfn div dl dt em + fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup + html i iframe ins kbd label legend li map mark menu meter nav noscript object + ol optgroup option output p pre progress q rp rt ruby s samp script section + select small span strong style sub summary sup table tbody td textarea tfoot + th thead time title tr u ul video'.split /\s+/ + + void: 'area base br col command embed hr img input keygen link meta param + source track wbr'.split /\s+/ + constructor: -> @reset() @@ -17,10 +29,19 @@ class Builder tag: (name, args...) -> options = @extractOptions(args) - @openTag(name, options.attributes) - options.content?() - @text(options.text) if options.text - @closeTag(name) + + @document.push(new OpenTag(name, options.attributes)) + if @elementIsVoid(name) + if (options.text? or options.content?) + throw new Error("Self-closing tag #{tag} cannot have text or content") + else + options.content?() + @text(options.text) if options.text + @document.push(new CloseTag(name)) + + + elementIsVoid: (name) -> + _.contains(this.constructor.elements.void, name) extractOptions: (args) -> options = {} @@ -31,12 +52,6 @@ class Builder options.attributes = arg if _.isObject(arg) options - openTag: (name, attributes) -> - @document.push(new OpenTag(name, attributes)) - - closeTag: (name) -> - @document.push(new CloseTag(name)) - text: (string) -> @document.push(new Text(string))