Skip to content

Commit

Permalink
fix(html): expressions in table family elements
Browse files Browse the repository at this point in the history
  • Loading branch information
smalluban committed May 22, 2018
1 parent b2062c8 commit 87f7a55
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 23 deletions.
64 changes: 46 additions & 18 deletions src/html/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,20 +168,6 @@ function resolveProperty(attrName, propertyName, isSVG) {
}
}

function getPropertyName(string) {
return string.replace(/\s*=\s*['"]*$/g, '').split(' ').pop();
}

function createWalker(node) {
return document.createTreeWalker(
node,
// eslint-disable-next-line no-bitwise
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
null,
false,
);
}

const PLACEHOLDER = `{{h-${Date.now()}}}`;
const PLACEHOLDER_REGEXP = new RegExp(PLACEHOLDER, 'g');
const ATTR_PREFIX = `--${Date.now()}--`;
Expand Down Expand Up @@ -223,7 +209,14 @@ function applyShadyCSS(template, tagName) {
}

export function createSignature(parts) {
const signature = parts.join(PLACEHOLDER);
const signature = parts.reduce((acc, part, index) => {
if (index === 0) {
return part;
} else if (parts.slice(index).join('').match(/\s*<\/\s*(table|tr|thead|tbody|tfoot|colgroup)>/)) {
return `${acc}<!--${PLACEHOLDER}-->${part}`;
}
return acc + PLACEHOLDER + part;
}, '');

if (IS_IE) {
return signature.replace(
Expand All @@ -235,17 +228,52 @@ export function createSignature(parts) {
return signature;
}

function getPropertyName(string) {
return string.replace(/\s*=\s*['"]*$/g, '').split(' ').pop();
}

function createWalker(node) {
return document.createTreeWalker(
node,
// eslint-disable-next-line no-bitwise
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
null,
false,
);
}

function replaceComments(fragment) {
const iterator = document.createNodeIterator(fragment, NodeFilter.SHOW_COMMENT, null, false);
let node;
// eslint-disable-next-line no-cond-assign
while (node = iterator.nextNode()) {
if (node.textContent === PLACEHOLDER) {
node.parentNode.insertBefore(document.createTextNode(PLACEHOLDER), node);
node.parentNode.removeChild(node);
}
}
}

const container = document.createElement('div');
export function compile(signature, rawParts, isSVG) {
const template = document.createElement('template');
const parts = [];

template.innerHTML = signature;
if (IS_IE) {
template.innerHTML = signature;
} else {
container.innerHTML = `<template>${signature}</template>`;
template.content.appendChild(container.children[0].content);
}

if (isSVG) {
const svgRoot = template.content.firstChild;
template.content.removeChild(svgRoot);
Array.from(svgRoot.childNodes).forEach(node => template.content.appendChild(node));
}

replaceComments(template.content);

const compileWalker = createWalker(template.content);
let compileIndex = 0;

Expand Down Expand Up @@ -324,10 +352,10 @@ export function compile(signature, rawParts, isSVG) {
while (renderWalker.nextNode()) {
const node = renderWalker.currentNode;

if (IS_IE && node.nodeType === Node.TEXT_NODE) {
if (node.nodeType === Node.TEXT_NODE) {
if (node.textContent === PLACEHOLDER) {
node.textContent = '';
} else {
} else if (IS_IE) {
node.textContent = node.textContent.replace(ATTR_REGEXP, '');
}
}
Expand Down
5 changes: 0 additions & 5 deletions test/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ import '../shim';
// Set dynamic env variable
window.env = 'development';

// Set IS_IE to true for testing hacks for support style attribute on IE
if (!('ActiveXObject' in window)) {
window.ActiveXObject = {};
}

window.test = (html) => {
const template = document.createElement('template');
template.innerHTML = html;
Expand Down
11 changes: 11 additions & 0 deletions test/spec/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,17 @@ describe('html:', () => {
});
});

describe('table', () => {
it('should render table with rows', () => {
const renderRow = v => html`<tr><td>${v}</td></tr>`.key(v);
const renderTable = html`
<table>${[1, 2].map(v => renderRow(v))} ${[3, 4].map(v => renderRow(v))}</table>`;

renderTable({}, fragment);
expect(fragment.children[0].outerHTML).toBe('<table><tr><td>1</td></tr><tr><td>2</td></tr> <tr><td>3</td></tr><tr><td>4</td></tr></table>');
});
});

describe('resolve method', () => {
const render = (promise, value, placeholder) => html`
${html.resolve(promise.then(() => html`<div>${value}</div>`), placeholder)}`;
Expand Down

0 comments on commit 87f7a55

Please sign in to comment.