Match-id-b3271adc745fbcd1091dfc0f70385d726500f682

This commit is contained in:
* 2023-06-07 14:50:36 +08:00
parent c6857c5bc5
commit dd7b65c45a
14 changed files with 67 additions and 70 deletions

View File

@ -149,7 +149,7 @@ export function submitDomUpdate(tag: string, vNode: VNode) {
if (tag === DomComponent) { if (tag === DomComponent) {
// DomComponent类型 // DomComponent类型
if (element !== null || element !== undefined) { if (element !== null && element !== undefined) {
const type = vNode.type; const type = vNode.type;
const changeList = vNode.changeList; const changeList = vNode.changeList;
vNode.changeList = null; vNode.changeList = null;
@ -210,9 +210,9 @@ export function hideDom(tag: string, dom: Element | Text) {
} }
// 不隐藏元素 // 不隐藏元素
export function unHideDom(tag: string, dom: Element | Text, props: Props) { export function unHideDom(tag: string, dom: Element | Text, props?: Props) {
if (tag === DomComponent) { if (tag === DomComponent) {
dom.style.display = adjustStyleValue('display', props.style?.display ?? ''); dom.style.display = adjustStyleValue('display', props?.style?.display ?? '');
} else if (tag === DomText) { } else if (tag === DomText) {
dom.textContent = props; dom.textContent = props;
} }

View File

@ -48,7 +48,7 @@ export function setDomProps(dom: Element, props: Object, isNativeTag: boolean, i
} }
} else if (propName === 'dangerouslySetInnerHTML') { } else if (propName === 'dangerouslySetInnerHTML') {
dom.innerHTML = propVal.__html; dom.innerHTML = propVal.__html;
} else if (!isInit || propVal !== null || propVal !== undefined) { } else if (!isInit || (propVal !== null && propVal !== undefined)) {
updateCommonProp(dom, propName, propVal, isNativeTag); updateCommonProp(dom, propName, propVal, isNativeTag);
} }
} }
@ -103,7 +103,7 @@ export function compareProps(oldProps: Object, newProps: Object): Object {
for (let i = 0; i < keysOfNewProps.length; i++) { for (let i = 0; i < keysOfNewProps.length; i++) {
propName = keysOfNewProps[i]; propName = keysOfNewProps[i];
newPropValue = newProps[propName]; newPropValue = newProps[propName];
oldPropValue = oldProps !== null ? oldProps[propName] : null; oldPropValue = oldProps !== null && oldProps !== undefined ? oldProps[propName] : null;
if ( if (
newPropValue === oldPropValue newPropValue === oldPropValue
@ -144,7 +144,7 @@ export function compareProps(oldProps: Object, newProps: Object): Object {
} else if (propName === 'dangerouslySetInnerHTML') { } else if (propName === 'dangerouslySetInnerHTML') {
newHTML = newPropValue ? newPropValue.__html : undefined; newHTML = newPropValue ? newPropValue.__html : undefined;
oldHTML = oldPropValue ? oldPropValue.__html : undefined; oldHTML = oldPropValue ? oldPropValue.__html : undefined;
if (newHTML != null) { if (newHTML !== null && newHTML !== undefined) {
if (oldHTML !== newHTML) { if (oldHTML !== newHTML) {
toUpdateProps[propName] = newPropValue; toUpdateProps[propName] = newPropValue;
} }

View File

@ -72,15 +72,10 @@ function mergeDefault(sourceObj, defaultObj) {
// ['key', 'ref', '__source', '__self']属性不从setting获取 // ['key', 'ref', '__source', '__self']属性不从setting获取
const keyArray = ['key', 'ref', '__source', '__self']; const keyArray = ['key', 'ref', '__source', '__self'];
function getSettingArgs(setting, isClone, type) {
const key = setting && setting.key !== undefined ? String(setting.key) : (isClone ? type.key : null);
const ref = setting && setting.ref !== undefined ? setting.ref : (isClone ? type.ref : null);
return { key, ref };
}
function buildElement(isClone, type, setting, children) { function buildElement(isClone, type, setting, children) {
// setting中的值优先级最高clone情况下从 type 中取值,创建情况下直接赋值为 null // setting中的值优先级最高clone情况下从 type 中取值,创建情况下直接赋值为 null
const { key, ref } = getSettingArgs(setting, isClone, type); const key = (setting && setting.key !== undefined) ? String(setting.key) : (isClone ? type.key : null);
const ref = (setting && setting.ref !== undefined) ? setting.ref : (isClone ? type.ref : null);
const props = isClone ? { ...type.props } : {}; const props = isClone ? { ...type.props } : {};
let vNode = isClone ? type[BELONG_CLASS_VNODE_KEY] : getProcessingClassVNode(); let vNode = isClone ? type[BELONG_CLASS_VNODE_KEY] : getProcessingClassVNode();

View File

@ -115,7 +115,8 @@ export function resolveMutation(from, to) {
if (res[i].mutation) found = true; if (res[i].mutation) found = true;
} }
} }
// TODO: resolve shifts
// need to resolve shifts
return { mutation: found, items: res, from, to }; return { mutation: found, items: res, from, to };
} }

View File

@ -116,18 +116,22 @@ function makeStoreSnapshot({ type, data }) {
export const devtools = { export const devtools = {
// returns vNode id from horizon devtools // returns vNode id from horizon devtools
getVNodeId: vNode => { getVNodeId: vNode => {
if (!isPanelActive()) return; if (!isPanelActive()) {
return null;
}
window['__HORIZON_DEV_HOOK__'].send(); // update list first window['__HORIZON_DEV_HOOK__'].send(); // update list first
return window['__HORIZON_DEV_HOOK__'].getVnodeId(vNode); return window['__HORIZON_DEV_HOOK__'].getVnodeId(vNode);
}, },
// sends horizonx devtool message to extension // sends horizonx devtool message to extension
emit: (type, data) => { emit: (type, data) => {
if (!isPanelActive()) return; if (!isPanelActive()) {
return;
}
window.postMessage({ window.postMessage({
type: 'HORIZON_DEV_TOOLS', type: 'HORIZON_DEV_TOOLS',
payload: makeStoreSnapshot({ type, data }), payload: makeStoreSnapshot({ type, data }),
from: 'dev tool hook', from: 'dev tool hook',
}); }, '');
}, },
}; };
@ -135,7 +139,7 @@ export const devtools = {
function getAffectedComponents() { function getAffectedComponents() {
const allStores = getAllStores(); const allStores = getAllStores();
const keys = Object.keys(allStores); const keys = Object.keys(allStores);
let res = {}; const res = {};
keys.forEach(key => { keys.forEach(key => {
if (!allStores[key].$config.state._horizonObserver.keyVNodes) { if (!allStores[key].$config.state._horizonObserver.keyVNodes) {
res[key] = []; res[key] = [];
@ -144,17 +148,17 @@ function getAffectedComponents() {
const subRes = new Set(); const subRes = new Set();
const process = Array.from(allStores[key].$config.state._horizonObserver.keyVNodes.values()); const process = Array.from(allStores[key].$config.state._horizonObserver.keyVNodes.values());
while (process.length) { while (process.length) {
let pivot = process.shift() as { tag: 'string' }; const pivot = process.shift() as { tag: 'string' };
if (pivot.tag) subRes.add(pivot); if (pivot.tag) subRes.add(pivot);
if (pivot?.toString() === '[object Set]') Array.from(pivot).forEach(item => process.push(item)); if (pivot.toString() === '[object Set]') Array.from(pivot).forEach(item => process.push(item));
} }
res[key] = Array.from(subRes).map(vnode => { res[key] = Array.from(subRes).map(vNode => {
return { return {
name: vnode?.type name: vNode?.type
.toString() .toString()
.replace(/\{.*\}/, '{...}') .replace(/\{.*\}/, '{...}')
.replace('function ', ''), .replace('function ', ''),
nodeId: window.__HORIZON_DEV_HOOK__.getVnodeId(vnode), nodeId: window.__HORIZON_DEV_HOOK__.getVnodeId(vNode),
}; };
}); });
}); });
@ -163,7 +167,7 @@ function getAffectedComponents() {
} }
// listens to messages from background // listens to messages from background
window.addEventListener('message', messageEvent => { window.addEventListener('message', (messageEvent?) => {
if (messageEvent?.data?.payload?.type === 'horizonx request observed components') { if (messageEvent?.data?.payload?.type === 'horizonx request observed components') {
// get observed components // get observed components
setTimeout(() => { setTimeout(() => {
@ -171,7 +175,7 @@ window.addEventListener('message', messageEvent => {
type: 'HORIZON_DEV_TOOLS', type: 'HORIZON_DEV_TOOLS',
payload: { type: OBSERVED_COMPONENTS, data: getAffectedComponents() }, payload: { type: OBSERVED_COMPONENTS, data: getAffectedComponents() },
from: 'dev tool hook', from: 'dev tool hook',
}); }, '');
}, 100); }, 100);
} }
@ -216,6 +220,7 @@ window.addEventListener('message', messageEvent => {
console.error(err); console.error(err);
} }
} }
// TODO:implement add and delete element
// need to implement add and delete element
} }
}); });

View File

@ -97,10 +97,6 @@ export class Observer implements IObserver {
} }
triggerUpdate(vNode: VNode): void { triggerUpdate(vNode: VNode): void {
if (!vNode) {
return;
}
// 触发VNode更新 // 触发VNode更新
launchUpdateFromVNode(vNode); launchUpdateFromVNode(vNode);
} }

View File

@ -62,11 +62,12 @@ export function createProxy(rawObj: any, isHookObserver: boolean, listener: { cu
// 创建Proxy // 创建Proxy
let proxyObj; let proxyObj;
if (!isHookObserver) { if (!isHookObserver) {
proxyObj = createObjectProxy(rawObj, true, { proxyObj = createObjectProxy(rawObj, {
current: change => { current: change => {
listener.current(change); listener.current(change);
},
}, },
}); true);
} else if (isArray(rawObj)) { } else if (isArray(rawObj)) {
// 数组 // 数组
proxyObj = createArrayProxy(rawObj as [], { proxyObj = createArrayProxy(rawObj as [], {
@ -76,18 +77,20 @@ export function createProxy(rawObj: any, isHookObserver: boolean, listener: { cu
}); });
} else if (isCollection(rawObj)) { } else if (isCollection(rawObj)) {
// 集合 // 集合
proxyObj = createCollectionProxy(rawObj, true, { proxyObj = createCollectionProxy(rawObj, {
current: change => { current: change => {
listener.current(change); listener.current(change);
},
}, },
}); true);
} else { } else {
// 原生对象 或 函数 // 原生对象 或 函数
proxyObj = createObjectProxy(rawObj, false, { proxyObj = createObjectProxy(rawObj, {
current: change => { current: change => {
listener.current(change); listener.current(change);
},
}, },
}); false);
} }
proxyMap.set(rawObj, proxyObj); proxyMap.set(rawObj, proxyObj);

View File

@ -35,7 +35,7 @@ function set(rawObj: any[], key: string, value: any, receiver: any) {
if (!isSame(newValue, oldValue)) { if (!isSame(newValue, oldValue)) {
// 值不一样,触发监听器 // 值不一样,触发监听器
if (observer.watchers?.[key]) { if (observer.watchers[key]) {
observer.watchers[key].forEach(cb => { observer.watchers[key].forEach(cb => {
cb(key, oldValue, newValue, mutation); cb(key, oldValue, newValue, mutation);
}); });

View File

@ -21,19 +21,17 @@ import { createMapProxy } from './MapProxy';
export function createCollectionProxy( export function createCollectionProxy(
rawObj: Object, rawObj: Object,
hookObserver: boolean, listener: { current: (...args) => any },
listener: { current: (...args) => any } hookObserver = true
): Object { ): Object {
hookObserver = hookObserver || true;
if (isWeakSet(rawObj)) { if (isWeakSet(rawObj)) {
return createWeakSetProxy(rawObj, hookObserver, listener); return createWeakSetProxy(rawObj, listener, hookObserver);
} }
if (isSet(rawObj)) { if (isSet(rawObj)) {
return createSetProxy(rawObj, hookObserver, listener); return createSetProxy(rawObj, listener, hookObserver);
} }
if (isWeakMap(rawObj)) { if (isWeakMap(rawObj)) {
return createWeakMapProxy(rawObj, hookObserver, listener); return createWeakMapProxy(rawObj, listener, hookObserver);
} }
return createMapProxy(rawObj, hookObserver, listener); return createMapProxy(rawObj, listener, hookObserver);
} }

View File

@ -20,14 +20,17 @@ import { isPanelActive } from '../../devtools';
const COLLECTION_CHANGE = '_collectionChange'; const COLLECTION_CHANGE = '_collectionChange';
export function createMapProxy(rawObj: Object, hookObserver: boolean, listener: { current: (...args) => any }): Object { export function createMapProxy(
hookObserver = hookObserver || true; rawObj: Object,
listener: { current: (...args) => any },
hookObserver = true
): Object {
let listeners: ((mutation) => {})[] = []; let listeners: ((mutation) => {})[] = [];
let oldData: [any, any][] = []; let oldData: [any, any][] = [];
let proxies = new Map(); let proxies = new Map();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function getFun(rawObj: { get: (key: any) => any; has: (key: any) => boolean }, key: any) { function getFun(rawObj: { get: (key: any) => any; has: (key: any) => boolean }, key: any): any {
const keyProxy = rawObj.has(key) ? key : proxies.get(key); const keyProxy = rawObj.has(key) ? key : proxies.get(key);
if (!keyProxy) return; if (!keyProxy) return;
const observer = getObserver(rawObj); const observer = getObserver(rawObj);
@ -61,7 +64,7 @@ export function createMapProxy(rawObj: Object, hookObserver: boolean, listener:
}, },
key: any, key: any,
value: any value: any
) { ): any {
if (rawObj.has(key) || rawObj.has(proxies.get(key))) { if (rawObj.has(key) || rawObj.has(proxies.get(key))) {
// VALUE CHANGE (whole value for selected key is changed) // VALUE CHANGE (whole value for selected key is changed)
const oldValue = rawObj.get(proxies.get(key)); const oldValue = rawObj.get(proxies.get(key));
@ -71,7 +74,7 @@ export function createMapProxy(rawObj: Object, hookObserver: boolean, listener:
const observer = getObserver(rawObj); const observer = getObserver(rawObj);
observer.setProp(COLLECTION_CHANGE, mutation); observer.setProp(COLLECTION_CHANGE, mutation);
if (observer.watchers?.[key]) { if (observer.watchers[key]) {
observer.watchers[key].forEach(cb => { observer.watchers[key].forEach(cb => {
cb(key, oldValue, value, mutation); cb(key, oldValue, value, mutation);
}); });

View File

@ -29,7 +29,7 @@ function set(rawObj: object, key: string, value: any, receiver: any): boolean {
const mutation = isPanelActive() ? resolveMutation(oldObject, rawObj) : resolveMutation(null, rawObj); const mutation = isPanelActive() ? resolveMutation(oldObject, rawObj) : resolveMutation(null, rawObj);
if (!isSame(newValue, oldValue)) { if (!isSame(newValue, oldValue)) {
if (observer.watchers?.[key]) { if (observer.watchers[key]) {
observer.watchers[key].forEach(cb => { observer.watchers[key].forEach(cb => {
cb(key, oldValue, newValue, mutation); cb(key, oldValue, newValue, mutation);
}); });
@ -41,10 +41,9 @@ function set(rawObj: object, key: string, value: any, receiver: any): boolean {
export function createObjectProxy<T extends object>( export function createObjectProxy<T extends object>(
rawObj: T, rawObj: T,
singleLevel: boolean, listener: { current: (...args) => any },
listener: { current: (...args) => any } singleLevel = false
): ProxyHandler<T> { ): ProxyHandler<T> {
singleLevel = singleLevel || false;
let listeners = [] as ((...args) => void)[]; let listeners = [] as ((...args) => void)[];
function get(rawObj: object, key: string | symbol, receiver: any): any { function get(rawObj: object, key: string | symbol, receiver: any): any {

View File

@ -20,10 +20,9 @@ const COLLECTION_CHANGE = '_collectionChange';
export function createSetProxy<T extends object>( export function createSetProxy<T extends object>(
rawObj: T, rawObj: T,
hookObserver: boolean, listener: { current: (...args) => any },
listener: { current: (...args) => any } hookObserver = true
): ProxyHandler<T> { ): ProxyHandler<T> {
hookObserver = hookObserver || true;
let listeners: ((mutation) => {})[] = []; let listeners: ((mutation) => {})[] = [];
let proxies = new WeakMap(); let proxies = new WeakMap();

View File

@ -22,10 +22,9 @@ const COLLECTION_CHANGE = '_collectionChange';
export function createWeakMapProxy( export function createWeakMapProxy(
rawObj: Object, rawObj: Object,
hookObserver: boolean, listener: { current: (...args) => any },
listener: { current: (...args) => any } hookObserver = true
): Object { ): Object {
hookObserver = hookObserver ||true;
let listeners: ((mutation) => {})[] = []; let listeners: ((mutation) => {})[] = [];
const handler = { const handler = {
@ -117,7 +116,7 @@ export function createWeakMapProxy(
} }
if (valChange) { if (valChange) {
if (observer.watchers?.[key]) { if (observer.watchers[key]) {
observer.watchers[key].forEach(cb => { observer.watchers[key].forEach(cb => {
cb(key, oldValue, newValue, mutation); cb(key, oldValue, newValue, mutation);
}); });

View File

@ -18,10 +18,9 @@ import { createProxy, getObserver, hookObserverMap } from '../ProxyHandler';
export function createWeakSetProxy<T extends object>( export function createWeakSetProxy<T extends object>(
rawObj: T, rawObj: T,
hookObserver: boolean, listener: { current: (...args) => any },
listener: { current: (...args) => any } hookObserver = true,
): ProxyHandler<T> { ): ProxyHandler<T> {
hookObserver = hookObserver || true;
let listeners: ((mutation) => {})[] = []; let listeners: ((mutation) => {})[] = [];
let proxies = new WeakMap(); let proxies = new WeakMap();