Skip to content
This repository has been archived by the owner on Jul 30, 2018. It is now read-only.

Commit

Permalink
Move child creation logic for custom elements to attach callback (#744)
Browse files Browse the repository at this point in the history
Resolves #531
  • Loading branch information
maier49 authored Nov 7, 2017
1 parent f119b24 commit d5f224b
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 29 deletions.
31 changes: 15 additions & 16 deletions src/customElements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,32 +221,31 @@ export function initializeElement(element: CustomElement) {
};
});

// find children
let children: DNode[] = [];

arrayFrom(element.children).forEach((childNode: HTMLElement, index: number) => {
const DomElement = DomWrapper(childNode);
children.push(w(DomElement, {
key: `child-${index}`
}));
});

if (initialization) {
initialization.call(element, initialProperties);
}

arrayFrom(element.children).forEach((childNode: HTMLElement) => {
element.removeChild(childNode);
});

const projector = ProjectorMixin(element.getWidgetConstructor());

const widgetInstance = new projector();

widgetInstance.setProperties(initialProperties);
widgetInstance.setChildren(children);
element.setWidgetInstance(widgetInstance);

return function() {
// find children
let children: DNode[] = [];
let elementChildren = arrayFrom(element.children);
elementChildren.forEach((childNode: HTMLElement, index: number) => {
const DomElement = DomWrapper(childNode);
children.push(w(DomElement, {
key: `child-${index}`
}));
});
elementChildren.forEach((childNode: HTMLElement) => {
element.removeChild(childNode);
});

widgetInstance.setChildren(children);
widgetInstance.append(element);
};
}
Expand Down
46 changes: 46 additions & 0 deletions tests/functional/registerCustomElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,52 @@ registerSuite('registerCustomElement', {
.then(pollUntil(function () {
return (<any> document).querySelector('#reinitButton > button').innerHTML === 'test';
}, undefined, 1000), undefined);
},
'declarative children should be wrapped as widgets'() {
if (skip) {
this.skip('not compatible with iOS 9.1 or Safari 9.1');
}
return this.remote
.get((<any> require).toUrl('./support/registerCustomElement.html'))
.setFindTimeout(1000)
.findByCssSelector('#parent-element > div > child-wrapper#nested-parent > div > div')
.then((element: any) => {
return element.getVisibleText();
})
.then((text: string) => {
assert.strictEqual(text, 'nested child');
})
.end()
.findByCssSelector('#parent-element > div > div')
.then((element: any) => {
return element.getVisibleText();
})
.then((text: string) => {
assert.strictEqual(text, 'top level child');
});
},
'programmatically added children should be wrapped as widgets'() {
if (skip) {
this.skip('not compatible with iOS 9.1 or Safari 9.1');
}
return this.remote
.get((<any> require).toUrl('./support/registerCustomElement.html'))
.setFindTimeout(1000)
.findByCssSelector('#dynamic-parent-element > div > child-wrapper > div > div')
.then((element: any) => {
return element.getVisibleText();
})
.then((text: string) => {
assert.strictEqual(text, 'programmatic nested child');
})
.end()
.findByCssSelector('#dynamic-parent-element > div > div')
.then((element: any) => {
return element.getVisibleText();
})
.then((text: string) => {
assert.strictEqual(text, 'programmatic top level child');
});
}
}
});
21 changes: 21 additions & 0 deletions tests/functional/support/registerCustomElement.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
<test-button id="testButton" label="hello" label-suffix="world"></test-button>

<no-attributes id="noAttributes" label="hello" label-suffix="world"></no-attributes>
<child-wrapper id="parent-element">
<child-wrapper id="nested-parent">
<div>nested child</div>
</child-wrapper>
<div>top level child</div>
</child-wrapper>

<script>
window.buttonClicked = false;
Expand Down Expand Up @@ -40,9 +46,24 @@
var reinitButton = document.createElement("test-button");
reinitButton.id = "reinitButton";
reinitButton.label = "test";
reinitButton.appendChild(document.createElement('div'));
document.body.appendChild(reinitButton);
document.body.removeChild(reinitButton);
document.body.appendChild(reinitButton);

var dynamicChildren = document.createElement('child-wrapper');
var nestedParent = document.createElement('child-wrapper');
var topLevelChild = document.createElement('div');
var nestedChild = document.createElement('div');
dynamicChildren.id = 'dynamic-parent-element';
nestedParent.appendChild(nestedChild);
dynamicChildren.appendChild(nestedParent);
dynamicChildren.appendChild(topLevelChild);
topLevelChild.textContent = 'programmatic top level child';
nestedChild.textContent = 'programmatic nested child';
document.body.appendChild(dynamicChildren);
document.body.removeChild(dynamicChildren);
document.body.appendChild(dynamicChildren);
});
</script>
</body>
Expand Down
13 changes: 13 additions & 0 deletions tests/functional/support/registerCustomElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ class TestButton extends WidgetBase<TestButtonProperties> {
}
}

class ChildWrapper extends WidgetBase {
render() {
return v('div', {}, this.children);
}
}

registerCustomElement(function () {
return {
tagName: 'test-button',
Expand Down Expand Up @@ -66,3 +72,10 @@ registerCustomElement(function () {
]
};
});

registerCustomElement(function () {
return {
tagName: 'child-wrapper',
widgetConstructor: ChildWrapper
};
});
30 changes: 17 additions & 13 deletions tests/unit/customElements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ function createFakeElement(attributes: any, descriptor: CustomElementDescriptor)
setWidgetInstance(instance: WidgetBase<any>) {
widgetInstance = instance;
},
getWidgetConstructor: () => WidgetBase,
getWidgetConstructor: () => class extends WidgetBase<any> {
render() {
return v('div');
}
},
getDescriptor: () => descriptor,
children: [],
getAttribute(name: string) {
Expand Down Expand Up @@ -75,7 +79,7 @@ registerSuite('customElements', {
]
});

initializeElement(element);
initializeElement(element)();

const result = element.getWidgetInstance().properties;
assert.strictEqual(result.a, '1');
Expand All @@ -101,7 +105,7 @@ registerSuite('customElements', {
]
});

initializeElement(element);
initializeElement(element)();

assert.strictEqual(element.a, '1');
assert.strictEqual(element.b, '2');
Expand All @@ -125,7 +129,7 @@ registerSuite('customElements', {
]
});

initializeElement(element);
initializeElement(element)();

element.a = 4;

Expand All @@ -143,7 +147,7 @@ registerSuite('customElements', {
]
});

initializeElement(element);
initializeElement(element)();

handleAttributeChanged(element, 'a', 'test', null);
handleAttributeChanged(element, 'b', 'test', null);
Expand All @@ -158,7 +162,7 @@ registerSuite('customElements', {
tagName: 'test'
});

initializeElement(element);
initializeElement(element)();

handleAttributeChanged(element, 'b', 'test', null);

Expand All @@ -177,7 +181,7 @@ registerSuite('customElements', {
]
});

initializeElement(element);
initializeElement(element)();
element.getWidgetInstance().__setProperties__({
a: 'test'
});
Expand All @@ -199,7 +203,7 @@ registerSuite('customElements', {
]
});

initializeElement(element);
initializeElement(element)();
element.getWidgetInstance().__setProperties__({
test: 'test'
});
Expand All @@ -220,7 +224,7 @@ registerSuite('customElements', {
]
});

initializeElement(element);
initializeElement(element)();
element.getWidgetInstance().__setProperties__({
a: 4
});
Expand All @@ -241,7 +245,7 @@ registerSuite('customElements', {
]
});

initializeElement(element);
initializeElement(element)();
element.a = 4;

assert.deepEqual(element.getWidgetInstance().properties.a, 8);
Expand Down Expand Up @@ -273,7 +277,7 @@ registerSuite('customElements', {
]
});

initializeElement(element);
initializeElement(element)();

assert.isFunction(element.getWidgetInstance().properties.onTest);
element.getWidgetInstance().properties.onTest('detail here');
Expand All @@ -296,7 +300,7 @@ registerSuite('customElements', {
parentNode: element
} ];

initializeElement(element);
initializeElement(element)();

assert.lengthOf(element.removedChildren(), 1);
assert.lengthOf(element.getWidgetInstance().children, 1);
Expand All @@ -313,7 +317,7 @@ registerSuite('customElements', {
}
});

initializeElement(element);
initializeElement(element)();

assert.strictEqual(element.getWidgetInstance().properties.prop1, 'test');
}
Expand Down

0 comments on commit d5f224b

Please sign in to comment.