Skip to content

Commit

Permalink
Ensure domNode is renamed to mount
Browse files Browse the repository at this point in the history
  • Loading branch information
tbranyen committed Apr 30, 2021
1 parent 7820d2e commit 124fb35
Show file tree
Hide file tree
Showing 41 changed files with 361 additions and 278 deletions.
2 changes: 1 addition & 1 deletion packages/babel-plugin-transform-diffhtml/.babelrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"env": {
"test": {
"plugins": [["module:.", { "createTree": "createTree" }]]
"plugins": [["module:.", { "createTree": "html" }]]
}
},

Expand Down
77 changes: 43 additions & 34 deletions packages/babel-plugin-transform-diffhtml/lib/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Internals } from 'diffhtml';
import { createTree, Internals } from 'diffhtml';
import * as babylon from 'babylon';

const { parse } = Internals;
const hasNonWhitespaceEx = /\S/;
const TOKEN = '__DIFFHTML_BABEL__';
const doctypeEx = /<!.*>/i;
const tokenEx = /__DIFFHTML_BABEL__([^_]*)__/;
const isPropEx = /(=|'|")/;
const isAttributeEx = /(=|"|')[^><]*?$/;
const isTagEx = /(<|\/)/;
let ident = {};

/**
* Transpiles a matching tagged template literal to createTree calls, the
Expand All @@ -17,7 +17,7 @@ const isTagEx = /(<|\/)/;
* @return {Object} containing the visitor handler.
*/
export default function({ types: t }) {
const interpolateValues = (string, supplemental, createTree) => {
const interpolateValues = (string, supplemental, createTreeNode) => {
// If this is text and not a doctype, add as a text node.
if (string && !doctypeEx.test(string) && !tokenEx.test(string)) {
return t.arrayExpression([t.stringLiteral('#text'), t.stringLiteral(string)]);
Expand All @@ -34,23 +34,25 @@ export default function({ types: t }) {
// the token's position. So all we do is ensure that we're on an odd
// index and then we can source the correct value.
if (i % 2 === 1) {
const innerTree = supplemental.children[value];
const isFragment = innerTree.nodeType === 11;
const nextValue = supplemental.children[value];
const isFragment = nextValue && nextValue.nodeType === 11;

if (typeof innerTree.rawNodeName === 'string' && isFragment) {
childNodes.push(...innerTree.childNodes);
if (!nextValue) continue;

if (typeof nextValue.rawNodeName === 'string' && isFragment) {
childNodes.push(...nextValue.childNodes);
}
else {
if (innerTree.type === 'StringLiteral' || innerTree.type === 'NumberLiteral') {
childNodes.push(t.callExpression(createTree, [t.stringLiteral('#text'), innerTree]));
if (nextValue.type === 'StringLiteral' || nextValue.type === 'NumberLiteral') {
childNodes.push(t.callExpression(createTreeNode, [t.stringLiteral('#text'), nextValue]));
}
else {
childNodes.push(innerTree);
childNodes.push(nextValue);
}
}
}
else if (!doctypeEx.test(value)) {
childNodes.push(t.callExpression(createTree, [t.stringLiteral('#text'), t.stringLiteral(value)]));
else if (!doctypeEx.test(value) && value) {
childNodes.push(t.callExpression(createTreeNode, [t.stringLiteral('#text'), t.stringLiteral(value)]));
}
}

Expand All @@ -59,13 +61,13 @@ export default function({ types: t }) {
// If no children were present, send back an empty text node.
if (childNodes.length === 0) {
retVal = t.callExpression(
createTree,
createTreeNode,
[t.stringLiteral('#text'), t.stringLiteral('')],
);
}
// Wrap multiple nodes in a fragment.
else if (childNodes.length > 1) {
retVal = t.callExpression(createTree, [
retVal = t.callExpression(createTreeNode, [
t.stringLiteral('#document-fragment'),
t.arrayExpression(childNodes),
]);
Expand All @@ -80,22 +82,32 @@ export default function({ types: t }) {
// Takes in a dot-notation identifier and breaks it up into a
// MemberExpression. Useful for configuration overrides specifying the
// tagged template function name and createTree calls.
const identifierToMemberExpression = identifier => {
const identifierToMemberExpression = (path, identifier) => {
const identifiers = identifier.split('.');

if (identifiers.length === 0) {
return;
}
else if (identifiers.length === 1) {
return t.identifier(identifiers[0]);
if (!ident[identifiers[0]]) {
ident[identifiers[0]] = t.identifier(identifiers[0]);
}

return ident[identifiers[0]];
}
else {
return identifiers.reduce((memo, identifier) => {
if (!ident[identifier]) {
ident[identifier] = t.identifier(identifier);
}

identifier = ident[identifier];

if (!memo) {
memo = t.identifier(identifier);
memo = identifier;
}
else {
memo = t.memberExpression(memo, t.identifier(identifier));
memo = t.memberExpression(memo, identifier);
}

return memo;
Expand Down Expand Up @@ -163,10 +175,9 @@ export default function({ types: t }) {

// Used to store markup and tokens.
let HTML = '';
const dynamicBits = [];

// Nearly identical logic to the diffHTML parser, as we have the static
// vs dynamic parts pre-separated for us and we simply need to fuse them
// Nearly identical logic to the core parser, as we have the static vs
// dynamic parts pre-separated for us and we simply need to fuse them
// together.
quasis.forEach((quasi, i) => {
HTML += quasi.value.raw;
Expand All @@ -178,9 +189,6 @@ export default function({ types: t }) {
const isAttribute = Boolean(HTML.match(isAttributeEx));
const isTag = Boolean(lastCharacter.match(isTagEx));
const isString = expression.type === 'StringLiteral';
const isObject = expression.type === 'ObjectExpression';
const isArray = expression.type === 'ArrayExpression';
const isIdentifier = expression.type === 'Identifier';
const token = TOKEN + i + '__';

// Injected as attribute.
Expand Down Expand Up @@ -231,9 +239,9 @@ export default function({ types: t }) {
const strRoot = JSON.stringify(root.length === 1 ? root[0] : root);
const vTree = babylon.parse('(' + strRoot + ')');

const createTree = plugin.opts.createTree ?
identifierToMemberExpression(plugin.opts.createTree) :
identifierToMemberExpression('diff.createTree');
const createTreeNode = plugin.opts.createTree ?
identifierToMemberExpression(path, plugin.opts.createTree) :
identifierToMemberExpression(path, 'diff.createTree');

/**
* Replace the dynamic parts of the AST with the actual quasi
Expand Down Expand Up @@ -358,7 +366,7 @@ export default function({ types: t }) {

const token = rawNodeName.value.match(tokenEx);

args.push(createTree, [
args.push(createTreeNode, [
identifierIsInScope ? t.identifier(rawNodeName.value) : (token ? supplemental.tags[token[1]] : rawNodeName),
attributes,
t.arrayExpression(expressions.map(expr => expr.expression)),
Expand All @@ -369,13 +377,13 @@ export default function({ types: t }) {
let value = nodeValue.value || '';

if (value.match(tokenEx)) {
const values = interpolateValues(value, supplemental, createTree);
const values = interpolateValues(value, supplemental, createTreeNode);

if (values.elements.length === 1) {
args.replacement = values.elements[0];
}
else {
args.push(createTree, [t.stringLiteral('#document-fragment'), values]);
args.push(createTreeNode, [t.stringLiteral('#document-fragment'), values]);
}

isDynamic = true;
Expand All @@ -385,13 +393,13 @@ export default function({ types: t }) {

path.scope.parent.push({
id,
init: t.callExpression(createTree, [
init: t.callExpression(createTreeNode, [
t.stringLiteral('#text'),
nodeValue,
]),
});

args.replacement = t.callExpression(createTree, [
args.replacement = t.callExpression(createTreeNode, [
t.stringLiteral('#text'),
nodeValue,
]);
Expand Down Expand Up @@ -420,18 +428,19 @@ export default function({ types: t }) {

replaceDynamicBits([...vTree.program.body]);

//if (vTree.program.body.length > 1) {
// If an array is returned convert to an inlined document fragment.
if (t.isArrayExpression(vTree.program.body[0].expression)) {
path.replaceWith(
t.callExpression(
createTree,
createTreeNode,
[
t.stringLiteral('#document-fragment'),
vTree.program.body[0].expression,
],
),
);
}
// Otherwise inline the expression itself.
else {
path.replaceWith(vTree.program.body[0]);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-plugin-transform-diffhtml/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"build": "npm run clean && NODE_ENV=umd browserify --im -x diffhtml -u diffhtml -s transform -g babelify lib/index.js -x ./global.js -o dist/index.js",
"clean": "rm -rf dist/* && mkdir -p dist",
"watch": "NODE_ENV=umd watchify --im -s transform -g babelify lib/index.js -o dist/index.js -v",
"build-fixtures": "NODE_ENV=umd babel --ignore node_modules test/fixtures.js -o test/.__fixtures__.js",
"build-fixtures": "NODE_ENV=test babel --ignore node_modules test/fixtures.js -o test/.__fixtures__.js",
"test": "NODE_ENV=test npm run build-fixtures && mocha test/_setup test/assertions",
"test:ci": "npm run test",
"test-watch": "npm run test -- -w"
Expand Down
8 changes: 7 additions & 1 deletion packages/babel-plugin-transform-diffhtml/test/fixtures.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const { html } = require('diffhtml');
const { html } = require('diffhtml/dist/cjs/lite');

BASICS: {

Expand Down Expand Up @@ -151,6 +151,12 @@ BUG_FIXES: {
</div>`;
};

exports.supportsChildNodes = () => {
const boolean = false;

return html`<div childNodes=${boolean}></div>`;
};

}

FRAGMENTS: {
Expand Down
4 changes: 2 additions & 2 deletions packages/diffhtml-devtools/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
const { use, html, innerHTML, outerHTML } = diff;

// Current broken and not letting text update for some reason...
use(inlineTransitions());
use(logger());
//use(inlineTransitions());
//use(logger());

const animate = (el, ...args) => new Promise(resolve => el.animate(
...args
Expand Down
14 changes: 14 additions & 0 deletions packages/diffhtml-devtools/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"strict": true,
"target": "es2017",
"declaration": true,
"checkJs": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"outDir": "./dist/typings",
"lib": ["es2017", "dom"],
"moduleResolution": "node"
},
"include": ["lib/**/*"],
}
13 changes: 7 additions & 6 deletions packages/diffhtml-devtools/lib/scripts/bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,20 @@ export default function devTools(Internals) {

function devToolsTask(transaction) {
const {
domNode, markup, options, state: { newTree }, state
mount, markup, config, state: { newTree }, state
} = transaction;

const isFunction = typeof domNode.rawNodeName === 'function';
const selector = unique(domNode) ||
`${isFunction ? domNode.rawNodeName.displayName || domNode.rawNodeName.name : domNode.rawNodeName}`;
const isFunction = typeof mount.rawNodeName === 'function';
const selector = unique(mount) ||
`${isFunction ? mount.rawNodeName.displayName || mount.rawNodeName.name : mount.rawNodeName}`;
const startDate = performance.now();

const start = () => {
console.log('Start transaction');
return extension.startTransaction(startDate, {
domNode: selector,
markup,
options,
options: config,
state: assign({}, state, state.nextTransaction && {
nextTransaction: undefined,
}, {
Expand Down Expand Up @@ -173,7 +174,7 @@ export default function devTools(Internals) {
const stop = () => extension.endTransaction(startDate, endDate, {
domNode: selector,
markup,
options,
options: config,
state: assign({}, state, state.nextTransaction && {
nextTransaction: undefined,
}, {
Expand Down
8 changes: 4 additions & 4 deletions packages/diffhtml-devtools/lib/scripts/components/footer.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { html } from 'diffhtml';
import { WebComponent } from 'diffhtml-components';
import { Component } from 'diffhtml-components';

class DevtoolsFooter extends WebComponent {
static propTypes = {
version: String,
class DevtoolsFooter extends Component {
static defaultProps = {
version: '',
}

render() {
Expand Down
18 changes: 12 additions & 6 deletions packages/diffhtml-devtools/lib/scripts/components/navigation.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { html } from 'diffhtml';
import { WebComponent } from 'diffhtml-components';
import { Component } from 'diffhtml-components';

class DevtoolsNavigation extends WebComponent {
static propTypes = {
activeRoute: String,
class DevtoolsNavigation extends Component {
static defaultProps = {
activeRoute: '',
}

render() {
const { activeRoute = '' } = this.props;
const { nav, selected } = this.state;
const { nav } = this.state;

return html`
<link rel="stylesheet" href="/styles/theme.css">
Expand All @@ -21,7 +21,7 @@ class DevtoolsNavigation extends WebComponent {
<span class="label">
${item.icon && html`<i class="${item.icon} icon" />`}
${item.label}
${item.subLabel && html`<span class="faded">${item.subLabel}</span>`}
${/*${item.subLabel && html`<span class="faded">${item.subLabel}</span>`}*/void 0}
</span>
</li>
`)}
Expand Down Expand Up @@ -145,6 +145,9 @@ class DevtoolsNavigation extends WebComponent {
],
}

/**
* @param {typeof DevtoolsNavigation['defaultProps']} nextProps
*/
componentWillReceiveProps(nextProps) {
if (!nextProps.activeRoute) { return; }
const route = nextProps.activeRoute.slice(1);
Expand All @@ -154,6 +157,9 @@ class DevtoolsNavigation extends WebComponent {
this.state.selected = selected;
}

/**
* @param {number} index
*/
onClick = index => {
const { nav } = this.state;
location.hash = nav[index].route;
Expand Down
10 changes: 5 additions & 5 deletions packages/diffhtml-devtools/lib/scripts/components/panels.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { html } from 'diffhtml';
import { WebComponent } from 'diffhtml-components';
import { Component } from 'diffhtml-components';

class DevtoolsPanels extends WebComponent {
static propTypes = {
route: String,
activeRoute: String,
class DevtoolsPanels extends Component {
static defaultProps = {
route: '',
activeRoute: '',
}

render() {
Expand Down
Loading

0 comments on commit 124fb35

Please sign in to comment.