Skip to content

Commit

Permalink
Make server side rendering of Dynamic Elements work similar to the cl…
Browse files Browse the repository at this point in the history
…ient side version
  • Loading branch information
Alfred Ringstad committed Oct 1, 2020
1 parent d0d9dff commit 346eb46
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 36 deletions.
52 changes: 20 additions & 32 deletions src/compiler/compile/render_ssr/handlers/DynamicElement.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { is_void } from '../../../utils/names';
import {
get_attribute_value,
get_class_attribute_value
Expand All @@ -11,6 +10,7 @@ import ElementHandler from './Element';
import { x } from 'code-red';
import Expression from '../../nodes/shared/Expression';
import remove_whitespace_children from './utils/remove_whitespace_children';
import Element from '../../nodes/Element';

export default function (
node: DynamicElement,
Expand All @@ -19,19 +19,20 @@ export default function (
slot_scopes: Map<any, any>;
}
) {
if (typeof node.tag.node === 'string') {
node.name = node.tag.node;
ElementHandler(node as any, renderer, options);
const dependencies = node.tag.dynamic_dependencies();

if (dependencies.length === 0) {
((node as unknown) as Element).dynamic_tag = node.tag;
ElementHandler((node as unknown) as Element, renderer, options);
} else {
const children = remove_whitespace_children(node.children, node.next);

// awkward special case
let node_contents;

const contenteditable =
node.name !== 'textarea' &&
node.name !== 'input' &&
node.attributes.some((attribute) => attribute.name === 'contenteditable');
const contenteditable = node.attributes.some(
(attribute) => attribute.name === 'contenteditable'
);

const slot = node.get_static_attribute_value('slot');
const nearest_inline_component = node.find_nearest(/InlineComponent/);
Expand Down Expand Up @@ -63,9 +64,7 @@ export default function (
args.push(attribute.expression.node);
} else {
const name = attribute.name.toLowerCase();
if (name === 'value' && node.name.toLowerCase() === 'textarea') {
node_contents = get_attribute_value(attribute);
} else if (attribute.is_true) {
if (attribute.is_true) {
args.push(x`{ ${attribute.name}: true }`);
} else if (
boolean_attributes.has(name) &&
Expand All @@ -91,9 +90,7 @@ export default function (
let add_class_attribute = !!class_expression;
node.attributes.forEach((attribute) => {
const name = attribute.name.toLowerCase();
if (name === 'value' && node.name.toLowerCase() === 'textarea') {
node_contents = get_attribute_value(attribute);
} else if (attribute.is_true) {
if (attribute.is_true) {
renderer.add_string(` ${attribute.name}`);
} else if (
boolean_attributes.has(name) &&
Expand Down Expand Up @@ -160,9 +157,6 @@ export default function (

// TODO where was this used?
// value = name === 'textContent' ? x`@escape($$value)` : x`$$value`;
} else if (binding.name === 'value' && node.name === 'textarea') {
const snippet = expression.node;
node_contents = x`${snippet} || ""`;
} else {
const snippet = expression.node;
renderer.add_expression(x`@add_attribute("${name}", ${snippet}, 1)`);
Expand All @@ -188,19 +182,15 @@ export default function (
renderer.add_expression(node_contents);
}

if (!is_void(node.name)) {
renderer.add_string('</');
renderer.add_expression(node.tag.node);
renderer.add_string('>');
}
renderer.add_string('</');
renderer.add_expression(node.tag.node);
renderer.add_string('>');
} else if (slot && nearest_inline_component) {
renderer.render(children, options);

if (!is_void(node.name)) {
renderer.add_string('</');
renderer.add_expression(node.tag.node);
renderer.add_string('>');
}
renderer.add_string('</');
renderer.add_expression(node.tag.node);
renderer.add_string('>');

const lets = node.lets;
const seen = new Set(lets.map((l) => l.name.name));
Expand All @@ -216,11 +206,9 @@ export default function (
} else {
renderer.render(children, options);

if (!is_void(node.name)) {
renderer.add_string('</');
renderer.add_expression(node.tag.node);
renderer.add_string('>');
}
renderer.add_string('</');
renderer.add_expression(node.tag.node);
renderer.add_string('>');
}
}
}
31 changes: 27 additions & 4 deletions src/compiler/compile/render_ssr/handlers/Element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
renderer.push();
}

renderer.add_string(`<${node.name}`);
if (node.dynamic_tag) {
renderer.add_string('<');
renderer.add_expression(node.dynamic_tag.node);
} else {
renderer.add_string(`<${node.name}`);
}

const class_expression_list = node.classes.map(class_directive => {
const { expression, name } = class_directive;
Expand Down Expand Up @@ -146,13 +151,25 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
}

if (!is_void(node.name)) {
renderer.add_string(`</${node.name}>`);
if (node.dynamic_tag) {
renderer.add_string('</');
renderer.add_expression(node.dynamic_tag.node);
renderer.add_string('>');
} else {
renderer.add_string(`</${node.name}>`);
}
}
} else if (slot && nearest_inline_component) {
renderer.render(children, options);

if (!is_void(node.name)) {
renderer.add_string(`</${node.name}>`);
if (node.dynamic_tag) {
renderer.add_string('</');
renderer.add_expression(node.dynamic_tag.node);
renderer.add_string('>');
} else {
renderer.add_string(`</${node.name}>`);
}
}

const lets = node.lets;
Expand All @@ -170,7 +187,13 @@ export default function(node: Element, renderer: Renderer, options: RenderOption
renderer.render(children, options);

if (!is_void(node.name)) {
renderer.add_string(`</${node.name}>`);
if (node.dynamic_tag) {
renderer.add_string('</');
renderer.add_expression(node.dynamic_tag.node);
renderer.add_string('>');
} else {
renderer.add_string(`</${node.name}>`);
}
}
}
}
Expand Down

0 comments on commit 346eb46

Please sign in to comment.