Skip to content

Commit

Permalink
Rebased, retained existing behavior to be back compat
Browse files Browse the repository at this point in the history
  • Loading branch information
bspaulding committed Apr 11, 2020
1 parent b405b8b commit 9e1379e
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 8 deletions.
13 changes: 9 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,17 @@ function connectedCallback() {
(this.hasAttribute('hydrate') ? hydrate : render)(this._vdom, this._root);
}

function toCamelCase(str) {
return str.replace(/-(\w)/g, function(_, c) {
return c ? c.toUpperCase() : ''
});
}

function attributeChangedCallback(name, oldValue, newValue) {
if (!this._vdom) return;
const props = {};
props[name] = newValue;
props[toCamelCase(name)] = newValue;
this._vdom = cloneElement(this._vdom, props);
render(this._vdom, this._root);
}
Expand All @@ -46,10 +53,8 @@ function toVdom(element, nodeName) {
a = element.attributes,
cn = element.childNodes;
for (i = a.length; i--; ) {
var propName = a[i].name.replace(/-(\w)/, function(_, c) {
return c ? c.toUpperCase() : ''
});
props[propName] = a[i].value;
props[a[i].name] = a[i].value;
props[toCamelCase(a[i].name)] = a[i].value;
}
for (i = cn.length; i--; ) children[i] = toVdom(cn[i]);
return h(nodeName || element.nodeName.toLowerCase(), props, children);
Expand Down
42 changes: 38 additions & 4 deletions src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,62 @@ import assert from 'assert';
import { h } from 'preact';
import registerElement from './index';

function Clock ({ time }) {
return <span>{time}</span>;
}

registerElement(Clock, 'x-clock', ['time', 'custom-date']);

it('renders ok, updates on attr change', () => {
const root = document.createElement('div');
const el = document.createElement('x-clock');
el.setAttribute('time', '10:28:57 PM');
el.setAttribute('custom-date', '11/11/2011');

root.appendChild(el);
document.body.appendChild(root);

assert.equal(
root.innerHTML,
'<x-clock time="10:28:57 PM" custom-date="11/11/2011"><span>10:28:57 PM, 11/11/2011</span></x-clock>'
'<x-clock time="10:28:57 PM"><span>10:28:57 PM</span></x-clock>'
);

el.setAttribute('time', '11:01:10 AM');
el.setAttribute('custom-date', '01/01/2001');

assert.equal(
root.innerHTML,
'<x-clock time="11:01:10 AM" custom-date="01/01/2001"><span>11:01:10 AM, 01/01/2001</span></x-clock>'
'<x-clock time="11:01:10 AM"><span>11:01:10 AM</span></x-clock>'
);

document.body.removeChild(root);
});

const kebabName = 'custom-date-long-name';
const camelName = 'customDateLongName';
const lowerName = camelName.toLowerCase();
function PropNameTransform (props) {
return <span>{props[kebabName]} {props[lowerName]} {props[camelName]}</span>;
}
registerElement(PropNameTransform , 'x-prop-name-transform', [kebabName, camelName]);

it('handles kebab-case attributes with passthrough', () => {
const root = document.createElement('div');
const el = document.createElement('x-prop-name-transform');
el.setAttribute(kebabName, '11/11/2011');
el.setAttribute(camelName, 'pretended to be camel');

root.appendChild(el);
document.body.appendChild(root);

assert.equal(
root.innerHTML,
`<x-prop-name-transform ${kebabName}="11/11/2011" ${lowerName}="pretended to be camel"><span>11/11/2011 pretended to be camel 11/11/2011</span></x-prop-name-transform>`
);

el.setAttribute(kebabName, '01/01/2001');

assert.equal(
root.innerHTML,
`<x-prop-name-transform ${kebabName}="01/01/2001" ${lowerName}="pretended to be camel"><span>01/01/2001 pretended to be camel 01/01/2001</span></x-prop-name-transform>`
);

document.body.removeChild(root);
Expand Down

0 comments on commit 9e1379e

Please sign in to comment.