Skip to content
This repository was archived by the owner on Nov 6, 2019. It is now read-only.

Commit 192025a

Browse files
committed
made implementation of hpass more robust; now prevents sibling clobbering
still need to figure out how to handle cleanup; current implementation likely causes a memory leak due to uncleaned-up React components
1 parent 25d5dfa commit 192025a

File tree

3 files changed

+34
-54
lines changed

3 files changed

+34
-54
lines changed

packages/virtualdom/src/index.ts

+23-43
Original file line numberDiff line numberDiff line change
@@ -748,10 +748,7 @@ class VirtualElement {
748748
}
749749

750750
export
751-
class VirtualElementPass {
752-
readonly realize: VirtualElementPass.IRealize;
753-
754-
readonly render: VirtualElementPass.IRender;
751+
class VirtualElementPass{
755752

756753
/**
757754
* The type of the node.
@@ -764,26 +761,13 @@ class VirtualElementPass {
764761
/**
765762
* Construct a new virtual element pass thru node.
766763
*
767-
* @param realize - a function that takes no arguments and returns an HTMLElement
768-
*
769764
* @param render - a function that takes a host HTMLElement and returns void
770765
*/
771-
constructor({realize, render}: VirtualElementPass.IProps) {
772-
this.render = render;
773-
this.realize = realize || (() => {const host = document.createElement('div'); this.render(host); return host});
774-
}
766+
constructor(readonly render: VirtualElementPass.IRender, readonly tag: string, readonly attrs: ElementAttrs) {}
775767
}
776768

777769
export namespace VirtualElementPass {
778-
export type IRealize = () => HTMLElement;
779-
780770
export type IRender = (host: HTMLElement) => void;
781-
782-
export interface IProps {
783-
realize?: IRealize;
784-
785-
render: IRender;
786-
}
787771
}
788772

789773
/**
@@ -973,8 +957,8 @@ namespace h {
973957
export const wbr: IFactory = h.bind(undefined, 'wbr');
974958
}
975959

976-
export function hpass(props: VirtualElementPass.IProps): VirtualElementPass {
977-
return new VirtualElementPass(props);
960+
export function hpass(render: VirtualElementPass.IRender, tag: string, attrs: ElementAttrs = {}): VirtualElementPass {
961+
return new VirtualElementPass(render, tag, attrs);
978962
}
979963

980964
/**
@@ -1070,32 +1054,28 @@ namespace Private {
10701054
let host = arguments[1] || null;
10711055
const before = arguments[2] || null;
10721056

1073-
if (node.type === 'passthru') {
1074-
if (host) {
1075-
// TODO: figure out how to do an "insert before" with a passthru node
1076-
node.render(host);
1077-
} else {
1078-
throw new Error("createDOMNode should not be called with only one argument on vdom nodes of type === 'passthru'");
1079-
}
1057+
if (host) {
1058+
host.insertBefore(createDOMNode(node), before);
10801059
} else {
1081-
if (host) {
1082-
host.insertBefore(createDOMNode(node), before);
1083-
} else {
1084-
// Create a text node for a virtual text node.
1085-
if (node.type === 'text') {
1086-
return document.createTextNode(node.content);
1087-
}
1060+
// Create a text node for a virtual text node.
1061+
if (node.type === 'text') {
1062+
return document.createTextNode(node.content);
1063+
}
10881064

1089-
// Create the HTML element with the specified tag.
1090-
host = document.createElement(node.tag);
1065+
// Create the HTML element with the specified tag.
1066+
host = document.createElement(node.tag);
10911067

1092-
// Add the attributes for the new element.
1093-
addAttrs(host, node.attrs);
1068+
// Add the attributes for the new element.
1069+
addAttrs(host, node.attrs);
10941070

1095-
// Recursively populate the element with child content.
1096-
for (let i = 0, n = node.children.length; i < n; ++i) {
1097-
createDOMNode(node.children[i], host);
1098-
}
1071+
if (node.type === 'passthru') {
1072+
node.render(host);
1073+
return host;
1074+
}
1075+
1076+
// Recursively populate the element with child content.
1077+
for (let i = 0, n = node.children.length; i < n; ++i) {
1078+
createDOMNode(node.children[i], host);
10991079
}
11001080
}
11011081

@@ -1155,7 +1135,7 @@ namespace Private {
11551135

11561136
// Handle the case of passthru update.
11571137
if (oldVNode.type === 'passthru' && newVNode.type === 'passthru') {
1158-
newVNode.render(host);
1138+
newVNode.render(currElem as HTMLElement);
11591139
currElem = currElem!.nextSibling;
11601140
continue;
11611141
}

packages/widgets/src/tabbar.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1341,8 +1341,8 @@ namespace TabBar {
13411341
const { title } = data;
13421342
let className = this.createIconClass(data);
13431343

1344-
if (title.iconPass) {
1345-
return hpass(title.iconPass);
1344+
if (title.iconRender) {
1345+
return hpass(title.iconRender, 'div');
13461346
} else {
13471347
return h.div({className}, data.title.iconLabel);
13481348
}

packages/widgets/src/title.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ class Title<T> {
4444
if (options.iconLabel !== undefined) {
4545
this._iconLabel = options.iconLabel;
4646
}
47-
if (options.iconPass !== undefined) {
48-
this._iconPass = options.iconPass;
47+
if (options.iconRender !== undefined) {
48+
this._iconRender = options.iconRender;
4949
}
5050
if (options.caption !== undefined) {
5151
this._caption = options.caption;
@@ -175,15 +175,15 @@ class Title<T> {
175175
this._changed.emit(undefined);
176176
}
177177

178-
get iconPass(): VirtualElementPass.IProps {
179-
return this._iconPass;
178+
get iconRender(): VirtualElementPass.IRender {
179+
return this._iconRender;
180180
}
181181

182-
set iconPass(value: VirtualElementPass.IProps) {
183-
if (this._iconPass === value) {
182+
set iconRender(value: VirtualElementPass.IRender) {
183+
if (this._iconRender === value) {
184184
return;
185185
}
186-
this._iconPass = value;
186+
this._iconRender = value;
187187
this._changed.emit(undefined);
188188
}
189189

@@ -285,7 +285,7 @@ class Title<T> {
285285
private _mnemonic = -1;
286286
private _iconClass = '';
287287
private _iconLabel = '';
288-
private _iconPass: VirtualElementPass.IProps;
288+
private _iconRender: VirtualElementPass.IRender;
289289
private _className = '';
290290
private _closable = false;
291291
private _dataset: Title.Dataset;
@@ -339,7 +339,7 @@ namespace Title {
339339
*/
340340
iconLabel?: string;
341341

342-
iconPass?: VirtualElementPass.IProps;
342+
iconRender?: VirtualElementPass.IRender;
343343

344344
/**
345345
* The caption for the title.

0 commit comments

Comments
 (0)