@begin/enhance
Advanced tools
Comparing version 0.0.4 to 0.0.5
164
index.js
import path from 'path' | ||
import { parse, parseFragment as fragment, serialize } from 'parse5' | ||
import { parse, fragment, serialize } from '@begin/parse5' | ||
import isCustomElement from './lib/is-custom-element.js' | ||
@@ -33,13 +33,31 @@ const TEMPLATES = path.join('..', 'views', 'templates') | ||
function findSlots(node) { | ||
const state = {} | ||
let place = 0 | ||
export function encode(value) { | ||
if (typeof value !== 'string') { | ||
const id = `__b_${place++}` | ||
state[id] = value | ||
return id | ||
} | ||
else { | ||
return value | ||
} | ||
} | ||
function processCustomElements(node, templates) { | ||
const elements = [] | ||
const find = (node) => { | ||
for (const child of node.childNodes) { | ||
if (child.tagName === 'slot') { | ||
if (isCustomElement(child.tagName)) { | ||
elements.push(child) | ||
const template = expandTemplate(child, templates) | ||
fillSlots(child, template) | ||
const nodeChildNodes = child.childNodes | ||
nodeChildNodes.splice( | ||
0, | ||
nodeChildNodes.length, | ||
...template.childNodes | ||
) | ||
} | ||
if (!isCustomElement(child.tagName) && | ||
child.childNodes) { | ||
find(child) | ||
} | ||
if (child.childNodes) find(child) | ||
} | ||
@@ -51,24 +69,28 @@ } | ||
function findInserts(node) { | ||
const elements = [] | ||
const find = (node) => { | ||
for (const child of node.childNodes) { | ||
const attrs = child.attrs | ||
if (attrs) { | ||
for (let i=0; i < attrs.length; i++) { | ||
if (attrs[i].name === 'slot') { | ||
elements.push(child) | ||
} | ||
} | ||
} | ||
if (!isCustomElement(child.tagName) && | ||
child.childNodes) { | ||
find(child) | ||
} | ||
} | ||
function expandTemplate(node, templates) { | ||
return fragment(renderTemplate(node.tagName, templates, node.attrs) || '') | ||
} | ||
function renderTemplate(tagName, templates, attrs) { | ||
const templatePath = `${templates}/${tagName}.js` | ||
try { | ||
return require(templatePath) | ||
.default(attrs && attrsToState(attrs), render) | ||
} | ||
find(node) | ||
return elements | ||
catch { | ||
console.warn(`🤷🏻♀️ Template file not found at: ${templatePath}`) | ||
} | ||
} | ||
function attrsToState(attrs, state={}) { | ||
[...attrs].forEach(attr => state[attr.name] = decode(attr.value)) | ||
return state | ||
} | ||
export function decode(value) { | ||
return value.startsWith('__b_') | ||
? state[value] | ||
: value | ||
} | ||
function fillSlots(node, template) { | ||
@@ -78,8 +100,10 @@ const slots = findSlots(template) | ||
for (let i=0; i < slots.length; i++) { | ||
const slotsLength = slots.length | ||
for (let i=0; i<slotsLength; i++) { | ||
let hasSlotName = false | ||
const slot = slots[i] | ||
const slotAttrs = slot.attrs || [] | ||
let hasSlotName = false | ||
for (let i=0; i < slotAttrs.length; i++) { | ||
const slotAttrsLength = slotAttrs.length | ||
for (let i=0; i < slotAttrsLength; i++) { | ||
const attr = slotAttrs[i] | ||
@@ -90,7 +114,9 @@ if (attr.name === 'name') { | ||
for (let i=0; i < inserts.length; i ++) { | ||
const insertsLength = inserts.length | ||
for (let i=0; i < insertsLength; i ++) { | ||
const insert = inserts[i] | ||
const insertAttrs = insert.attrs || [] | ||
for (let i=0; i < insertAttrs.length; i++) { | ||
const insertAttrsLength = insertAttrs.length | ||
for (let i=0; i < insertAttrsLength; i++) { | ||
const attr = insertAttrs[i] | ||
@@ -126,18 +152,13 @@ const insertSlot = attr.value | ||
function processCustomElements(node, templates) { | ||
function findSlots(node) { | ||
const elements = [] | ||
const find = (node) => { | ||
for (const child of node.childNodes) { | ||
if (isCustomElement(child.tagName)) { | ||
if (child.tagName === 'slot') { | ||
elements.push(child) | ||
const template = expandTemplate(child, templates) | ||
fillSlots(child, template) | ||
const nodeChildNodes = child.childNodes | ||
nodeChildNodes.splice( | ||
0, | ||
nodeChildNodes.length, | ||
...template.childNodes | ||
) | ||
} | ||
if (child.childNodes) find(child) | ||
if (!isCustomElement(child.tagName) && | ||
child.childNodes) { | ||
find(child) | ||
} | ||
} | ||
@@ -149,24 +170,22 @@ } | ||
function expandTemplate(node, templates) { | ||
return fragment(renderTemplate(node.tagName, templates, node.attrs) || '') | ||
} | ||
function addScriptTags(body, scripts) { | ||
body.childNodes.push(...scripts.childNodes) | ||
} | ||
function attrsToState(attrs, state={}) { | ||
[...attrs].forEach(attr => state[attr.name] = decode(attr.value)) | ||
return state | ||
} | ||
function renderTemplate(tagName, templates, attrs) { | ||
const templatePath = `${templates}/${tagName}.js` | ||
try { | ||
return require(templatePath) | ||
.default(attrs && attrsToState(attrs), render) | ||
function findInserts(node) { | ||
const elements = [] | ||
const find = (node) => { | ||
for (const child of node.childNodes) { | ||
const attrs = child.attrs | ||
if (attrs) { | ||
for (let i=0; i < attrs.length; i++) { | ||
if (attrs[i].name === 'slot') { | ||
elements.push(child) | ||
} | ||
} | ||
} | ||
if (!isCustomElement(child.tagName) && | ||
child.childNodes) { | ||
find(child) | ||
} | ||
} | ||
} | ||
catch { | ||
console.warn(`🤷🏻♀️ Template file not found at: ${templatePath}`) | ||
} | ||
find(node) | ||
return elements | ||
} | ||
@@ -180,19 +199,4 @@ | ||
const state = {} | ||
let place = 0 | ||
export function encode(value) { | ||
if (typeof value !== 'string') { | ||
const id = `__b_${place++}` | ||
state[id] = value | ||
return id | ||
} | ||
else { | ||
return value | ||
} | ||
function addScriptTags(body, scripts) { | ||
body.childNodes.push(...scripts.childNodes) | ||
} | ||
export function decode(value) { | ||
return value.startsWith('__b_') | ||
? state[value] | ||
: value | ||
} |
{ | ||
"name": "@begin/enhance", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "Custom Element Server-side rendering CESR", | ||
@@ -17,5 +17,5 @@ "main": "index.js", | ||
"dependencies": { | ||
"parse5": "^6.0.1", | ||
"@begin/parse5": "^0.0.2", | ||
"esm": "^3.2.25" | ||
} | ||
} |
import test from 'tape' | ||
import enhance from '..' | ||
// Timed version | ||
//import enhance from '../timed.js' | ||
const strip = str => str.replace(/\r?\n|\r|\s\s+/g, '') | ||
@@ -13,8 +15,18 @@ | ||
test('enhance should exist', t => { | ||
t.ok(html) | ||
test('Enhance should', t => { | ||
t.ok(true, 'it really should') | ||
t.end() | ||
}) | ||
test('should expand template', t=> { | ||
test('exist', t => { | ||
t.ok(enhance, 'it lives') | ||
t.end() | ||
}) | ||
test('return an html function', t => { | ||
t.ok(html, 'ah yes, this might come in handy') | ||
t.end() | ||
}) | ||
test('expand template', t=> { | ||
const actual = html`<my-paragraph></my-paragraph>` | ||
@@ -30,3 +42,3 @@ const expected = doc(` | ||
strip(expected), | ||
'expands template with slot default content correctly' | ||
'by gum, i do believe that it does expand that template with slotted default content' | ||
) | ||
@@ -36,3 +48,3 @@ t.end() | ||
test('should fill named slot', t=> { | ||
test('fill named slot', t=> { | ||
const actual = html` | ||
@@ -52,3 +64,3 @@ <my-paragraph> | ||
strip(expected), | ||
'Fills named slot' | ||
'fills that named slot alright' | ||
) | ||
@@ -58,3 +70,3 @@ t.end() | ||
test('should add authored children to unnamed slot.', t=> { | ||
test('add authored children to unnamed slot', t=> { | ||
const actual = html` | ||
@@ -76,3 +88,3 @@ <my-content> | ||
strip(expected), | ||
'Adds unslotted children to unnamed slot' | ||
'adds unslotted children to the unnamed slot' | ||
) | ||
@@ -82,3 +94,3 @@ t.end() | ||
test('should pass attributes as state', t=> { | ||
test('pass attributes as state', t=> { | ||
const actual = html` | ||
@@ -96,3 +108,3 @@ <my-link href='/yolo' text='sketchy'></my-link> | ||
strip(expected), | ||
'Passes attributes as state' | ||
'passes attributes as a state object when executing template functions' | ||
) | ||
@@ -102,3 +114,3 @@ t.end() | ||
test('should pass attribute array values correctly', t => { | ||
test('pass attribute array values correctly', t => { | ||
const things = [{ title: 'one' },{ title: 'two' },{ title: 'three' }] | ||
@@ -124,3 +136,3 @@ const actual = html` | ||
strip(expected), | ||
'Passes complex attribute as state' | ||
'this means that encoding and decoding arrays and objects works, exciting' | ||
) | ||
@@ -131,3 +143,3 @@ t.end() | ||
test('should update deeply nested slots', t=> { | ||
test('update deeply nested slots', t=> { | ||
const actual = html` | ||
@@ -164,3 +176,3 @@ <my-content> | ||
strip(expected), | ||
'Updates deeply nested slots' | ||
'updates deeply nested slots SLOTS ON SLOTS ON SLOTS' | ||
) | ||
@@ -170,3 +182,3 @@ t.end() | ||
test('should fill nested rendered slots', t=> { | ||
test('fill nested rendered slots', t=> { | ||
const items = [{ title: 'one' },{ title: 'two' },{ title: 'three' }] | ||
@@ -199,3 +211,3 @@ const actual = html` | ||
strip(expected), | ||
'Renders nested custom elements by passing html function' | ||
'Wow it renders nested custom elements by passing that handy render function when executing template functions' | ||
) | ||
@@ -205,8 +217,9 @@ t.end() | ||
test('should not throw when template not found', t => { | ||
test('not throw when template not found', t => { | ||
t.ok( | ||
html`<missing-template></missing-template>`, | ||
'Warns instead of throwing.' | ||
'well that\'s nice, it warns instead of throwing.' | ||
) | ||
t.end() | ||
}) | ||
18165
13
660
3
+ Added@begin/parse5@^0.0.2
+ Added@begin/parse5@0.0.2(transitive)
+ Added@jridgewell/gen-mapping@0.3.8(transitive)
+ Added@jridgewell/resolve-uri@3.1.2(transitive)
+ Added@jridgewell/set-array@1.2.1(transitive)
+ Added@jridgewell/source-map@0.3.6(transitive)
+ Added@jridgewell/sourcemap-codec@1.5.0(transitive)
+ Added@jridgewell/trace-mapping@0.3.25(transitive)
+ AddedJSONStream@1.3.5(transitive)
+ Addedacorn@7.4.18.14.0(transitive)
+ Addedacorn-node@1.8.2(transitive)
+ Addedacorn-walk@7.2.0(transitive)
+ Addedasn1.js@4.10.1(transitive)
+ Addedassert@1.5.1(transitive)
+ Addedavailable-typed-arrays@1.0.7(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbase64-js@1.5.1(transitive)
+ Addedbn.js@4.12.15.2.1(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedbrorand@1.1.0(transitive)
+ Addedbrowser-pack@6.1.0(transitive)
+ Addedbrowser-resolve@2.0.0(transitive)
+ Addedbrowserify@17.0.1(transitive)
+ Addedbrowserify-aes@1.2.0(transitive)
+ Addedbrowserify-cipher@1.0.1(transitive)
+ Addedbrowserify-des@1.0.2(transitive)
+ Addedbrowserify-rsa@4.1.1(transitive)
+ Addedbrowserify-sign@4.2.3(transitive)
+ Addedbrowserify-zlib@0.2.0(transitive)
+ Addedbuffer@5.2.1(transitive)
+ Addedbuffer-from@1.1.2(transitive)
+ Addedbuffer-xor@1.0.3(transitive)
+ Addedbuiltin-status-codes@3.0.0(transitive)
+ Addedcached-path-relative@1.1.0(transitive)
+ Addedcall-bind@1.0.8(transitive)
+ Addedcall-bind-apply-helpers@1.0.1(transitive)
+ Addedcall-bound@1.0.3(transitive)
+ Addedcipher-base@1.0.6(transitive)
+ Addedcombine-source-map@0.8.0(transitive)
+ Addedcommander@2.20.3(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedconcat-stream@1.6.2(transitive)
+ Addedconsole-browserify@1.2.0(transitive)
+ Addedconstants-browserify@1.0.0(transitive)
+ Addedconvert-source-map@1.1.3(transitive)
+ Addedcore-util-is@1.0.3(transitive)
+ Addedcreate-ecdh@4.0.4(transitive)
+ Addedcreate-hash@1.2.0(transitive)
+ Addedcreate-hmac@1.1.7(transitive)
+ Addedcrypto-browserify@3.12.1(transitive)
+ Addeddash-ast@1.0.0(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addeddefine-properties@1.2.1(transitive)
+ Addeddefined@1.0.1(transitive)
+ Addeddeps-sort@2.0.1(transitive)
+ Addeddes.js@1.1.0(transitive)
+ Addeddetective@5.2.1(transitive)
+ Addeddiffie-hellman@5.0.3(transitive)
+ Addeddomain-browser@1.2.0(transitive)
+ Addeddunder-proto@1.0.1(transitive)
+ Addedduplexer2@0.1.4(transitive)
+ Addedelliptic@6.6.1(transitive)
+ Addedes-define-property@1.0.1(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedes-object-atoms@1.1.1(transitive)
+ Addedevents@3.3.0(transitive)
+ Addedevp_bytestokey@1.0.3(transitive)
+ Addedfast-safe-stringify@2.1.1(transitive)
+ Addedfor-each@0.3.4(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-assigned-identifiers@1.2.0(transitive)
+ Addedget-intrinsic@1.2.7(transitive)
+ Addedget-proto@1.0.1(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedgopd@1.2.0(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-symbols@1.1.0(transitive)
+ Addedhas-tostringtag@1.0.2(transitive)
+ Addedhash-base@3.0.5(transitive)
+ Addedhash.js@1.1.7(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedhmac-drbg@1.0.1(transitive)
+ Addedhtmlescape@1.1.1(transitive)
+ Addedhttps-browserify@1.0.0(transitive)
+ Addedieee754@1.2.1(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.32.0.4(transitive)
+ Addedinline-source-map@0.6.3(transitive)
+ Addedinsert-module-globals@7.2.1(transitive)
+ Addedis-arguments@1.2.0(transitive)
+ Addedis-buffer@1.1.6(transitive)
+ Addedis-callable@1.2.7(transitive)
+ Addedis-core-module@2.16.1(transitive)
+ Addedis-generator-function@1.1.0(transitive)
+ Addedis-regex@1.2.1(transitive)
+ Addedis-typed-array@1.1.15(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedjsonparse@1.3.1(transitive)
+ Addedlabeled-stream-splicer@2.0.2(transitive)
+ Addedlodash.memoize@3.0.4(transitive)
+ Addedmath-intrinsics@1.1.0(transitive)
+ Addedmd5.js@1.3.5(transitive)
+ Addedmiller-rabin@4.0.1(transitive)
+ Addedminimalistic-assert@1.0.1(transitive)
+ Addedminimalistic-crypto-utils@1.0.1(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedmkdirp-classic@0.5.3(transitive)
+ Addedmodule-deps@6.2.3(transitive)
+ Addedobject-inspect@1.13.4(transitive)
+ Addedobject-keys@1.1.1(transitive)
+ Addedobject.assign@4.1.7(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedos-browserify@0.3.0(transitive)
+ Addedpako@1.0.11(transitive)
+ Addedparents@1.0.1(transitive)
+ Addedparse-asn1@5.1.7(transitive)
+ Addedpath-browserify@1.0.1(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedpath-parse@1.0.7(transitive)
+ Addedpath-platform@0.11.15(transitive)
+ Addedpbkdf2@3.1.2(transitive)
+ Addedpossible-typed-array-names@1.1.0(transitive)
+ Addedprocess@0.11.10(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedpublic-encrypt@4.0.3(transitive)
+ Addedpunycode@1.4.1(transitive)
+ Addedqs@6.14.0(transitive)
+ Addedquerystring-es3@0.2.1(transitive)
+ Addedrandombytes@2.1.0(transitive)
+ Addedrandomfill@1.0.4(transitive)
+ Addedread-only-stream@2.0.0(transitive)
+ Addedreadable-stream@2.3.83.6.2(transitive)
+ Addedresolve@1.22.10(transitive)
+ Addedripemd160@2.0.2(transitive)
+ Addedsafe-buffer@5.1.25.2.1(transitive)
+ Addedsafe-regex-test@1.1.0(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedsha.js@2.4.11(transitive)
+ Addedshasum-object@1.0.0(transitive)
+ Addedshell-quote@1.8.2(transitive)
+ Addedside-channel@1.1.0(transitive)
+ Addedside-channel-list@1.0.0(transitive)
+ Addedside-channel-map@1.0.1(transitive)
+ Addedside-channel-weakmap@1.0.2(transitive)
+ Addedsimple-concat@1.0.1(transitive)
+ Addedsource-map@0.5.70.6.1(transitive)
+ Addedsource-map-support@0.5.21(transitive)
+ Addedstream-browserify@3.0.0(transitive)
+ Addedstream-combiner2@1.1.1(transitive)
+ Addedstream-http@3.2.0(transitive)
+ Addedstream-splicer@2.0.1(transitive)
+ Addedstring_decoder@1.1.11.3.0(transitive)
+ Addedsubarg@1.0.0(transitive)
+ Addedsupports-preserve-symlinks-flag@1.0.0(transitive)
+ Addedsyntax-error@1.4.0(transitive)
+ Addedterser@5.38.1(transitive)
+ Addedthrough@2.3.8(transitive)
+ Addedthrough2@2.0.5(transitive)
+ Addedtimers-browserify@1.4.2(transitive)
+ Addedtty-browserify@0.0.1(transitive)
+ Addedtypedarray@0.0.6(transitive)
+ Addedumd@3.0.3(transitive)
+ Addedundeclared-identifiers@1.1.3(transitive)
+ Addedurl@0.11.4(transitive)
+ Addedutil@0.10.40.12.5(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addedvm-browserify@1.1.2(transitive)
+ Addedwhich-typed-array@1.1.18(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedxtend@4.0.2(transitive)
- Removedparse5@^6.0.1