From 53e7181e009efcdcad182d485972bfbfda982fc0 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Fri, 29 Mar 2013 21:36:57 +0000 Subject: Allow HTML elements to be reused in HTML generation --- lib/html-generator.js | 27 ++++++++++++++++++++++++--- lib/styles.js | 23 ++++++++++++++++++++--- tests/html-generator.tests.js | 17 +++++++++++++++-- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/lib/html-generator.js b/lib/html-generator.js index 247ca09..5f2befa 100644 --- a/lib/html-generator.js +++ b/lib/html-generator.js @@ -1,5 +1,7 @@ var util = require("util"); +var _ = require("underscore"); + exports.HtmlGenerator = HtmlGenerator; @@ -17,10 +19,20 @@ function HtmlGenerator() { } function style(style) { - popAll(); - style.forEach(function(tagName) { - push(tagName); + var firstFreshPartIndex = findIndex(style, function(part) { + return part.fresh; }); + + var partIndex = 0; + while (partIndex < firstFreshPartIndex && style[partIndex].tagName === stack[partIndex]) { + partIndex++; + } + while (stack.length > partIndex) { + pop(); + } + for (; partIndex < style.length; partIndex++) { + push(style[partIndex].tagName); + } } function push(element) { @@ -54,3 +66,12 @@ function escapeHtml(value) { .replace(//g, '>'); } + +function findIndex(array, predicate) { + for (var i = 0; i < array.length; i++) { + if (predicate(array[i])) { + return i; + } + } + return -1; +} diff --git a/lib/styles.js b/lib/styles.js index d3aa0a4..06d63a8 100644 --- a/lib/styles.js +++ b/lib/styles.js @@ -1,10 +1,27 @@ +var _ = require("underscore"); + exports.topLevelElement = topLevelElement; exports.elements = elements; +exports.element = element; function topLevelElement(tagName) { - return elements([tagName]); + return elements([element(tagName, {fresh: true})]); +} + +function elements(elementStyles) { + return elementStyles.map(function(elementStyle) { + if (_.isString(elementStyle)) { + return element(elementStyle); + } else { + return elementStyle; + } + }); } -function elements(tagNames) { - return tagNames; +function element(tagName, options) { + options = options || {}; + return { + tagName: tagName, + fresh: options.fresh + }; } diff --git a/tests/html-generator.tests.js b/tests/html-generator.tests.js index 822aed9..a98ee70 100644 --- a/tests/html-generator.tests.js +++ b/tests/html-generator.tests.js @@ -14,13 +14,26 @@ describe('HtmlGenerator', function() { test('HTML-escapes text', function() { var generator = new HtmlGenerator(); generator.text("<"); - return assert.equal("<", generator.asString()); + return assert.equal(generator.asString(), "<"); }); test('asString closes all elements', function() { var generator = new HtmlGenerator(); generator.style(styles.elements(["p", "span"])); generator.text("Hello!"); - return assert.equal("

Hello!

", generator.asString()); + return assert.equal(generator.asString(), "

Hello!

"); + }); + + test('can leave some HTML elements for next style', function() { + var generator = new HtmlGenerator(); + var listStyle = styles.elements([ + styles.element("ul", {fresh: false}), + styles.element("li", {fresh: true}) + ]) + generator.style(listStyle); + generator.text("Apple"); + generator.style(listStyle); + generator.text("Banana"); + return assert.equal(generator.asString(), ""); }); }) -- cgit v1.2.3