From 888492e7c4c3bfb108865f118c65dd303e058263 Mon Sep 17 00:00:00 2001 From: Matthew Beale Date: Sun, 3 May 2015 13:53:04 -0400 Subject: [PATCH] Bring back the render hook with a pushable buffer --- .../lib/system/component-node.js | 15 + .../ember-htmlbars/lib/system/render-view.js | 34 +- .../ember-views/lib/compat/render_buffer.js | 605 ++++++++++++++++++ .../lib/mixins/template_rendering_support.js | 3 - .../{system => compat}/render_buffer_test.js | 2 +- .../tests/compat/view_render_hook_test.js | 98 +++ 6 files changed, 720 insertions(+), 37 deletions(-) create mode 100644 packages/ember-views/lib/compat/render_buffer.js rename packages/ember-views/tests/{system => compat}/render_buffer_test.js (99%) create mode 100644 packages/ember-views/tests/compat/view_render_hook_test.js diff --git a/packages/ember-htmlbars/lib/system/component-node.js b/packages/ember-htmlbars/lib/system/component-node.js index 747375f5e36..56d3a558302 100644 --- a/packages/ember-htmlbars/lib/system/component-node.js +++ b/packages/ember-htmlbars/lib/system/component-node.js @@ -7,6 +7,7 @@ import setProperties from "ember-metal/set_properties"; import View from "ember-views/views/view"; import { MUTABLE_CELL } from "ember-views/compat/attrs-proxy"; import getCellOrValue from "ember-htmlbars/hooks/get-cell-or-value"; +import SafeString from "htmlbars-util/safe-string"; // In theory this should come through the env, but it should // be safe to import this until we make the hook system public @@ -105,6 +106,20 @@ ComponentNode.prototype.render = function(env, attrs, visitor) { if (component) { var element = this.expectElement && this.renderNode.firstNode; + if (component.render) { + var content, node, lastChildIndex; + var buffer = []; + component.render(buffer); + content = buffer.join(''); + if (element) { + lastChildIndex = this.renderNode.childNodes.length - 1; + node = this.renderNode.childNodes[lastChildIndex]; + } else { + node = this.renderNode; + } + node.setContent(new SafeString(content)); + } + env.renderer.didCreateElement(component, element); // 2.0TODO: Remove legacy hooks. env.renderer.willInsertElement(component, element); env.lifecycleHooks.push({ type: 'didInsertElement', view: component }); diff --git a/packages/ember-htmlbars/lib/system/render-view.js b/packages/ember-htmlbars/lib/system/render-view.js index 17e97465aa4..5224652cf4e 100644 --- a/packages/ember-htmlbars/lib/system/render-view.js +++ b/packages/ember-htmlbars/lib/system/render-view.js @@ -1,23 +1,6 @@ -import Ember from "ember-metal/core"; import defaultEnv from "ember-htmlbars/env"; -import { get } from "ember-metal/property_get"; import ComponentNode, { createOrUpdateComponent } from "ember-htmlbars/system/component-node"; -export default function renderView(view, buffer, template) { - if (!template) { - return; - } - - var output; - - Ember.assert('template must be a function. Did you mean to call Ember.Handlebars.compile("...") or specify templateName instead?', typeof template === 'function'); - output = renderLegacyTemplate(view, buffer, template); - - if (output !== undefined) { - buffer.push(output); - } -} - // This function only gets called once per render of a "root view" (`appendTo`). Otherwise, // HTMLBars propagates the existing env and renders templates for a given render node. export function renderHTMLBarsBlock(view, block, renderNode) { @@ -36,22 +19,7 @@ export function renderHTMLBarsBlock(view, block, renderNode) { view.env = env; createOrUpdateComponent(view, {}, renderNode, env); - var componentNode = new ComponentNode(view, null, renderNode, block, true); + var componentNode = new ComponentNode(view, null, renderNode, block, view.tagName !== ''); componentNode.render(env, {}); } - -function renderLegacyTemplate(view, buffer, template) { - // FIXME: This should likely be removed. Adds support for bespoke kind-of-handlebars - // templates. They are used in tests, but nobody should be using them in the - // wild. - var context = get(view, 'context'); - var options = { - data: { - view: view, - buffer: buffer - } - }; - - return template(context, options); -} diff --git a/packages/ember-views/lib/compat/render_buffer.js b/packages/ember-views/lib/compat/render_buffer.js new file mode 100644 index 00000000000..539664de983 --- /dev/null +++ b/packages/ember-views/lib/compat/render_buffer.js @@ -0,0 +1,605 @@ +/** +@module ember +@submodule ember-views +*/ + +import jQuery from "ember-views/system/jquery"; +import Ember from "ember-metal/core"; +import o_create from 'ember-metal/platform/create'; +import { normalizeProperty } from "dom-helper/prop"; +import { canSetNameOnInputs } from "ember-views/system/platform"; + +// The HTML spec allows for "omitted start tags". These tags are optional +// when their intended child is the first thing in the parent tag. For +// example, this is a tbody start tag: +// +// +// +// +// +// The tbody may be omitted, and the browser will accept and render: +// +//
+// +// +// However, the omitted start tag will still be added to the DOM. Here +// we test the string and context to see if the browser is about to +// perform this cleanup, but with a special allowance for disregarding +//