Match-id-2909a47b27480d6ed5a321c4bab455c53313c6b9
This commit is contained in:
commit
e51f135a83
|
@ -24,11 +24,12 @@ const internalKeys = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 通过 VNode 实例获取 DOM 节点
|
// 通过 VNode 实例获取 DOM 节点
|
||||||
export function getDom(vNode: VNode): Element | Text | void {
|
export function getDom(vNode: VNode): Element | Text | null {
|
||||||
const {tag} = vNode;
|
const {tag} = vNode;
|
||||||
if (tag === DomComponent || tag === DomText) {
|
if (tag === DomComponent || tag === DomText) {
|
||||||
return vNode.realNode;
|
return vNode.realNode;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将 VNode 属性相关信息挂到 DOM 对象的特定属性上
|
// 将 VNode 属性相关信息挂到 DOM 对象的特定属性上
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
import {
|
import {
|
||||||
createDom,
|
createDom,
|
||||||
} from './utils/DomCreator';
|
} from './utils/DomCreator';
|
||||||
import { getSelectionInfo, resetSelectionRange, selectionData } from './SelectionRangeHandler';
|
import { getSelectionInfo, resetSelectionRange, SelectionData } from './SelectionRangeHandler';
|
||||||
import { isElement, isComment, isDocument, isDocumentFragment, getDomTag, shouldAutoFocus } from './utils/Common';
|
import { isElement, isComment, isDocument, isDocumentFragment, getDomTag, shouldAutoFocus } from './utils/Common';
|
||||||
import { NSS } from './utils/DomCreator';
|
import { NSS } from './utils/DomCreator';
|
||||||
import { adjustStyleValue } from './DOMPropertiesHandler/StyleHandler';
|
import { adjustStyleValue } from './DOMPropertiesHandler/StyleHandler';
|
||||||
|
@ -37,7 +37,7 @@ export type Props = {
|
||||||
|
|
||||||
export type Container = (Element & { _treeRoot?: VNode }) | (Document & { _treeRoot?: VNode });
|
export type Container = (Element & { _treeRoot?: VNode }) | (Document & { _treeRoot?: VNode });
|
||||||
|
|
||||||
let selectionInfo: null | selectionData = null;
|
let selectionInfo: null | SelectionData = null;
|
||||||
|
|
||||||
function getChildNS(parentNS: string | null, tagName: string): string {
|
function getChildNS(parentNS: string | null, tagName: string): string {
|
||||||
if (parentNS === NSS.svg && tagName === 'foreignObject') {
|
if (parentNS === NSS.svg && tagName === 'foreignObject') {
|
||||||
|
@ -54,12 +54,12 @@ function getChildNS(parentNS: string | null, tagName: string): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取容器
|
// 获取容器
|
||||||
export function getNSCtx(dom?: Container, parentNS: string, type: string): string {
|
export function getNSCtx(parentNS: string, type: string, dom?: Container): string {
|
||||||
return dom ? getChildNS(dom.namespaceURI ?? null, dom.nodeName) : getChildNS(parentNS, type);
|
return dom ? getChildNS(dom.namespaceURI ?? null, dom.nodeName) : getChildNS(parentNS, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function prepareForSubmit(): void {
|
export function prepareForSubmit(): void {
|
||||||
selectionInfo = <selectionData>getSelectionInfo();
|
selectionInfo = <SelectionData>getSelectionInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resetAfterSubmit(): void {
|
export function resetAfterSubmit(): void {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
} from '../../event/EventBinding';
|
} from '../../event/EventBinding';
|
||||||
import { isEventProp, isNativeElement } from '../validators/ValidateProps';
|
import { isEventProp, isNativeElement } from '../validators/ValidateProps';
|
||||||
|
|
||||||
function updateOneProp(dom, propName, propVal, isNativeTag, isInit?: boolean) {
|
function updateOneProp(dom, propName, isNativeTag, propVal?, isInit?: boolean) {
|
||||||
if (propName === 'style') {
|
if (propName === 'style') {
|
||||||
setStyles(dom, propVal);
|
setStyles(dom, propVal);
|
||||||
} else if (propName === 'dangerouslySetInnerHTML') {
|
} else if (propName === 'dangerouslySetInnerHTML') {
|
||||||
|
@ -42,7 +42,7 @@ export function setDomProps(
|
||||||
const propName = keysOfProps[i];
|
const propName = keysOfProps[i];
|
||||||
const propVal = props[propName];
|
const propVal = props[propName];
|
||||||
|
|
||||||
updateOneProp(dom, propName, propVal, isNativeTag, true);
|
updateOneProp(dom, propName, isNativeTag, propVal, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ export function updateDomProps(
|
||||||
for (let i = 0; i < changeList.length; i++) {
|
for (let i = 0; i < changeList.length; i++) {
|
||||||
const { propName, propVal } = changeList[i];
|
const { propName, propVal } = changeList[i];
|
||||||
|
|
||||||
updateOneProp(dom, propName, propVal, isNativeTag);
|
updateOneProp(dom, propName, isNativeTag, propVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ export function compareProps(
|
||||||
for (let i = 0; i < keysOfNewProps.length; i++) {
|
for (let i = 0; i < keysOfNewProps.length; i++) {
|
||||||
const propName = keysOfNewProps[i];
|
const propName = keysOfNewProps[i];
|
||||||
const newPropValue = newProps[propName];
|
const newPropValue = newProps[propName];
|
||||||
const oldPropValue = oldProps != null ? oldProps[propName] : undefined;
|
const oldPropValue = oldProps != null ? oldProps[propName] : null;
|
||||||
|
|
||||||
if (newPropValue === oldPropValue || (newPropValue == null && oldPropValue == null)) {
|
if (newPropValue === oldPropValue || (newPropValue == null && oldPropValue == null)) {
|
||||||
// 新旧属性值未发生变化,或者新旧属性皆为空值,不需要进行处理
|
// 新旧属性值未发生变化,或者新旧属性皆为空值,不需要进行处理
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
/**
|
||||||
|
* 对一些没有写单位的样式进行适配,例如:width: 10 => width: 10px
|
||||||
|
* 对空值或布尔值进行适配,转为空字符串
|
||||||
|
* 去掉多余空字符
|
||||||
|
*/
|
||||||
|
export function adjustStyleValue(name, value) {
|
||||||
|
let validValue = value;
|
||||||
|
|
||||||
|
if (typeof value === 'number' && value !== 0 && isNeedUnitCSS(name)) {
|
||||||
|
validValue = `${value}px`;
|
||||||
|
} else if (value === '' || value == null || typeof value === 'boolean') {
|
||||||
|
validValue = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return validValue;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置 DOM 节点的 style 属性
|
* 设置 DOM 节点的 style 属性
|
||||||
*/
|
*/
|
||||||
|
@ -32,20 +49,3 @@ function isNeedUnitCSS(propName: string) {
|
||||||
|| propName.startsWith('box')
|
|| propName.startsWith('box')
|
||||||
|| propName.endsWith('Opacity'));
|
|| propName.endsWith('Opacity'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 对一些没有写单位的样式进行适配,例如:width: 10 => width: 10px
|
|
||||||
* 对空值或布尔值进行适配,转为空字符串
|
|
||||||
* 去掉多余空字符
|
|
||||||
*/
|
|
||||||
export function adjustStyleValue(name, value) {
|
|
||||||
let validValue = value;
|
|
||||||
|
|
||||||
if (typeof value === 'number' && value !== 0 && isNeedUnitCSS(name)) {
|
|
||||||
validValue = `${value}px`;
|
|
||||||
} else if (value === '' || value == null || typeof value === 'boolean') {
|
|
||||||
validValue = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return validValue;
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,6 +18,13 @@ const svgHumpAttr = new Set(['allowReorder', 'autoReverse', 'baseFrequency', 'ba
|
||||||
'stitchTiles', 'surfaceScale','systemLanguage', 'tableValues', 'targetX', 'targetY',
|
'stitchTiles', 'surfaceScale','systemLanguage', 'tableValues', 'targetX', 'targetY',
|
||||||
'textLength','viewBox', 'viewTarget', 'xChannelSelector','yChannelSelector', 'zoomAndPan']);
|
'textLength','viewBox', 'viewTarget', 'xChannelSelector','yChannelSelector', 'zoomAndPan']);
|
||||||
|
|
||||||
|
// 驼峰 变 “-”
|
||||||
|
function convertToLowerCase(str) {
|
||||||
|
const replacer = (match, char) => `-${char.toLowerCase()}`;
|
||||||
|
|
||||||
|
return str.replace(/([A-Z])/g, replacer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 给 dom 设置属性
|
* 给 dom 设置属性
|
||||||
* attrName 指代码中属性设置的属性名称(如 class)
|
* attrName 指代码中属性设置的属性名称(如 class)
|
||||||
|
@ -70,12 +77,3 @@ export function updateCommonProp(dom: Element, attrName: string, value: any, isN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 驼峰 变 “-”
|
|
||||||
function convertToLowerCase(str) {
|
|
||||||
const replacer = (match, char) => {
|
|
||||||
return `-${char.toLowerCase()}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return str.replace(/([A-Z])/g, replacer);
|
|
||||||
};
|
|
||||||
|
|
|
@ -105,16 +105,16 @@ export function getSelectionInfo() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface selectionData {
|
export interface SelectionData {
|
||||||
focusedDom: HTMLInputElement | HTMLTextAreaElement | void;
|
focusedDom: HTMLInputElement | HTMLTextAreaElement | void;
|
||||||
selectionRange: {
|
selectionRange: {
|
||||||
start: number;
|
start: number | null;
|
||||||
end: number;
|
end: number | null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 防止选择范围内的信息因为节点删除或其他原因导致的信息丢失
|
// 防止选择范围内的信息因为节点删除或其他原因导致的信息丢失
|
||||||
export function resetSelectionRange(preSelectionRangeData: selectionData) {
|
export function resetSelectionRange(preSelectionRangeData: SelectionData) {
|
||||||
// 当前 focus 的元素
|
// 当前 focus 的元素
|
||||||
const currentFocusedDom = getIFrameFocusedDom();
|
const currentFocusedDom = getIFrameFocusedDom();
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ export enum PROPERTY_TYPE {
|
||||||
STRING, // 普通的字符串类型
|
STRING, // 普通的字符串类型
|
||||||
SPECIAL, // 需要特殊处理的属性类型
|
SPECIAL, // 需要特殊处理的属性类型
|
||||||
BOOLEAN_STR, // 字符串类型的 true false
|
BOOLEAN_STR, // 字符串类型的 true false
|
||||||
};
|
}
|
||||||
|
|
||||||
export type PropDetails = {
|
export type PropDetails = {
|
||||||
propName: string;
|
propName: string;
|
||||||
|
@ -15,10 +15,6 @@ export type PropDetails = {
|
||||||
attrNS: string | null;
|
attrNS: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getPropDetails(name: string): PropDetails | null {
|
|
||||||
return propsDetailData[name] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 属性相关数据
|
// 属性相关数据
|
||||||
// 依次为 propertyName、type、attributeName、attributeNamespace,不填则使用默认值
|
// 依次为 propertyName、type、attributeName、attributeNamespace,不填则使用默认值
|
||||||
// type 默认 STRING
|
// type 默认 STRING
|
||||||
|
@ -123,3 +119,7 @@ propertiesData.forEach(record => {
|
||||||
attrNS,
|
attrNS,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export function getPropDetails(name: string): PropDetails | null {
|
||||||
|
return propsDetailData[name] || null;
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,11 @@ function isInvalidBoolean(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 是事件属性
|
||||||
|
export function isEventProp(propName) {
|
||||||
|
return propName.substr(0, 2) === 'on';
|
||||||
|
}
|
||||||
|
|
||||||
function isValidProp(tagName, name, value) {
|
function isValidProp(tagName, name, value) {
|
||||||
// 校验事件名称
|
// 校验事件名称
|
||||||
if (isEventProp(name)) {
|
if (isEventProp(name)) {
|
||||||
|
@ -79,11 +84,6 @@ export function isInvalidValue(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 是事件属性
|
|
||||||
export function isEventProp(propName) {
|
|
||||||
return propName.substr(0, 2) === 'on';
|
|
||||||
}
|
|
||||||
|
|
||||||
// dev模式下校验属性是否合法
|
// dev模式下校验属性是否合法
|
||||||
export function validateProps(type, props) {
|
export function validateProps(type, props) {
|
||||||
if (!props) {
|
if (!props) {
|
||||||
|
|
|
@ -1,14 +1,5 @@
|
||||||
import {HorizonSelect, IProperty} from '../utils/Interface';
|
import {HorizonSelect, IProperty} from '../utils/Interface';
|
||||||
|
|
||||||
// 更新 <option>
|
|
||||||
function updateValue(options, newValues: any, isMultiple: boolean) {
|
|
||||||
if (isMultiple) {
|
|
||||||
updateMultipleValue(options, newValues);
|
|
||||||
} else {
|
|
||||||
updateSingleValue(options, newValues);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateMultipleValue(options, newValues) {
|
function updateMultipleValue(options, newValues) {
|
||||||
const newValueSet = new Set();
|
const newValueSet = new Set();
|
||||||
|
|
||||||
|
@ -39,6 +30,15 @@ function updateSingleValue(options, newValue) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新 <option>
|
||||||
|
function updateValue(options, newValues: any, isMultiple: boolean) {
|
||||||
|
if (isMultiple) {
|
||||||
|
updateMultipleValue(options, newValues);
|
||||||
|
} else {
|
||||||
|
updateSingleValue(options, newValues);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getSelectPropsWithoutValue(dom: HorizonSelect, properties: Object) {
|
export function getSelectPropsWithoutValue(dom: HorizonSelect, properties: Object) {
|
||||||
return {
|
return {
|
||||||
...properties,
|
...properties,
|
||||||
|
|
|
@ -21,7 +21,6 @@ export type JSXElement = {
|
||||||
key: any;
|
key: any;
|
||||||
ref: any;
|
ref: any;
|
||||||
props: any;
|
props: any;
|
||||||
|
|
||||||
belongClassVNode: any;
|
belongClassVNode: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
let isMessageLoopRunning = false;
|
let isMessageLoopRunning = false;
|
||||||
let browserCallback = null;
|
let browserCallback = null;
|
||||||
|
const { port1, port2 } = new MessageChannel();
|
||||||
|
|
||||||
|
|
||||||
export function isOverTime() {
|
export function isOverTime() {
|
||||||
|
@ -33,7 +34,7 @@ const callRenderTasks = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const { port1, port2 } = new MessageChannel();
|
|
||||||
port1.onmessage = callRenderTasks;
|
port1.onmessage = callRenderTasks;
|
||||||
|
|
||||||
export function requestBrowserCallback(callback) {
|
export function requestBrowserCallback(callback) {
|
||||||
|
|
|
@ -12,30 +12,6 @@ let callingQueueTask: any | null = null;
|
||||||
// 防止重入
|
// 防止重入
|
||||||
let isCallingRenderQueue = false;
|
let isCallingRenderQueue = false;
|
||||||
|
|
||||||
export function pushRenderCallback(callback: RenderCallback) {
|
|
||||||
if (renderQueue === null) {
|
|
||||||
renderQueue = [callback];
|
|
||||||
// 高优先级的异步调度
|
|
||||||
callingQueueTask = runAsync(callRenderQueue, ImmediatePriority);
|
|
||||||
} else {
|
|
||||||
// 不需要调度,在syncQueue创建的时候已经调度了
|
|
||||||
renderQueue.push(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回一个空对象,用于区别null
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function callRenderQueueImmediate() {
|
|
||||||
if (callingQueueTask !== null) {
|
|
||||||
// 取消异步调度
|
|
||||||
cancelTask(callingQueueTask);
|
|
||||||
callingQueueTask = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
callRenderQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行render回调
|
// 执行render回调
|
||||||
function callRenderQueue() {
|
function callRenderQueue() {
|
||||||
if (!isCallingRenderQueue && renderQueue !== null) {
|
if (!isCallingRenderQueue && renderQueue !== null) {
|
||||||
|
@ -64,3 +40,27 @@ function callRenderQueue() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function pushRenderCallback(callback: RenderCallback) {
|
||||||
|
if (renderQueue === null) {
|
||||||
|
renderQueue = [callback];
|
||||||
|
// 高优先级的异步调度
|
||||||
|
callingQueueTask = runAsync(callRenderQueue, ImmediatePriority);
|
||||||
|
} else {
|
||||||
|
// 不需要调度,在syncQueue创建的时候已经调度了
|
||||||
|
renderQueue.push(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回一个空对象,用于区别null
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function callRenderQueueImmediate() {
|
||||||
|
if (callingQueueTask !== null) {
|
||||||
|
// 取消异步调度
|
||||||
|
cancelTask(callingQueueTask);
|
||||||
|
callingQueueTask = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
callRenderQueue();
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* 调度器的核心实现
|
* 调度器的核心实现
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Node } from '../taskExecutor/TaskQueue';
|
||||||
import {
|
import {
|
||||||
requestBrowserCallback,
|
requestBrowserCallback,
|
||||||
isOverTime,
|
isOverTime,
|
||||||
|
@ -21,39 +22,11 @@ let isProcessing = false;
|
||||||
// 调度中,等待浏览器回调
|
// 调度中,等待浏览器回调
|
||||||
let isWaiting = false;
|
let isWaiting = false;
|
||||||
|
|
||||||
function runAsync(callback, priorityLevel= NormalPriority ) {
|
|
||||||
let increment;
|
|
||||||
switch (priorityLevel) {
|
|
||||||
case ImmediatePriority:
|
|
||||||
increment = -1;
|
|
||||||
break;
|
|
||||||
case NormalPriority:
|
|
||||||
default:
|
|
||||||
increment = 10000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const task = {
|
|
||||||
id: idCounter++,
|
|
||||||
callback,
|
|
||||||
order: idCounter + increment,
|
|
||||||
};
|
|
||||||
|
|
||||||
add(task);
|
|
||||||
|
|
||||||
if (!isWaiting && !isProcessing) {
|
|
||||||
isWaiting = true;
|
|
||||||
requestBrowserCallback(callTasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
function callTasks() {
|
function callTasks() {
|
||||||
isWaiting = false;
|
isWaiting = false;
|
||||||
isProcessing = true;
|
isProcessing = true;
|
||||||
|
|
||||||
let task = null;
|
let task: Node | null= null;
|
||||||
try {
|
try {
|
||||||
task = first();
|
task = first();
|
||||||
|
|
||||||
|
@ -89,6 +62,34 @@ function callTasks() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function runAsync(callback, priorityLevel= NormalPriority ) {
|
||||||
|
let increment;
|
||||||
|
switch (priorityLevel) {
|
||||||
|
case ImmediatePriority:
|
||||||
|
increment = -1;
|
||||||
|
break;
|
||||||
|
case NormalPriority:
|
||||||
|
default:
|
||||||
|
increment = 10000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const task = {
|
||||||
|
id: idCounter++,
|
||||||
|
callback,
|
||||||
|
order: idCounter + increment,
|
||||||
|
};
|
||||||
|
|
||||||
|
add(task);
|
||||||
|
|
||||||
|
if (!isWaiting && !isProcessing) {
|
||||||
|
isWaiting = true;
|
||||||
|
requestBrowserCallback(callTasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
function cancelTask(task) {
|
function cancelTask(task) {
|
||||||
task.callback = null;
|
task.callback = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type Queue = Array<Node>;
|
type Queue = Array<Node>;
|
||||||
type Node = {
|
export type Node = {
|
||||||
id: number;
|
id: number;
|
||||||
order: number;
|
order: number;
|
||||||
};
|
};
|
||||||
|
@ -11,15 +11,10 @@ type Node = {
|
||||||
// 任务队列
|
// 任务队列
|
||||||
const taskQueue: Queue = [];
|
const taskQueue: Queue = [];
|
||||||
|
|
||||||
export function add(node: Node): void {
|
function compare(a: Node, b: Node) {
|
||||||
// 查找第一个大于等于 value 的下标,都比 value 小则返回 -1
|
// 优先先用index排序,其次用id
|
||||||
const idx = getBiggerIdx(node);
|
const diff = a.order - b.order;
|
||||||
|
return diff !== 0 ? diff : a.id - b.id;
|
||||||
if (idx === -1) {
|
|
||||||
taskQueue.push(node);
|
|
||||||
} else {
|
|
||||||
taskQueue.splice(idx, 0, node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 二分法查找第一个大于等于 value 的下标,都比 value 小则返回 -1,时间复杂度O(logn)
|
// 二分法查找第一个大于等于 value 的下标,都比 value 小则返回 -1,时间复杂度O(logn)
|
||||||
|
@ -37,11 +32,22 @@ function getBiggerIdx(node: Node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (left < taskQueue.length) ? left : -1;
|
return left < taskQueue.length ? left : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function add(node: Node): void {
|
||||||
|
// 查找第一个大于等于 value 的下标,都比 value 小则返回 -1
|
||||||
|
const idx = getBiggerIdx(node);
|
||||||
|
|
||||||
|
if (idx === -1) {
|
||||||
|
taskQueue.push(node);
|
||||||
|
} else {
|
||||||
|
taskQueue.splice(idx, 0, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function first(): Node | null {
|
export function first(): Node | null {
|
||||||
const val = taskQueue[0];
|
const val: Node | null | undefined = taskQueue[0];
|
||||||
return val !== undefined ? val : null;
|
return val !== undefined ? val : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,9 +59,3 @@ export function shift(): Node | null {
|
||||||
export function remove(node: Node) {
|
export function remove(node: Node) {
|
||||||
taskQueue.splice(taskQueue.indexOf(node), 1);
|
taskQueue.splice(taskQueue.indexOf(node), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function compare(a: Node, b: Node) {
|
|
||||||
// 优先先用index排序,其次用id
|
|
||||||
const diff = a.order - b.order;
|
|
||||||
return diff !== 0 ? diff : a.id - b.id;
|
|
||||||
}
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ export function onlyUpdateChildVNodes(processing: VNode): VNode | null {
|
||||||
// 此vNode无需更新,但是子树需要
|
// 此vNode无需更新,但是子树需要
|
||||||
if (!processing.isCreated && processing.child !== null) {
|
if (!processing.isCreated && processing.child !== null) {
|
||||||
// 更新子节点
|
// 更新子节点
|
||||||
let child = processing.child;
|
let child: VNode | null = processing.child;
|
||||||
while (child !== null) {
|
while (child !== null) {
|
||||||
updateVNode(child, child.props);
|
updateVNode(child, child.props);
|
||||||
updateVNodePath(child);
|
updateVNodePath(child);
|
||||||
|
|
|
@ -37,6 +37,19 @@ export function updateChildShouldUpdate(vNode: VNode) {
|
||||||
vNode.childShouldUpdate = false;
|
vNode.childShouldUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新从当前节点到根节点的childShouldUpdate为true
|
||||||
|
export function setParentsChildShouldUpdate(parent: VNode | null) {
|
||||||
|
let node = parent;
|
||||||
|
while (node !== null) {
|
||||||
|
if (node.childShouldUpdate) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
node.childShouldUpdate = true;
|
||||||
|
|
||||||
|
node = node.parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 设置节点的所有父节点的childShouldUpdate
|
// 设置节点的所有父节点的childShouldUpdate
|
||||||
export function updateParentsChildShouldUpdate(vNode: VNode) {
|
export function updateParentsChildShouldUpdate(vNode: VNode) {
|
||||||
let node = vNode.parent;
|
let node = vNode.parent;
|
||||||
|
@ -51,16 +64,3 @@ export function updateParentsChildShouldUpdate(vNode: VNode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新从当前节点到根节点的childShouldUpdate为true
|
|
||||||
export function setParentsChildShouldUpdate(parent: VNode | null) {
|
|
||||||
let node = parent;
|
|
||||||
while (node !== null) {
|
|
||||||
if (node.childShouldUpdate) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
node.childShouldUpdate = true;
|
|
||||||
|
|
||||||
node = node.parent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue