Index: fluid-engage-core/framework/js/engageClientUtils.js =================================================================== --- fluid-engage-core/framework/js/engageClientUtils.js (revision 9131) +++ fluid-engage-core/framework/js/engageClientUtils.js (working copy) @@ -306,48 +306,50 @@ fluid.engage.renderUtils = fluid.engage.renderUtils || {}; fluid.engage.renderUtils.createRendererFunction = function (container, selectors, options) { - var that = fluid.merge("merge", {container: container, selectors: selectors}, options); - that.container = $(that.container); + options = options || {}; - var renderFunc = function (tree, options) { - if (that.template) { - fluid.reRender(that.template, that.container, tree, options); - } else { - that.template = fluid.selfRender(that.container, tree, options); - } + var that = { + container: $(container), + rendererOptions: options.rendererOptions || {}, + templates: null }; - var render = function (tree) { - var mapFunc = "fluid.engage.renderUtils.selectorMapper"; + return function (tree) { + var cutpointFn = that.cutpointGenerator || "fluid.engage.renderUtils.selectorsToCutpoints"; + that.rendererOptions.cutpoints = that.rendererOptions.cutpoints || fluid.invokeGlobalFunction(cutpointFn, [selectors, options]); - that.selectorMap = that.selectorMap || fluid.invokeGlobalFunction(that.selectorMapper || mapFunc, [that.selectors, that]); - renderFunc(tree, fluid.merge("merge", {cutpoints: that.selectorMap}, that.rendererOptions)); + if (that.templates) { + fluid.reRender(that.templates, that.container, tree, that.rendererOptions); + } else { + that.templates = fluid.selfRender(that.container, tree, that.rendererOptions); + } }; - - return function (tree) { - render(tree); - }; }; - fluid.engage.renderUtils.removeSelectors = function (selectors, ignore) { - $.each(ignore || [], function (index, selectorToIgnore) { - delete selectors[selectorToIgnore]; - }); + fluid.engage.renderUtils.removeSelectors = function (selectors, selectorsToIgnore) { + if (selectorsToIgnore) { + $.each(selectorsToIgnore, function (index, selectorToIgnore) { + delete selectors[selectorToIgnore]; + }); + } return selectors; }; - fluid.engage.renderUtils.markRepeated = function (selector, repeat) { - $.each(repeat || [], function (index, repeatingSelector) { - if (selector === repeatingSelector) { - selector = selector + ":"; - } - }); + fluid.engage.renderUtils.markRepeated = function (selector, repeatingSelectors) { + if (repeatingSelectors) { + $.each(repeatingSelectors, function (index, repeatingSelector) { + if (selector === repeatingSelector) { + selector = selector + ":"; + } + }); + } return selector; }; - fluid.engage.renderUtils.selectorMapper = function (selectors, options) { - var map = []; + fluid.engage.renderUtils.selectorsToCutpoints = function (selectors, options) { + var cutpoints = []; options = options || {}; + selectors = fluid.copy(selectors); // Make a copy before potentially destructively changing someone's selectors. if (options.selectorsToIgnore) { selectors = fluid.engage.renderUtils.removeSelectors(selectors, options.selectorsToIgnore); @@ -355,14 +357,14 @@ for (var key in selectors) { if (selectors.hasOwnProperty(key)) { - map.push({ + cutpoints.push({ id: fluid.engage.renderUtils.markRepeated(key, options.repeatingSelectors), selector: selectors[key] }); } } - return map; + return cutpoints; }; /** A special "shallow copy" operation suitable for nondestructively Index: fluid-engage-core/tests/framework-tests/engageClientUtils/js/EngageClientUtilsTests.js =================================================================== --- fluid-engage-core/tests/framework-tests/engageClientUtils/js/EngageClientUtilsTests.js (revision 9131) +++ fluid-engage-core/tests/framework-tests/engageClientUtils/js/EngageClientUtilsTests.js (working copy) @@ -121,11 +121,35 @@ jqUnit.assertDeepEq("Proper uiBound with an attr decorator created, no value passed", {ID: id, decorators: [{attrs: attrObj}]}, fluid.engage.renderUtils.attrDecoratedUIBound(id, attrName, attrValue)); }); - tests.test("Renderer Utilities Test: selector mapper", function () { - jqUnit.assertDeepEq("Selector Map generation", [{id: "selector", selector: ".className"}], fluid.engage.renderUtils.selectorMapper({selector: ".className"})); - jqUnit.assertDeepEq("Selector Map generation, with repeating items", [{id: "selector1", selector: ".class1"}, {id: "selector2:", selector: ".class2"}], fluid.engage.renderUtils.selectorMapper({selector1: ".class1", selector2: ".class2"}, {repeatingSelectors: ["selector2"]})); - jqUnit.assertDeepEq("Selector Map generation, with ignored selectors", [{id: "selector1", selector: ".class1"}], fluid.engage.renderUtils.selectorMapper({selector1: ".class1", selector2: ".class2"}, {selectorsToIgnore: ["selector2"]})); - jqUnit.assertDeepEq("Selector Map generation, with repeating items and ignored selectors", [{id: "selector1:", selector: ".class1"}], fluid.engage.renderUtils.selectorMapper({selector1: ".class1", selector2: ".class2"}, {repeatingSelectors: ["selector1"], selectorsToIgnore: ["selector2"]})); + tests.test("Renderer Utilities Test: selectorsToCutpoints", function () { + // Single class name, simple cutpoints generation. + var selectors = {selector1: ".class1"}; + var expected = [{id: "selector1", selector: ".class1"}]; + jqUnit.assertDeepEq("Selector Map generation", expected, fluid.engage.renderUtils.selectorsToCutpoints(selectors)); + + selectors = {selector1: ".class1", selector2: ".class2"} + + // Multiple selectors with one repeating. + expected = [{id: "selector1", selector: ".class1"}, {id: "selector2:", selector: ".class2"}]; + var actual = fluid.engage.renderUtils.selectorsToCutpoints(selectors, {repeatingSelectors: ["selector2"]}); + jqUnit.assertDeepEq("Selector Map generation, with repeating items", expected, actual); + + // Ignoring selectors. + expected = [{id: "selector1", selector: ".class1"}]; + actual = fluid.engage.renderUtils.selectorsToCutpoints(selectors, { + selectorsToIgnore: ["selector2"] + }); + jqUnit.assertDeepEq("Selector Map generation, with ignored selectors", expected, actual); + jqUnit.assertNotUndefined("selectorsToCutpoints should not eat other people's selectors", selectors.selector2); + + // Repeating and ignored selectors. + expected = [{id: "selector1:", selector: ".class1"}]; + actual = fluid.engage.renderUtils.selectorsToCutpoints(selectors, { + repeatingSelectors: ["selector1"], + selectorsToIgnore: ["selector2"] + }); + jqUnit.assertDeepEq("Selector Map generation, with repeating items and ignored selectors", expected, actual); + jqUnit.assertNotUndefined("selectorsToCutpoints should not eat other people's selectors", selectors.selector2); }); tests.test("Renderer Utilities Test: Renderer Init Helper", function () {