Skip to content

Commit

Permalink
feat(engine): refactoring abstraction for create, insert, remove and …
Browse files Browse the repository at this point in the history
…render to support CE
  • Loading branch information
caridy committed Feb 13, 2018
1 parent 93c73fe commit 9d0379c
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 15 deletions.
4 changes: 1 addition & 3 deletions packages/lwc-engine/src/framework/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ const hook: Hooks = {
if (vm.cmpSlots !== oldVNode.data.slotset && !vm.isDirty) {
markComponentAsDirty(vm);
}
if (vm.isDirty) {
renderVM(vm);
}
renderVM(vm);
},
insert(vnode: VNode) {
const vm = getCustomElementVM(vnode.elm as HTMLElement);
Expand Down
16 changes: 9 additions & 7 deletions packages/lwc-engine/src/framework/upgrade.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import assert from "./assert";
import { isUndefined, isFunction, assign } from "./language";
import { isUndefined, isFunction, assign, hasOwnProperty } from "./language";
import { createVM, removeVM, appendVM, renderVM } from "./vm";
import { registerComponent, getCtorByTagName, prepareForAttributeMutationFromTemplate } from "./def";
import { registerComponent, getCtorByTagName, prepareForAttributeMutationFromTemplate, ViewModelReflection } from "./def";
import { ComponentConstructor } from "./component";
import { getCustomElementVM } from "./html-element";

Expand Down Expand Up @@ -58,19 +58,21 @@ export function createElement(sel: string, options: any = {}): HTMLElement {
throw new TypeError();
}
registerComponent(sel, options.is);
// extracing the registered constructor just in case we need to force the tagName
// extracting the registered constructor just in case we need to force the tagName
const Ctor = getCtorByTagName(sel);
const { forceTagName } = Ctor as ComponentConstructor;
const tagName = isUndefined(forceTagName) ? sel : forceTagName;
// Create element with correct tagName
const element = document.createElement(tagName);
if (hasOwnProperty.call(element, ViewModelReflection)) {
return element;
}
// In case the element is not initialized already, we need to carry on the manual creation
createVM(sel, element);
// Handle insertion and removal from the DOM
// Handle insertion and removal from the DOM manually
element[ConnectingSlot] = () => {
const vm = getCustomElementVM(element);
if (vm.idx > 0) {
removeVM(vm); // moving the element from one place to another is observable via life-cycle hooks
}
removeVM(vm); // moving the element from one place to another is observable via life-cycle hooks
appendVM(vm);
// TODO: this is the kind of awkwardness introduced by "is" attribute
// We don't want to do this during construction because it breaks another
Expand Down
18 changes: 13 additions & 5 deletions packages/lwc-engine/src/framework/vm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import assert from "./assert";
import { getComponentDef } from "./def";
import { createComponent, linkComponent, renderComponent, clearReactiveListeners, ComponentConstructor, ErrorCallback } from "./component";
import { patchChildren } from "./patch";
import { ArrayPush, isUndefined, isNull, ArrayUnshift, ArraySlice, create } from "./language";
import { ArrayPush, isUndefined, isNull, ArrayUnshift, ArraySlice, create, hasOwnProperty } from "./language";
import { addCallbackToNextTick, EmptyObject, EmptyArray, usesNativeSymbols } from "./utils";
import { ViewModelReflection, getCtorByTagName } from "./def";
import { invokeServiceHook, Services } from "./services";
Expand Down Expand Up @@ -94,23 +94,28 @@ export function removeInsertionIndex(vm: VM) {
export function renderVM(vm: VM) {
if (process.env.NODE_ENV !== 'production') {
assert.vm(vm);
assert.isTrue(vm.isDirty, `${vm} must be dirty before renderVM is invoked.`);
}
rehydrate(vm);
if (vm.isDirty) {
rehydrate(vm);
}
}

export function appendVM(vm: VM) {
if (process.env.NODE_ENV !== 'production') {
assert.vm(vm);
assert.isTrue(vm.idx === 0, `${vm} is already inserted.`);
}
if (vm.idx !== 0) {
return; // already appended
}
addInsertionIndex(vm);
}

export function removeVM(vm: VM) {
if (process.env.NODE_ENV !== 'production') {
assert.vm(vm);
assert.isTrue(vm.idx > 0, `${vm} is not inserted.`);
}
if (vm.idx === 0) {
return; // already removed
}
removeInsertionIndex(vm);
// just in case it comes back, with this we guarantee re-rendering it
Expand All @@ -128,6 +133,9 @@ export function createVM(tagName: string, elm: HTMLElement, cmpSlots?: Slotset)
if (process.env.NODE_ENV !== 'production') {
assert.invariant(elm instanceof HTMLElement, `VM creation requires a DOM element instead of ${elm}.`);
}
if (hasOwnProperty.call(elm, ViewModelReflection)) {
return; // already created
}
const Ctor = getCtorByTagName(tagName) as ComponentConstructor;
const def = getComponentDef(Ctor);
const isRoot = arguments.length === 2; // root elements can't provide slotset
Expand Down

0 comments on commit 9d0379c

Please sign in to comment.