Match-id-f8ecd1a4fccd7fdcabbbedc46d6ecbcf8b98d02b

This commit is contained in:
* 2022-11-12 02:40:09 +08:00
commit 6d25551899
190 changed files with 3992 additions and 1289 deletions

View File

@ -8,15 +8,13 @@ notifications:
buildspace: buildspace:
log_collect: log_collect:
- config/CI/build/logs - config/CI/build/logs
fixed: true fixed: false
env: env:
resource: resource:
type: docker type: docker
image: kweecr04.his.huawei.com:80/ecr-build-arm-gzkunpeng/euleros_v2r7spc522_x64_opmt_cs5.0_sz:v5.0 image: kweecr04.his.huawei.com:80/ecr-build-arm-gzkunpeng/euleros_v2r7spc522_x64_opmt_cs5.0_sz:v5.0
class: 4U8G class: 4U8G
mode: toolbox mode: toolbox
cache:
- type: workspace
steps: steps:
PRE_BUILD: PRE_BUILD:
- checkout: - checkout:
@ -34,4 +32,11 @@ steps:
yarn yarn
yarn run test yarn run test
yarn run build yarn run build
node .cloudbuild/release.js sh .cloudbuild/release.sh
enhance:
- feature: md5_source_tracement
build_tools: [npm]
check:
auto: true
buildcheck: true
mode: sync

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
*/
const fs = require('fs');
const path = require('path');
const childProcess = require('child_process');
const version = process.env.releaseVersion;
const DIST_PATH = path.resolve(__dirname, '../build/horizon');
const NPMRC = `registry=https://cmc.centralrepo.rnd.huawei.com/npm
@cloudsop:registry=https://cmc.centralrepo.rnd.huawei.com/artifactory/product_npm
_auth = Y2xvdWRzb3BhcnRpZmFjdG9yeTpDbG91ZHNvcDY2NiEhIQ
always-auth = true
email = cloudsop@huawei.com
`;
if (!version) {
process.exit();
}
if (!/\d+\.\d+\.\d+/.test(version)) {
console.log('请输入正确版本号');
process.exit();
}
const exec = (cmd, cwd) => {
return new Promise((resolve, reject) => {
childProcess.exec(
cmd,
{
cwd,
},
function (error, stdout, stderr) {
if (error) {
error && console.log(`Error: ${error}`);
reject(error);
} else {
stdout && console.log(`STDOUT: ${stdout}`);
resolve(stdout);
}
}
);
});
};
const main = async () => {
try {
console.log(`==== Horizon Upgrade ${version} ====`);
await exec(`npm version ${version}`, DIST_PATH);
fs.writeFileSync(path.resolve(DIST_PATH, '.npmrc'), NPMRC);
console.log('==== Publish new version====');
await exec('npm publish', DIST_PATH);
process.exit();
} catch (err) {
console.error(err);
process.exit(1);
}
};
main();

36
.cloudbuild/release.sh Normal file
View File

@ -0,0 +1,36 @@
#!/bin/bash
#
# Copyright (c) 2020 Huawei Technologies Co.,Ltd.
#
# openGauss is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
#
if [ -n "${releaseVersion}" ] ; then
echo "==== Horizon Upgrade ${releaseVersion} ===="
cd ./build/horizon || { echo 'ERROR: Build directory not found' ; exit 1; }
# 写入新版本号
npm version "${releaseVersion}"
cat >.npmrc <<- EndOfMessage
registry=https://cmc.centralrepo.rnd.huawei.com/npm
@cloudsop:registry=https://cmc.centralrepo.rnd.huawei.com/artifactory/api/npm/product_npm
_auth = Y2xvdWRzb3BhcnRpZmFjdG9yeTpDbG91ZHNvcDY2NiEhIQ
always-auth = true
email = cloudsop@huawei.com
EndOfMessage
echo "==== Publish new version===="
# npm仓库发布接口返回HTML屏蔽错误码
npm publish || echo 'WARNING: Parsing publish response failed'
npm view @cloudsop/horizon@"${releaseVersion}"
else
echo "No release version, quit."
fi

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
module.exports = { module.exports = {
extends: [ extends: [
'eslint:recommended', 'eslint:recommended',

View File

@ -0,0 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright (c) 2020 Huawei Technologies Co.,Ltd.&#10;&#10;openGauss is licensed under Mulan PSL v2.&#10;You can use this software according to the terms and conditions of the Mulan PSL v2.&#10;You may obtain a copy of Mulan PSL v2 at:&#10;&#10; http://license.coscl.org.cn/MulanPSL2&#10;&#10;THIS SOFTWARE IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OF ANY KIND,&#10;EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,&#10;MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.&#10;See the Mulan PSL v2 for more details." />
<option name="myName" value="huawei" />
</copyright>
</component>

View File

@ -0,0 +1,7 @@
<component name="CopyrightManager">
<settings default="huawei">
<LanguageOptions name="JavaScript">
<option name="fileTypeOverride" value="3" />
</LanguageOptions>
</settings>
</component>

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
'use strict'; 'use strict';
module.exports = { module.exports = {

View File

@ -1,3 +1,15 @@
## 0.0.26 (2022-11-09)
- **CI**: 包信息同步CMC
## 0.0.25 (2022-11-03)
- **core**: fix 修改IE中Set的不兼容问题
## 0.0.24 (2022-10-25)
- **core**: fix 修改IE上报Symbol错误的问题
## 0.0.23 (2022-09-23)
- **core**: #86 兼容ReactIs API
## 0.0.22 (2022-09-22) ## 0.0.22 (2022-09-22)
- **core**: #83 #75 #72 input支持受控 - **core**: #83 #75 #72 input支持受控

125
License Normal file
View File

@ -0,0 +1,125 @@
木兰宽松许可证, 第2版
木兰宽松许可证, 第2版
2020年1月 http://license.coscl.org.cn/MulanPSL2
您对“软件”的复制、使用、修改及分发受木兰宽松许可证第2版“本许可证”的如下条款的约束
0. 定义
“软件” 是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。
“贡献” 是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。
“贡献者” 是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。
“法人实体” 是指提交贡献的机构及其“关联实体”。
“关联实体” 是指对“本许可证”下的行为方而言控制、受控制或与其共同受控制的机构此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。
1. 授予版权许可
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。
2. 授予专利许可
每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。
3. 无商标许可
“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可但您为满足第4条规定的声明义务而必须使用除外。
4. 分发限制
您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。
5. 免责声明与责任限制
“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。
6. 语言
“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。
条款结束
如何将木兰宽松许可证第2版应用到您的软件
如果您希望将木兰宽松许可证第2版应用到您的新软件为了方便接收者查阅建议您完成如下三步
1 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字;
2 请您在软件包的一级目录下创建以“LICENSE”为名的文件将整个许可证文本放入该文件中
3 请将如下声明文本放入每个源文件的头部注释中。
Copyright (c) [Year] [name of copyright holder]
[Software Name] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
Mulan Permissive Software LicenseVersion 2
Mulan Permissive Software LicenseVersion 2 (Mulan PSL v2)
January 2020 http://license.coscl.org.cn/MulanPSL2
Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions:
0. Definition
Software means the program and related documents which are licensed under this License and comprise all Contribution(s).
Contribution means the copyrightable work licensed by a particular Contributor under this License.
Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License.
Legal Entity means the entity making a Contribution and all its Affiliates.
Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, control means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.
1. Grant of Copyright License
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
2. Grant of Patent License
Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.
3. No Trademark License
No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4.
4. Distribution Restriction
You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.
5. Disclaimer of Warranty and Limitation of Liability
THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW ITS CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
6. Language
THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL.
END OF THE TERMS AND CONDITIONS
How to Apply the Mulan Permissive Software LicenseVersion 2 (Mulan PSL v2) to Your Software
To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps:
Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;
Create a file named "LICENSE" which contains the whole context of this License in the first directory of your software package;
Attach the statement to the appropriate annotated syntax at the beginning of each source file.
Copyright (c) [Year] [name of copyright holder]
[Software Name] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
module.exports = { module.exports = {
presets: ['@babel/preset-typescript', ['@babel/preset-env', { targets: { node: 'current' } }]], presets: ['@babel/preset-typescript', ['@babel/preset-env', { targets: { node: 'current' } }]],
plugins: [ plugins: [

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
module.exports = { module.exports = {
coverageDirectory: 'coverage', coverageDirectory: 'coverage',
resetModules: true, resetModules: true,

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/* /*
*/ */

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { import {
TYPE_FRAGMENT as Fragment, TYPE_FRAGMENT as Fragment,
TYPE_PROFILER as Profiler, TYPE_PROFILER as Profiler,
@ -30,7 +45,17 @@ import {
import { asyncUpdates } from './src/renderer/TreeBuilder'; import { asyncUpdates } from './src/renderer/TreeBuilder';
import { callRenderQueueImmediate } from './src/renderer/taskExecutor/RenderQueue'; import { callRenderQueueImmediate } from './src/renderer/taskExecutor/RenderQueue';
import { runAsyncEffects } from './src/renderer/submit/HookEffectHandler'; import { runAsyncEffects } from './src/renderer/submit/HookEffectHandler';
import {
isContextProvider,
isContextConsumer,
isElement,
isValidElementType,
isForwardRef,
isFragment,
isLazy,
isMemo,
isPortal,
} from './src/external/HorizonIs';
import { createStore, useStore, clearStore } from './src/horizonx/store/StoreHandler'; import { createStore, useStore, clearStore } from './src/horizonx/store/StoreHandler';
import * as reduxAdapter from './src/horizonx/adapters/redux'; import * as reduxAdapter from './src/horizonx/adapters/redux';
import { watch } from './src/horizonx/proxy/watch'; import { watch } from './src/horizonx/proxy/watch';
@ -87,6 +112,15 @@ const Horizon = {
clearStore, clearStore,
reduxAdapter, reduxAdapter,
watch, watch,
isFragment,
isElement,
isValidElementType,
isForwardRef,
isLazy,
isMemo,
isPortal,
isContextProvider,
isContextConsumer,
}; };
export const version = __VERSION__; export const version = __VERSION__;
@ -128,6 +162,16 @@ export {
clearStore, clearStore,
reduxAdapter, reduxAdapter,
watch, watch,
// 兼容ReactIs
isFragment,
isElement,
isValidElementType,
isForwardRef,
isLazy,
isMemo,
isPortal,
isContextProvider,
isContextConsumer,
}; };
export default Horizon; export default Horizon;

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
'use strict'; 'use strict';
if (process.env.NODE_ENV === 'production') { if (process.env.NODE_ENV === 'production') {

View File

@ -4,7 +4,7 @@
"keywords": [ "keywords": [
"horizon" "horizon"
], ],
"version": "0.0.22", "version": "0.0.26",
"homepage": "", "homepage": "",
"bugs": "", "bugs": "",
"main": "index.js", "main": "index.js",

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { asyncUpdates, getFirstCustomDom, syncUpdates, startUpdate, createTreeRootVNode } from '../renderer/Renderer'; import { asyncUpdates, getFirstCustomDom, syncUpdates, startUpdate, createTreeRootVNode } from '../renderer/Renderer';
import { createPortal } from '../renderer/components/CreatePortal'; import { createPortal } from '../renderer/components/CreatePortal';
import type { Container } from './DOMOperator'; import type { Container } from './DOMOperator';

View File

@ -1,18 +1,26 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/** /**
* dom节点赋 VNode * dom节点赋 VNode
*/ */
import type {VNode} from '../renderer/Types'; import type { VNode } from '../renderer/Types';
import type { import type { Container, Props } from './DOMOperator';
Container,
Props,
} from './DOMOperator';
import { import { DomComponent, DomText, TreeRoot } from '../renderer/vnode/VNodeTags';
DomComponent,
DomText,
TreeRoot,
} from '../renderer/vnode/VNodeTags';
const INTERNAL_VNODE = '_horizon_VNode'; const INTERNAL_VNODE = '_horizon_VNode';
const INTERNAL_PROPS = '_horizon_Props'; const INTERNAL_PROPS = '_horizon_Props';
@ -20,7 +28,7 @@ const INTERNAL_NONDELEGATEEVENTS = '_horizon_NonDelegatedEvents';
// 通过 VNode 实例获取 DOM 节点 // 通过 VNode 实例获取 DOM 节点
export function getDom(vNode: VNode): Element | Text | null { 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;
} }
@ -28,18 +36,15 @@ export function getDom(vNode: VNode): Element | Text | null {
} }
// 将 VNode 属性相关信息挂到 DOM 对象的特定属性上 // 将 VNode 属性相关信息挂到 DOM 对象的特定属性上
export function saveVNode( export function saveVNode(vNode: VNode, dom: Element | Text | Container): void {
vNode: VNode,
dom: Element | Text | Container,
): void {
dom[INTERNAL_VNODE] = vNode; dom[INTERNAL_VNODE] = vNode;
} }
// 用 DOM 节点,来找其对应的 VNode 实例 // 用 DOM 节点,来找其对应的 VNode 实例
export function getVNode(dom: Node|Container): VNode | null { export function getVNode(dom: Node | Container): VNode | null {
const vNode = dom[INTERNAL_VNODE] || (dom as Container)._treeRoot; const vNode = dom[INTERNAL_VNODE] || (dom as Container)._treeRoot;
if (vNode) { if (vNode) {
const {tag} = vNode; const { tag } = vNode;
if (tag === DomComponent || tag === DomText || tag === TreeRoot) { if (tag === DomComponent || tag === DomText || tag === TreeRoot) {
return vNode; return vNode;
} }
@ -63,7 +68,7 @@ export function getNearestVNode(dom: Node): null | VNode {
} }
// 获取 vNode 上的属性相关信息 // 获取 vNode 上的属性相关信息
export function getVNodeProps(dom: Element | Text): Props | null{ export function getVNodeProps(dom: Element | Text): Props | null {
return dom[INTERNAL_PROPS] || null; return dom[INTERNAL_PROPS] || null;
} }

View File

@ -1,24 +1,27 @@
import { /*
saveVNode, * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
updateVNodeProps, *
} from './DOMInternalKeys'; * openGauss is licensed under Mulan PSL v2.
import { * You can use this software according to the terms and conditions of the Mulan PSL v2.
createDom, * You may obtain a copy of Mulan PSL v2 at:
} from './utils/DomCreator'; *
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { saveVNode, updateVNodeProps } from './DOMInternalKeys';
import { createDom } from './utils/DomCreator';
import { getSelectionInfo, resetSelectionRange, SelectionData } from './SelectionRangeHandler'; import { getSelectionInfo, resetSelectionRange, SelectionData } from './SelectionRangeHandler';
import { shouldAutoFocus } from './utils/Common'; import { shouldAutoFocus } from './utils/Common';
import { NSS } from './utils/DomCreator'; import { NSS } from './utils/DomCreator';
import { adjustStyleValue } from './DOMPropertiesHandler/StyleHandler'; import { adjustStyleValue } from './DOMPropertiesHandler/StyleHandler';
import type { VNode } from '../renderer/Types'; import type { VNode } from '../renderer/Types';
import { import { setInitValue, getPropsWithoutValue, updateValue } from './valueHandler';
setInitValue, import { compareProps, setDomProps } from './DOMPropertiesHandler/DOMPropertiesHandler';
getPropsWithoutValue,
updateValue,
} from './valueHandler';
import {
compareProps,
setDomProps,
} from './DOMPropertiesHandler/DOMPropertiesHandler';
import { isNativeElement, validateProps } from './validators/ValidateProps'; import { isNativeElement, validateProps } from './validators/ValidateProps';
import { watchValueChange } from './valueHandler/ValueChangeHandler'; import { watchValueChange } from './valueHandler/ValueChangeHandler';
import { DomComponent, DomText } from '../renderer/vnode/VNodeTags'; import { DomComponent, DomText } from '../renderer/vnode/VNodeTags';
@ -66,12 +69,7 @@ export function resetAfterSubmit(): void {
} }
// 创建 DOM 对象 // 创建 DOM 对象
export function newDom( export function newDom(tagName: string, props: Props, parentNamespace: string, vNode: VNode): Element {
tagName: string,
props: Props,
parentNamespace: string,
vNode: VNode,
): Element {
const dom: Element = createDom(tagName, parentNamespace); const dom: Element = createDom(tagName, parentNamespace);
// 将 vNode 节点挂到 DOM 对象上 // 将 vNode 节点挂到 DOM 对象上
saveVNode(vNode, dom); saveVNode(vNode, dom);
@ -104,12 +102,7 @@ export function initDomProps(dom: Element, tagName: string, rawProps: Props): bo
} }
// 准备更新之前进行一系列校验 DOM寻找属性差异等准备工作 // 准备更新之前进行一系列校验 DOM寻找属性差异等准备工作
export function getPropChangeList( export function getPropChangeList(dom: Element, type: string, lastRawProps: Props, nextRawProps: Props): Object {
dom: Element,
type: string,
lastRawProps: Props,
nextRawProps: Props,
): Object {
// 校验两个对象的不同 // 校验两个对象的不同
validateProps(type, nextRawProps); validateProps(type, nextRawProps);
@ -136,10 +129,7 @@ export function isTextChild(type: string, props: Props): boolean {
} }
} }
export function newTextDom( export function newTextDom(text: string, processing: VNode): Text {
text: string,
processing: VNode,
): Text {
const textNode: Text = document.createTextNode(text); const textNode: Text = document.createTextNode(text);
saveVNode(processing, textNode); saveVNode(processing, textNode);
return textNode; return textNode;
@ -183,26 +173,16 @@ export function clearText(dom: Element): void {
} }
// 添加child元素 // 添加child元素
export function appendChildElement( export function appendChildElement(parent: Element | Container, child: Element | Text): void {
parent: Element | Container,
child: Element | Text
): void {
parent.appendChild(child); parent.appendChild(child);
} }
// 插入dom元素 // 插入dom元素
export function insertDomBefore( export function insertDomBefore(parent: Element | Container, child: Element | Text, beforeChild: Element | Text) {
parent: Element | Container,
child: Element | Text,
beforeChild: Element | Text,
) {
parent.insertBefore(child, beforeChild); parent.insertBefore(child, beforeChild);
} }
export function removeChildDom( export function removeChildDom(parent: Element | Container, child: Element | Text) {
parent: Element | Container,
child: Element | Text
) {
parent.removeChild(child); parent.removeChild(child);
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { allDelegatedHorizonEvents } from '../../event/EventHub'; import { allDelegatedHorizonEvents } from '../../event/EventHub';
import { updateCommonProp } from './UpdateCommonProp'; import { updateCommonProp } from './UpdateCommonProp';
import { setStyles } from './StyleHandler'; import { setStyles } from './StyleHandler';
@ -66,11 +81,7 @@ export function compareProps(oldProps: Object, newProps: Object): Object {
styleProp = styleProps[j]; styleProp = styleProps[j];
updatesForStyle[styleProp] = ''; updatesForStyle[styleProp] = '';
} }
} else if ( } else if (propName === 'autoFocus' || propName === 'children' || propName === 'dangerouslySetInnerHTML') {
propName === 'autoFocus' ||
propName === 'children' ||
propName === 'dangerouslySetInnerHTML'
) {
continue; continue;
} else if (isEventProp(propName)) { } else if (isEventProp(propName)) {
if (!allDelegatedHorizonEvents.has(propName)) { if (!allDelegatedHorizonEvents.has(propName)) {

View File

@ -1,12 +1,29 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
function isNeedUnitCSS(styleName: string) { function isNeedUnitCSS(styleName: string) {
return !(noUnitCSS.includes(styleName) return !(
|| styleName.startsWith('borderImage') noUnitCSS.includes(styleName) ||
|| styleName.startsWith('flex') styleName.startsWith('borderImage') ||
|| styleName.startsWith('gridRow') styleName.startsWith('flex') ||
|| styleName.startsWith('gridColumn') styleName.startsWith('gridRow') ||
|| styleName.startsWith('stroke') styleName.startsWith('gridColumn') ||
|| styleName.startsWith('box') styleName.startsWith('stroke') ||
|| styleName.endsWith('Opacity')); styleName.startsWith('box') ||
styleName.endsWith('Opacity')
);
} }
/** /**
@ -14,7 +31,7 @@ function isNeedUnitCSS(styleName: string) {
* *
* *
*/ */
export function adjustStyleValue(name, value) { export function adjustStyleValue(name, value) {
let validValue = value; let validValue = value;
if (typeof value === 'number' && value !== 0 && isNeedUnitCSS(name)) { if (typeof value === 'number' && value !== 0 && isNeedUnitCSS(name)) {
@ -35,7 +52,7 @@ export function setStyles(dom, styles) {
} }
const style = dom.style; const style = dom.style;
Object.keys(styles).forEach((name) => { Object.keys(styles).forEach(name => {
const styleVal = styles[name]; const styleVal = styles[name];
style[name] = adjustStyleValue(name, styleVal); style[name] = adjustStyleValue(name, styleVal);
@ -45,5 +62,19 @@ export function setStyles(dom, styles) {
/** /**
* css * css
*/ */
const noUnitCSS = ['animationIterationCount', 'columnCount', 'columns', 'gridArea', 'fontWeight', 'lineClamp', const noUnitCSS = [
'lineHeight', 'opacity', 'order', 'orphans', 'tabSize', 'widows', 'zIndex', 'zoom']; 'animationIterationCount',
'columnCount',
'columns',
'gridArea',
'fontWeight',
'lineClamp',
'lineHeight',
'opacity',
'order',
'orphans',
'tabSize',
'widows',
'zIndex',
'zoom',
];

View File

@ -1,22 +1,91 @@
import { /*
getPropDetails, * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
PROPERTY_TYPE, *
} from '../validators/PropertiesData'; * openGauss is licensed under Mulan PSL v2.
import {isInvalidValue} from '../validators/ValidateProps'; * You can use this software according to the terms and conditions of the Mulan PSL v2.
import {getNamespaceCtx} from '../../renderer/ContextSaver'; * You may obtain a copy of Mulan PSL v2 at:
import {NSS} from '../utils/DomCreator'; *
import {getDomTag} from '../utils/Common'; * http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
const svgHumpAttr = new Set(['allowReorder', 'autoReverse', 'baseFrequency', 'baseProfile', 'calcMode', 'clipPathUnits', import { getPropDetails, PROPERTY_TYPE } from '../validators/PropertiesData';
'contentScriptType', 'contentStyleType', 'diffuseConstant', 'edgeMode', 'externalResourcesRequired', 'filterRes', import { isInvalidValue } from '../validators/ValidateProps';
'filterUnits', 'glyphRef', 'gradientTransform', 'gradientUnits', 'kernelMatrix', 'kernelUnitLength', 'keyPoints', import { getNamespaceCtx } from '../../renderer/ContextSaver';
'keySplines', 'keyTimes', 'lengthAdjust', 'limitingConeAngle', 'markerHeight', 'markerUnits', 'markerWidth', import { NSS } from '../utils/DomCreator';
'maskContentUnits', 'maskUnits', 'numOctaves', 'pathLength', 'patternContentUnits', 'patternTransform,', import { getDomTag } from '../utils/Common';
'patternUnits', 'pointsAtX', 'pointsAtY', 'pointsAtZ', 'preserveAlpha', 'preserveAspectRatio', 'primitiveUnits',
'referrerPolicy', 'refX', 'refY', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', // 不需要装换的svg属性集合
'specularConstant', 'specularExponent', 'spreadMethod', 'startOffset', 'stdDeviation', const svgHumpAttr = new Set();
'stitchTiles', 'surfaceScale','systemLanguage', 'tableValues', 'targetX', 'targetY', [
'textLength','viewBox', 'viewTarget', 'xChannelSelector','yChannelSelector', 'zoomAndPan']); 'allowReorder',
'autoReverse',
'baseFrequency',
'baseProfile',
'calcMode',
'clipPathUnits',
'contentScriptType',
'contentStyleType',
'diffuseConstant',
'edgeMode',
'externalResourcesRequired',
'filterRes',
'filterUnits',
'glyphRef',
'gradientTransform',
'gradientUnits',
'kernelMatrix',
'kernelUnitLength',
'keyPoints',
'keySplines',
'keyTimes',
'lengthAdjust',
'limitingConeAngle',
'markerHeight',
'markerUnits',
'markerWidth',
'maskContentUnits',
'maskUnits',
'numOctaves',
'pathLength',
'patternContentUnits',
'patternTransform,',
'patternUnits',
'pointsAtX',
'pointsAtY',
'pointsAtZ',
'preserveAlpha',
'preserveAspectRatio',
'primitiveUnits',
'referrerPolicy',
'refX',
'refY',
'repeatCount',
'repeatDur',
'requiredExtensions',
'requiredFeatures',
'specularConstant',
'specularExponent',
'spreadMethod',
'startOffset',
'stdDeviation',
'stitchTiles',
'surfaceScale',
'systemLanguage',
'tableValues',
'targetX',
'targetY',
'textLength',
'viewBox',
'viewTarget',
'xChannelSelector',
'yChannelSelector',
'zoomAndPan',
].forEach((name) => svgHumpAttr.add(name));
// 驼峰 变 “-” // 驼峰 变 “-”
function convertToLowerCase(str) { function convertToLowerCase(str) {
@ -50,19 +119,22 @@ export function updateCommonProp(dom: Element, attrName: string, value: any, isN
dom.setAttribute(attrName, String(value)); dom.setAttribute(attrName, String(value));
} }
} else if (['checked', 'multiple', 'muted', 'selected'].includes(propDetails.attrName)) { } else if (['checked', 'multiple', 'muted', 'selected'].includes(propDetails.attrName)) {
if (value === null) { // 必填属性设置默认值 if (value === null) {
// 必填属性设置默认值
dom[propDetails.attrName] = false; dom[propDetails.attrName] = false;
} else { } else {
dom[propDetails.attrName] = value; dom[propDetails.attrName] = value;
} }
} else { // 处理其他普通属性 } else {
// 处理其他普通属性
if (value === null) { if (value === null) {
dom.removeAttribute(propDetails.attrName); dom.removeAttribute(propDetails.attrName);
} else { } else {
const {type, attrNS} = propDetails; // 数据类型、固有属性命名空间 const { type, attrNS } = propDetails; // 数据类型、固有属性命名空间
const attributeName = propDetails.attrName; // 固有属性名 const attributeName = propDetails.attrName; // 固有属性名
let attributeValue; let attributeValue;
if (type === PROPERTY_TYPE.BOOLEAN) { // 即可以用作标志又可以是属性值的属性 if (type === PROPERTY_TYPE.BOOLEAN) {
// 即可以用作标志又可以是属性值的属性
attributeValue = ''; attributeValue = '';
} else { } else {
attributeValue = String(value); attributeValue = String(value);

View File

@ -1,10 +1,25 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/** /**
* *
*/ */
import {getIFrameFocusedDom, isText} from './utils/Common'; import { getIFrameFocusedDom, isText } from './utils/Common';
import {isElement} from './utils/Common'; import { isElement } from './utils/Common';
/** /**
* textarea input * textarea input
@ -61,7 +76,8 @@ function isNodeContainsByTargetNode(targetNode, node) {
if (typeof targetNode.contains === 'function') { if (typeof targetNode.contains === 'function') {
return targetNode.contains(node); // 该的节点是否为目标节点的后代节点 return targetNode.contains(node); // 该的节点是否为目标节点的后代节点
} }
if (typeof targetNode.compareDocumentPosition === 'function') { // compareDocumentPosition 数值,表示两个节点彼此做比较的位置 if (typeof targetNode.compareDocumentPosition === 'function') {
// compareDocumentPosition 数值,表示两个节点彼此做比较的位置
const CONTAINS_CODE = 16; const CONTAINS_CODE = 16;
// 返回 16 代表 第二节点在第一节点内部 // 返回 16 代表 第二节点在第一节点内部
return targetNode.compareDocumentPosition(node) === CONTAINS_CODE; return targetNode.compareDocumentPosition(node) === CONTAINS_CODE;
@ -138,9 +154,10 @@ export function resetSelectionRange(preSelectionRangeData: SelectionData) {
let ancestor = preFocusedDom.parentNode; let ancestor = preFocusedDom.parentNode;
// 查找先前的 focus 节点的先祖 // 查找先前的 focus 节点的先祖
while (ancestor) { while (ancestor) {
if (isElement(ancestor)) { // 是元素节点,就把先祖信息放到先祖数组中 if (isElement(ancestor)) {
// 是元素节点,就把先祖信息放到先祖数组中
// @ts-ignore // @ts-ignore
const {scrollLeft, scrollTop} = ancestor; const { scrollLeft, scrollTop } = ancestor;
ancestors.push({ ancestors.push({
dom: ancestor, dom: ancestor,
scrollLeft, scrollLeft,

View File

@ -1,5 +1,20 @@
import {HorizonDom} from './Interface'; /*
import {Props} from '../DOMOperator'; * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { HorizonDom } from './Interface';
import { Props } from '../DOMOperator';
/** /**
* input textarea * input textarea
@ -20,12 +35,15 @@ export function getIFrameFocusedDom() {
while (focusedDom instanceof currentWindow.HTMLIFrameElement) { while (focusedDom instanceof currentWindow.HTMLIFrameElement) {
try { try {
// 访问 HTMLIframeElement 的 contentDocument 可能会导致浏览器抛出错误 // 访问 HTMLIframeElement 的 contentDocument 可能会导致浏览器抛出错误
if (typeof focusedDom.contentWindow.location.href === 'string') { // iframe 的内容为同源 if (typeof focusedDom.contentWindow.location.href === 'string') {
// iframe 的内容为同源
focusedDom = getFocusedDom(focusedDom.contentWindow.document); focusedDom = getFocusedDom(focusedDom.contentWindow.document);
} else { // 非同源 iframe 因为安全性原因无法获取其中的具体元素 } else {
// 非同源 iframe 因为安全性原因无法获取其中的具体元素
break; break;
} }
} catch (e) { // 非同源 iframe 因为安全性原因无法获取其中的具体元素 } catch (e) {
// 非同源 iframe 因为安全性原因无法获取其中的具体元素
break; break;
} }
} }

View File

@ -1,3 +1,17 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export const NSS = { export const NSS = {
html: 'http://www.w3.org/1999/xhtml', html: 'http://www.w3.org/1999/xhtml',
@ -6,10 +20,7 @@ export const NSS = {
}; };
// 创建DOM元素 // 创建DOM元素
export function createDom( export function createDom(tagName: string, parentNamespace: string): Element {
tagName: string,
parentNamespace: string,
): Element {
let dom: Element; let dom: Element;
const selfNamespace = NSS[tagName] || NSS.html; const selfNamespace = NSS[tagName] || NSS.html;
const ns = parentNamespace !== NSS.html ? parentNamespace : selfNamespace; const ns = parentNamespace !== NSS.html ? parentNamespace : selfNamespace;

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export interface Props { export interface Props {
[propName: string]: any; [propName: string]: any;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/* eslint-disable no-sparse-arrays */ /* eslint-disable no-sparse-arrays */
// 属性值的数据类型 // 属性值的数据类型

View File

@ -1,20 +1,28 @@
import { /*
getPropDetails, PROPERTY_TYPE, PropDetails, * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
} from './PropertiesData'; *
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { getPropDetails, PROPERTY_TYPE, PropDetails } from './PropertiesData';
const INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/; const INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
// 是内置元素 // 是内置元素
export function isNativeElement(tagName: string, props: Record<string, any>) { export function isNativeElement(tagName: string, props: Record<string, any>) {
return !tagName.includes('-') && props.is === undefined; return !tagName.includes('-') && props.is === undefined;
} }
function isInvalidBoolean( function isInvalidBoolean(attributeName: string, value: any, propDetails: PropDetails): boolean {
attributeName: string,
value: any,
propDetails: PropDetails,
): boolean {
if (propDetails.type === PROPERTY_TYPE.SPECIAL) { if (propDetails.type === PROPERTY_TYPE.SPECIAL) {
return false; return false;
} }
@ -63,7 +71,7 @@ export function isInvalidValue(
name: string, name: string,
value: any, value: any,
propDetails: PropDetails | null, propDetails: PropDetails | null,
isNativeTag: boolean, isNativeTag: boolean
): boolean { ): boolean {
if (value == null) { if (value == null) {
return true; return true;
@ -107,11 +115,7 @@ export function validateProps(type, props) {
const propString = invalidProps.map(prop => '`' + prop + '`').join(', '); const propString = invalidProps.map(prop => '`' + prop + '`').join(', ');
if (invalidProps.length >= 1) { if (invalidProps.length >= 1) {
console.error( console.error('Invalid value for prop %s on <%s> tag.', propString, type);
'Invalid value for prop %s on <%s> tag.',
propString,
type,
);
} }
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { updateCommonProp } from '../DOMPropertiesHandler/UpdateCommonProp'; import { updateCommonProp } from '../DOMPropertiesHandler/UpdateCommonProp';
import { Props } from '../utils/Interface'; import { Props } from '../utils/Interface';
@ -13,7 +28,7 @@ function getInitValue(dom: HTMLInputElement, props: Props) {
export function getInputPropsWithoutValue(dom: HTMLInputElement, props: Props) { export function getInputPropsWithoutValue(dom: HTMLInputElement, props: Props) {
// checked属于必填属性无法置 // checked属于必填属性无法置
let {checked} = props; let { checked } = props;
if (checked == null) { if (checked == null) {
checked = getInitValue(dom, props).initChecked; checked = getInitValue(dom, props).initChecked;
} }
@ -28,9 +43,10 @@ export function getInputPropsWithoutValue(dom: HTMLInputElement, props: Props) {
} }
export function updateInputValue(dom: HTMLInputElement, props: Props) { export function updateInputValue(dom: HTMLInputElement, props: Props) {
const {value, checked} = props; const { value, checked } = props;
if (value != null) { // 处理 dom.value 逻辑 if (value != null) {
// 处理 dom.value 逻辑
if (dom.value !== String(value)) { if (dom.value !== String(value)) {
dom.value = String(value); dom.value = String(value);
} }
@ -41,8 +57,8 @@ export function updateInputValue(dom: HTMLInputElement, props: Props) {
// 设置input的初始值 // 设置input的初始值
export function setInitInputValue(dom: HTMLInputElement, props: Props) { export function setInitInputValue(dom: HTMLInputElement, props: Props) {
const {value, defaultValue} = props; const { value, defaultValue } = props;
const {initValue, initChecked} = getInitValue(dom, props); const { initValue, initChecked } = getInitValue(dom, props);
if (value != null || defaultValue != null) { if (value != null || defaultValue != null) {
// value 的使用优先级 value 属性 > defaultValue 属性 > 空字符串 // value 的使用优先级 value 属性 > defaultValue 属性 > 空字符串

View File

@ -1,10 +1,25 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { Children } from '../../external/ChildrenUtil'; import { Children } from '../../external/ChildrenUtil';
import { Props } from '../utils/Interface'; import { Props } from '../utils/Interface';
// 把 const a = 'a'; <option>gir{a}ffe</option> 转成 giraffe // 把 const a = 'a'; <option>gir{a}ffe</option> 转成 giraffe
function concatChildren(children) { function concatChildren(children) {
let content = ''; let content = '';
Children.forEach(children, function(child) { Children.forEach(children, function (child) {
content += child; content += child;
}); });

View File

@ -1,9 +1,24 @@
import {HorizonSelect, Props} from '../utils/Interface'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { HorizonSelect, Props } from '../utils/Interface';
function updateMultipleValue(options, newValues) { function updateMultipleValue(options, newValues) {
const newValueSet = new Set(); const newValueSet = new Set();
newValues.forEach((val) => { newValues.forEach(val => {
newValueSet.add(String(val)); newValueSet.add(String(val));
}); });
@ -46,8 +61,8 @@ export function getSelectPropsWithoutValue(dom: HorizonSelect, properties: Objec
}; };
} }
export function updateSelectValue(dom: HorizonSelect, props: Props, isInit: boolean = false) { export function updateSelectValue(dom: HorizonSelect, props: Props, isInit = false) {
const {value, defaultValue, multiple} = props; const { value, defaultValue, multiple } = props;
const oldMultiple = dom._multiple !== undefined ? dom._multiple : dom.multiple; const oldMultiple = dom._multiple !== undefined ? dom._multiple : dom.multiple;
const newMultiple = Boolean(multiple); const newMultiple = Boolean(multiple);
@ -56,7 +71,8 @@ export function updateSelectValue(dom: HorizonSelect, props: Props, isInit: bool
// 设置了 value 属性 // 设置了 value 属性
if (value != null) { if (value != null) {
updateValue(dom.options, value, newMultiple); updateValue(dom.options, value, newMultiple);
} else if (oldMultiple !== newMultiple) { // 修改了 multiple 属性 } else if (oldMultiple !== newMultiple) {
// 修改了 multiple 属性
// 切换 multiple 之后,如果设置了 defaultValue 需要重新应用 // 切换 multiple 之后,如果设置了 defaultValue 需要重新应用
if (defaultValue != null) { if (defaultValue != null) {
updateValue(dom.options, defaultValue, newMultiple); updateValue(dom.options, defaultValue, newMultiple);
@ -64,7 +80,8 @@ export function updateSelectValue(dom: HorizonSelect, props: Props, isInit: bool
// 恢复到未选定状态 // 恢复到未选定状态
updateValue(dom.options, newMultiple ? [] : '', newMultiple); updateValue(dom.options, newMultiple ? [] : '', newMultiple);
} }
} else if (isInit && defaultValue != null) { // 设置了 defaultValue 属性 } else if (isInit && defaultValue != null) {
// 设置了 defaultValue 属性
updateValue(dom.options, defaultValue, newMultiple); updateValue(dom.options, defaultValue, newMultiple);
} }
} }

View File

@ -1,12 +1,26 @@
import {Props} from '../utils/Interface'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { Props } from '../utils/Interface';
// 值的优先级 value > children > defaultValue // 值的优先级 value > children > defaultValue
function getInitValue(props: Props) { function getInitValue(props: Props) {
const {value} = props; const { value } = props;
if (value == null) { if (value == null) {
const {defaultValue, children} = props; const { defaultValue, children } = props;
let initValue = defaultValue; let initValue = defaultValue;
// children content存在时会覆盖defaultValue // children content存在时会覆盖defaultValue
@ -30,7 +44,7 @@ export function getTextareaPropsWithoutValue(dom: HTMLTextAreaElement, propertie
}; };
} }
export function updateTextareaValue(dom: HTMLTextAreaElement, props: Props, isInit: boolean = false) { export function updateTextareaValue(dom: HTMLTextAreaElement, props: Props, isInit = false) {
if (isInit) { if (isInit) {
const initValue = getInitValue(props); const initValue = getInitValue(props);
if (initValue !== '') { if (initValue !== '') {
@ -48,4 +62,3 @@ export function updateTextareaValue(dom: HTMLTextAreaElement, props: Props, isIn
} }
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/** /**
* Horizon的输入框和文本框的change事件在原生的change事件上做了一层处理 * Horizon的输入框和文本框的change事件在原生的change事件上做了一层处理
* change事件 * change事件
@ -37,7 +52,7 @@ export function watchValueChange(dom) {
const setFunc = descriptor?.set; const setFunc = descriptor?.set;
Object.defineProperty(dom, keyForValue, { Object.defineProperty(dom, keyForValue, {
...descriptor, ...descriptor,
set: function(value) { set: function (value) {
currentVal = String(value); currentVal = String(value);
setFunc?.apply(this, [value]); setFunc?.apply(this, [value]);
}, },

View File

@ -1,25 +1,28 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/** /**
* <input> <textarea> <select> <option> value * <input> <textarea> <select> <option> value
* *
*/ */
import {HorizonDom, HorizonSelect, Props} from '../utils/Interface'; import { HorizonDom, HorizonSelect, Props } from '../utils/Interface';
import { import { getInputPropsWithoutValue, setInitInputValue, updateInputValue } from './InputValueHandler';
getInputPropsWithoutValue, import { getOptionPropsWithoutValue } from './OptionValueHandler';
setInitInputValue, import { getSelectPropsWithoutValue, updateSelectValue } from './SelectValueHandler';
updateInputValue, import { getTextareaPropsWithoutValue, updateTextareaValue } from './TextareaValueHandler';
} from './InputValueHandler';
import {
getOptionPropsWithoutValue,
} from './OptionValueHandler';
import {
getSelectPropsWithoutValue,
updateSelectValue,
} from './SelectValueHandler';
import {
getTextareaPropsWithoutValue,
updateTextareaValue,
} from './TextareaValueHandler';
// 获取元素除了被代理的值以外的属性 // 获取元素除了被代理的值以外的属性
function getPropsWithoutValue(type: string, dom: HorizonDom, props: Props) { function getPropsWithoutValue(type: string, dom: HorizonDom, props: Props) {
@ -71,8 +74,4 @@ function updateValue(type: string, dom: HorizonDom, props: Props) {
} }
} }
export { export { getPropsWithoutValue, setInitValue, updateValue };
getPropsWithoutValue,
setInitValue,
updateValue,
};

View File

@ -1,10 +1,22 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/** /**
* *
*/ */
import { import { allDelegatedHorizonEvents, allDelegatedNativeEvents } from './EventHub';
allDelegatedHorizonEvents,
allDelegatedNativeEvents,
} from './EventHub';
import { isDocument } from '../dom/utils/Common'; import { isDocument } from '../dom/utils/Common';
import { getNearestVNode, getNonDelegatedListenerMap } from '../dom/DOMInternalKeys'; import { getNearestVNode, getNonDelegatedListenerMap } from '../dom/DOMInternalKeys';
import { asyncUpdates, runDiscreteUpdates } from '../renderer/TreeBuilder'; import { asyncUpdates, runDiscreteUpdates } from '../renderer/TreeBuilder';
@ -12,11 +24,7 @@ import { handleEventMain } from './HorizonEventMain';
import { decorateNativeEvent } from './EventWrapper'; import { decorateNativeEvent } from './EventWrapper';
import { VNode } from '../renderer/vnode/VNode'; import { VNode } from '../renderer/vnode/VNode';
const listeningMarker = const listeningMarker = '_horizonListening' + Math.random().toString(36).slice(4);
'_horizonListening' +
Math.random()
.toString(36)
.slice(4);
// 触发委托事件 // 触发委托事件
function triggerDelegatedEvent( function triggerDelegatedEvent(
@ -56,7 +64,7 @@ export function lazyDelegateOnRoot(currentRoot: VNode, eventName: string) {
const nativeEvents = allDelegatedHorizonEvents.get(eventName); const nativeEvents = allDelegatedHorizonEvents.get(eventName);
nativeEvents.forEach(nativeEvent => { nativeEvents.forEach(nativeEvent => {
const nativeFullName = isCapture ? nativeEvent + 'capture' : nativeEvent; const nativeFullName = isCapture ? nativeEvent + 'capture' : nativeEvent;
// 事件存储在DOM节点属性避免多个VNode(root和portal)对应同一个DOM, 造成事件重复监听 // 事件存储在DOM节点属性避免多个VNode(root和portal)对应同一个DOM, 造成事件重复监听
let events = currentRoot.realNode.$EV; let events = currentRoot.realNode.$EV;

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
// 需要委托的horizon事件和原生事件对应关系 // 需要委托的horizon事件和原生事件对应关系
export const allDelegatedHorizonEvents = new Map(); export const allDelegatedHorizonEvents = new Map();
// 所有委托的原生事件集合 // 所有委托的原生事件集合

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
// 兼容IE的event key // 兼容IE的event key
import { AnyNativeEvent } from './Types'; import { AnyNativeEvent } from './Types';
@ -25,7 +40,7 @@ export class WrappedEvent {
stopPropagation: () => void; stopPropagation: () => void;
preventDefault: () => void; preventDefault: () => void;
propagationStopped = false propagationStopped = false;
isPropagationStopped = (): boolean => this.propagationStopped; isPropagationStopped = (): boolean => this.propagationStopped;
// 适配Keyboard键盘事件该函数不能由合成事件调用 // 适配Keyboard键盘事件该函数不能由合成事件调用
@ -36,9 +51,9 @@ export class WrappedEvent {
constructor(customEventName: string, nativeEvtName: string, nativeEvent: AnyNativeEvent) { constructor(customEventName: string, nativeEvtName: string, nativeEvent: AnyNativeEvent) {
for (const name in nativeEvent) { for (const name in nativeEvent) {
this[name] = nativeEvent[name]; this[name] = nativeEvent[name];
if(name === 'getModifierState') { if (name === 'getModifierState') {
const keyBoardEvent = nativeEvent as KeyboardEvent; const keyBoardEvent = nativeEvent as KeyboardEvent;
this.getModifierState = (keyArg) => keyBoardEvent.getModifierState(keyArg); this.getModifierState = keyArg => keyBoardEvent.getModifierState(keyArg);
} }
} }
// stopPropagation和preventDefault 必须通过Event实例调用 // stopPropagation和preventDefault 必须通过Event实例调用

View File

@ -1,10 +1,21 @@
/* /*
* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/ */
import { getVNodeProps } from '../dom/DOMInternalKeys'; import { getVNodeProps } from '../dom/DOMInternalKeys';
import { getDomTag } from '../dom/utils/Common'; import { getDomTag } from '../dom/utils/Common';
import { Props } from '../dom/utils/Interface'; import { Props } from '../dom/utils/Interface';
import { updateTextareaValue } from '../dom/valueHandler/TextareaValueHandler'; import { updateTextareaValue } from '../dom/valueHandler/TextareaValueHandler';
import { updateInputHandlerIfChanged } from '../dom/valueHandler/ValueChangeHandler'; import { updateInputHandlerIfChanged } from '../dom/valueHandler/ValueChangeHandler';
import { updateInputValue } from '../dom/valueHandler/InputValueHandler'; import { updateInputValue } from '../dom/valueHandler/InputValueHandler';
@ -76,4 +87,3 @@ function controlInputValue(inputDom: HTMLInputElement, props: Props) {
updateInputValue(inputDom, props); updateInputValue(inputDom, props);
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { AnyNativeEvent, ListenerUnitList } from './Types'; import { AnyNativeEvent, ListenerUnitList } from './Types';
import type { VNode } from '../renderer/Types'; import type { VNode } from '../renderer/Types';
import { isInputElement, setPropertyWritable } from './utils'; import { isInputElement, setPropertyWritable } from './utils';
@ -63,11 +78,7 @@ function getChangeListeners(
if (shouldTriggerChangeEvent(targetDom, nativeEvtName)) { if (shouldTriggerChangeEvent(targetDom, nativeEvtName)) {
recordChangeEventTargets(target); recordChangeEventTargets(target);
const event = decorateNativeEvent( const event = decorateNativeEvent('onChange', 'change', nativeEvt);
'onChange',
'change',
nativeEvt,
);
return getListenersFromTree(vNode, 'onChange', event, EVENT_TYPE_ALL); return getListenersFromTree(vNode, 'onChange', event, EVENT_TYPE_ALL);
} }
@ -80,7 +91,7 @@ function getCommonListeners(
vNode: null | VNode, vNode: null | VNode,
nativeEvent: AnyNativeEvent, nativeEvent: AnyNativeEvent,
target: null | EventTarget, target: null | EventTarget,
isCapture: boolean, isCapture: boolean
): ListenerUnitList { ): ListenerUnitList {
const horizonEvtName = transformToHorizonEvent(nativeEvtName); const horizonEvtName = transformToHorizonEvent(nativeEvtName);
@ -102,12 +113,7 @@ function getCommonListeners(
} }
const horizonEvent = decorateNativeEvent(horizonEvtName, nativeEvtName, nativeEvent); const horizonEvent = decorateNativeEvent(horizonEvtName, nativeEvtName, nativeEvent);
return getListenersFromTree( return getListenersFromTree(vNode, horizonEvtName, horizonEvent, isCapture ? EVENT_TYPE_CAPTURE : EVENT_TYPE_BUBBLE);
vNode,
horizonEvtName,
horizonEvent,
isCapture ? EVENT_TYPE_CAPTURE : EVENT_TYPE_BUBBLE,
);
} }
// 按顺序执行事件队列 // 按顺序执行事件队列
@ -130,27 +136,16 @@ function triggerHorizonEvents(
nativeEvtName: string, nativeEvtName: string,
isCapture: boolean, isCapture: boolean,
nativeEvent: AnyNativeEvent, nativeEvent: AnyNativeEvent,
vNode: VNode | null, vNode: VNode | null
) { ) {
const target = nativeEvent.target || nativeEvent.srcElement!; const target = nativeEvent.target || nativeEvent.srcElement!;
// 触发普通委托事件 // 触发普通委托事件
let listenerList: ListenerUnitList = getCommonListeners( let listenerList: ListenerUnitList = getCommonListeners(nativeEvtName, vNode, nativeEvent, target, isCapture);
nativeEvtName,
vNode,
nativeEvent,
target,
isCapture,
);
// 触发特殊handler委托事件 // 触发特殊handler委托事件
if (!isCapture && horizonEventToNativeMap.get('onChange')!.includes(nativeEvtName)) { if (!isCapture && horizonEventToNativeMap.get('onChange')!.includes(nativeEvtName)) {
const changeListeners = getChangeListeners( const changeListeners = getChangeListeners(nativeEvtName, nativeEvent, vNode, target);
nativeEvtName,
nativeEvent,
vNode,
target
);
if (changeListeners.length) { if (changeListeners.length) {
listenerList = listenerList.concat(changeListeners); listenerList = listenerList.concat(changeListeners);
} }
@ -160,7 +155,6 @@ function triggerHorizonEvents(
processListeners(listenerList); processListeners(listenerList);
} }
// 其他事件正在执行中标记 // 其他事件正在执行中标记
let isInEventsExecution = false; let isInEventsExecution = false;
@ -170,7 +164,7 @@ export function handleEventMain(
isCapture: boolean, isCapture: boolean,
nativeEvent: AnyNativeEvent, nativeEvent: AnyNativeEvent,
vNode: null | VNode, vNode: null | VNode,
targetDom: EventTarget, targetDom: EventTarget
): void { ): void {
let startVNode = vNode; let startVNode = vNode;
if (startVNode !== null) { if (startVNode !== null) {

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { VNode } from '../renderer/Types'; import { VNode } from '../renderer/Types';
import { DomComponent } from '../renderer/vnode/VNodeTags'; import { DomComponent } from '../renderer/vnode/VNodeTags';
import { WrappedEvent } from './EventWrapper'; import { WrappedEvent } from './EventWrapper';

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode } from '../renderer/Types'; import type { VNode } from '../renderer/Types';
import { WrappedEvent } from './EventWrapper'; import { WrappedEvent } from './EventWrapper';

View File

@ -1,12 +1,25 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export function isInputElement(dom?: HTMLElement): boolean { export function isInputElement(dom?: HTMLElement): boolean {
return dom instanceof HTMLInputElement || dom instanceof HTMLTextAreaElement; return dom instanceof HTMLInputElement || dom instanceof HTMLTextAreaElement;
} }
export function setPropertyWritable(obj, propName) { export function setPropertyWritable(obj, propName) {
const desc = Object.getOwnPropertyDescriptor(obj, propName); const desc = Object.getOwnPropertyDescriptor(obj, propName);
if (!desc || !desc.writable) { if (!desc || !desc.writable) {
Object.defineProperty(obj, propName, { writable : true }); Object.defineProperty(obj, propName, { writable: true });
} }
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { throwIfTrue } from '../renderer/utils/throwIfTrue'; import { throwIfTrue } from '../renderer/utils/throwIfTrue';
import { TYPE_COMMON_ELEMENT, TYPE_PORTAL } from './JSXElementType'; import { TYPE_COMMON_ELEMENT, TYPE_PORTAL } from './JSXElementType';

112
libs/horizon/src/external/HorizonIs.ts vendored Normal file
View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import {
TYPE_COMMON_ELEMENT,
TYPE_CONTEXT,
TYPE_FORWARD_REF,
TYPE_FRAGMENT,
TYPE_LAZY,
TYPE_MEMO,
TYPE_PORTAL,
TYPE_PROVIDER,
TYPE_SUSPENSE,
} from './JSXElementType';
function isObject(anyThing) {
return Object.prototype.toString.call(anyThing) === '[object Object]';
}
function isBuiltinTag(type: any) {
return [TYPE_FRAGMENT, TYPE_SUSPENSE].includes(type);
}
function isBuiltinComponent(type: any) {
return [TYPE_MEMO, TYPE_PROVIDER, TYPE_LAZY, TYPE_FORWARD_REF, TYPE_CONTEXT].includes(type);
}
/**
* element的类型
* 1. fragment, suspense type
* 2. memo, lazy, forwardRef type.vtype
* 3. Context.Provider/Consumer type.vtype
* 4. portal比较特殊elementvtype
* @param ele
*/
function getType(ele: any) {
if (isObject(ele)) {
const type = ele.type;
if (isBuiltinTag(type)) {
return type;
}
const vtypeOfType = type?.vtype;
if (isBuiltinComponent(vtypeOfType)) {
return vtypeOfType;
}
const vtype = ele.vtype;
if (TYPE_PORTAL === vtype) {
return vtype;
}
}
return undefined;
}
export function isElement(ele: any) {
return isObject(ele) && ele.vtype === TYPE_COMMON_ELEMENT;
}
export function isFragment(ele: any) {
return getType(ele) === TYPE_FRAGMENT;
}
export function isForwardRef(ele: any) {
return getType(ele) === TYPE_FORWARD_REF;
}
export function isLazy(ele: any) {
return getType(ele) === TYPE_LAZY;
}
export function isMemo(ele: any) {
return getType(ele) === TYPE_MEMO;
}
export function isPortal(ele: any) {
return getType(ele) === TYPE_PORTAL;
}
export function isContextProvider(ele: any) {
return getType(ele) === TYPE_PROVIDER;
}
// Context.consumer的类型就是context的类型
export function isContextConsumer(ele: any) {
return getType(ele) === TYPE_CONTEXT;
}
export function isValidElementType(type: any) {
if (typeof type === 'string' || typeof type === 'function' || isBuiltinTag(type)) {
return true;
}
if (isObject(type)) {
if (isBuiltinComponent(type.vtype)) {
return true;
}
}
return false;
}

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { TYPE_COMMON_ELEMENT } from './JSXElementType'; import { TYPE_COMMON_ELEMENT } from './JSXElementType';
import { getProcessingClassVNode } from '../renderer/GlobalVar'; import { getProcessingClassVNode } from '../renderer/GlobalVar';
import { Source } from '../renderer/Types'; import { Source } from '../renderer/Types';
@ -41,8 +56,8 @@ function mergeDefault(sourceObj, defaultObj) {
function buildElement(isClone, type, setting, children) { function buildElement(isClone, type, setting, children) {
// setting中的值优先级最高clone情况下从 type 中取值,创建情况下直接赋值为 null // setting中的值优先级最高clone情况下从 type 中取值,创建情况下直接赋值为 null
const key = (setting && setting.key !== undefined) ? String(setting.key) : (isClone ? type.key : null); 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 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.belongClassVNode : getProcessingClassVNode(); let vNode = isClone ? type.belongClassVNode : getProcessingClassVNode();

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export const TYPE_COMMON_ELEMENT = 1; export const TYPE_COMMON_ELEMENT = 1;
export const TYPE_PORTAL = 2; export const TYPE_PORTAL = 2;
export const TYPE_FRAGMENT = 3; export const TYPE_FRAGMENT = 3;

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { travelVNodeTree } from '../renderer/vnode/VNodeUtils'; import { travelVNodeTree } from '../renderer/vnode/VNodeUtils';
import { Hook, Reducer, Ref, Effect, CallBack, Memo } from '../renderer/hooks/HookType'; import { Hook, Reducer, Ref, Effect, CallBack, Memo } from '../renderer/hooks/HookType';
import { VNode } from '../renderer/vnode/VNode'; import { VNode } from '../renderer/vnode/VNode';

View File

@ -1,52 +0,0 @@
export function isObject(obj) {
const type = typeof obj;
return obj != null && (type === 'object' || type === 'function');
}
export function isSet(obj) {
return obj != null && (Object.prototype.toString.call(obj) === '[object Set]' || obj.constructor === Set);
}
export function isWeakSet(obj) {
return obj != null && (Object.prototype.toString.call(obj) === '[object WeakSet]' || obj.constructor === WeakSet);
}
export function isMap(obj) {
return obj != null && (Object.prototype.toString.call(obj) === '[object Map]' || obj.constructor === Map);
}
export function isWeakMap(obj) {
return obj != null && (Object.prototype.toString.call(obj) === '[object WeakMap]' || obj.constructor === WeakMap);
}
export function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
export function isCollection(obj) {
return isSet(obj) || isWeakSet(obj) || isMap(obj) || isWeakMap(obj);
}
export function isString(obj) {
return typeof obj === 'string';
}
export function isValidIntegerKey(key) {
return isString(key) && key !== 'NaN' && key[0] !== '-' && String(parseInt(key, 10)) === key;
}
export const noop = () => {};
export function isSame(x, y) {
if (!(typeof Object.is === 'function')) {
if (x === y) {
// +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// NaN == NaN
return x !== x && y !== y;
}
} else {
return Object.is(x, y);
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export function isObject(obj: any): boolean {
const type = typeof obj;
return (obj !== null || obj !== undefined) && (type === 'object' || type === 'function');
}
export function isSet(obj: any): boolean {
return (obj !== null || obj !== undefined) && (Object.prototype.toString.call(obj) === '[object Set]' || obj.constructor === Set);
}
export function isWeakSet(obj: any): boolean {
return (obj !== null || obj !== undefined) && (Object.prototype.toString.call(obj) === '[object WeakSet]' || obj.constructor === WeakSet);
}
export function isMap(obj: any): boolean {
return (obj !== null || obj !== undefined) && (Object.prototype.toString.call(obj) === '[object Map]' || obj.constructor === Map);
}
export function isWeakMap(obj: any): boolean {
return (obj !== null || obj !== undefined) && (Object.prototype.toString.call(obj) === '[object WeakMap]' || obj.constructor === WeakMap);
}
export function isArray(obj: any): boolean {
return Object.prototype.toString.call(obj) === '[object Array]';
}
export function isCollection(obj: any): boolean {
return isSet(obj) || isWeakSet(obj) || isMap(obj) || isWeakMap(obj);
}
export function isString(obj: any): boolean {
return typeof obj === 'string';
}
// key是有效的正整数字的字符串
export function isValidIntegerKey(key: any): boolean {
return isString(key) && key !== 'NaN' && key[0] !== '-' && String(parseInt(key, 10)) === key;
}
export function isPromise(obj: any): boolean {
return isObject(obj) && typeof obj.then === 'function';
}
export function isSame(x, y) {
if (!(typeof Object.is === 'function')) {
if (x === y) {
// +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// NaN == NaN
return x !== x && y !== y;
}
} else {
return Object.is(x, y);
}
}

View File

@ -1,5 +1,16 @@
// The two constants must be the same as those in horizon. /*
export const FunctionComponent = 'FunctionComponent'; * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
export const ClassComponent = 'ClassComponent'; *
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export const OBSERVER_KEY = Symbol('_horizonObserver'); export const OBSERVER_KEY = '_horizonObserver';

View File

@ -1,6 +1,19 @@
import { createStore as createStoreX } from '../store/StoreHandler'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { ReduxStoreHandler } from '../store/StoreHandler'; import { createStore as createStoreX } from '../store/StoreHandler';
export { thunk } from './reduxThunk'; export { thunk } from './reduxThunk';
@ -14,6 +27,14 @@ export {
createDispatchHook, createDispatchHook,
} from './reduxReact'; } from './reduxReact';
export type ReduxStoreHandler = {
reducer: (state: any, action: { type: string }) => any;
dispatch: (action: { type: string }) => void;
getState: () => any;
subscribe: (listener: () => void) => () => void;
replaceReducer: (reducer: (state: any, action: { type: string }) => any) => void;
};
export type ReduxAction = { export type ReduxAction = {
type: string; type: string;
[key: string]: any; [key: string]: any;
@ -90,7 +111,7 @@ export function createStore(reducer: Reducer, preloadedState?: any, enhancers?):
}, },
}, },
options: { options: {
reduxAdapter: true, isReduxAdapter: true,
}, },
})(); })();

View File

@ -1,11 +1,22 @@
// @ts-ignore /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { useState, useContext, useEffect, useRef } from '../../renderer/hooks/HookExternal'; import { useState, useContext, useEffect, useRef } from '../../renderer/hooks/HookExternal';
import { createContext } from '../../renderer/components/context/CreateContext'; import { createContext } from '../../renderer/components/context/CreateContext';
import { createElement } from '../../external/JSXElement'; import { createElement } from '../../external/JSXElement';
import { BoundActionCreator } from './redux'; import type { ReduxStoreHandler, ReduxAction, BoundActionCreator } from './redux';
import { ReduxAction } from './redux';
import { ReduxStoreHandler } from '../store/StoreHandler';
import { VNode } from '../../renderer/Types';
const DefaultContext = createContext(null); const DefaultContext = createContext(null);
type Context = typeof DefaultContext; type Context = typeof DefaultContext;
@ -66,47 +77,12 @@ export const useStore = () => {
return createStoreHook(DefaultContext)(); return createStoreHook(DefaultContext)();
}; };
// function shallowCompare(a,b){ export function connect(
// return Object.keys(a).length === Object.keys(b).length && mapStateToProps?: (state: any, ownProps: { [key: string]: any }) => object,
// Object.keys(a).every(key => a[key] === b[key]); mapDispatchToProps?:
// } | { [key: string]: (...args: any[]) => ReduxAction }
| ((dispatch: (action: ReduxAction) => any, ownProps?: object) => object),
//TODO: implement options mergeProps?: (stateProps: object, dispatchProps: object, ownProps: object) => object,
// context?: Object,
// areStatesEqual?: Function, :)
// areOwnPropsEqual?: Function,
// areStatePropsEqual?: Function,
// areMergedPropsEqual?: Function,
// forwardRef?: boolean,
// const defaultOptions = {
// areStatesEqual: shallowCompare,
// areOwnPropsEqual: shallowCompare,
// areStatePropsEqual: shallowCompare,
// areMergedPropsEqual: shallowCompare
// };
type MapStateToPropsP<StateProps, OwnProps> = (state: any, ownProps: OwnProps) => StateProps;
type MapDispatchToPropsP<DispatchProps, OwnProps> =
| { [key: string]: (...args: any[]) => ReduxAction }
| ((dispatch: (action: ReduxAction) => any, ownProps: OwnProps) => DispatchProps);
type MergePropsP<StateProps, DispatchProps, OwnProps, MergedProps> = (
stateProps: StateProps,
dispatchProps: DispatchProps,
ownProps: OwnProps
) => MergedProps;
type WrappedComponent<OwnProps> = (props: OwnProps) => ReturnType<typeof createElement>;
type OriginalComponent<MergedProps> = (props: MergedProps) => ReturnType<typeof createElement>;
type Connector<OwnProps, MergedProps> = (Component: OriginalComponent<MergedProps>) => WrappedComponent<OwnProps>;
export function connect<StateProps, DispatchProps, OwnProps, MergedProps>(
mapStateToProps: MapStateToPropsP<StateProps, OwnProps> = () => ({} as StateProps),
mapDispatchToProps: MapDispatchToPropsP<DispatchProps, OwnProps> = () => ({} as DispatchProps),
mergeProps: MergePropsP<StateProps, DispatchProps, OwnProps, MergedProps> = (
stateProps,
dispatchProps,
ownProps
): MergedProps => ({ ...stateProps, ...dispatchProps, ...ownProps } as MergedProps),
options?: { options?: {
areStatesEqual?: (oldState: any, newState: any) => boolean; areStatesEqual?: (oldState: any, newState: any) => boolean;
context?: Context; context?: Context;
@ -124,7 +100,7 @@ export function connect<StateProps, DispatchProps, OwnProps, MergedProps>(
const Wrapper: WrappedComponent<OwnProps> = (props: OwnProps) => { const Wrapper: WrappedComponent<OwnProps> = (props: OwnProps) => {
const [f, forceReload] = useState(true); const [f, forceReload] = useState(true);
const store = useStore(); const store = useStore() as unknown as ReduxStoreHandler;
useEffect(() => { useEffect(() => {
const unsubscribe = store.subscribe(() => forceReload(!f)); const unsubscribe = store.subscribe(() => forceReload(!f));

View File

@ -1,21 +1,37 @@
import { ReduxAction, ReduxMiddleware } from './redux'; /*
import { ReduxStoreHandler } from '../store/StoreHandler'; * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { ReduxStoreHandler, ReduxAction, ReduxMiddleware } from './redux';
function createThunkMiddleware(extraArgument?: any): ReduxMiddleware { function createThunkMiddleware(extraArgument?: any): ReduxMiddleware {
return (store: ReduxStoreHandler) => (next: (action: ReduxAction) => any) => ( return (store: ReduxStoreHandler) =>
action: (next: (action: ReduxAction) => any) =>
| ReduxAction (
| ((dispatch: (action: ReduxAction) => void, store: ReduxStoreHandler, extraArgument?: any) => any) action:
) => { | ReduxAction
// This gets called for every action you dispatch. | ((dispatch: (action: ReduxAction) => void, store: ReduxStoreHandler, extraArgument?: any) => any)
// If it's a function, call it. ) => {
if (typeof action === 'function') { // This gets called for every action you dispatch.
return action(store.dispatch, store.getState.bind(store), extraArgument); // If it's a function, call it.
} if (typeof action === 'function') {
return action(store.dispatch, store.getState.bind(store), extraArgument);
}
// Otherwise, just continue processing this action as usual // Otherwise, just continue processing this action as usual
return next(action); return next(action);
}; };
} }
export const thunk = createThunkMiddleware(); export const thunk = createThunkMiddleware();

View File

@ -1,17 +1,27 @@
// TODO: implement vNode type /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import {IObserver} from './Observer'; import type { IObserver } from './Observer';
/** /**
* Observer * Observer
*
*/ */
export class HooklessObserver implements IObserver { export class HooklessObserver implements IObserver {
listeners: (() => void)[] = [];
listeners:(() => void)[] = []; useProp(key: string | symbol): void {}
useProp(key: string | symbol): void {
}
addListener(listener: () => void) { addListener(listener: () => void) {
this.listeners.push(listener); this.listeners.push(listener);
@ -34,12 +44,9 @@ export class HooklessObserver implements IObserver {
}); });
} }
triggerUpdate(vNode): void { triggerUpdate(vNode): void {}
}
allChange(): void { allChange(): void {}
}
clearByVNode(vNode): void { clearByVNode(vNode): void {}
}
} }

View File

@ -1,11 +1,22 @@
/** /*
* Observer * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/ */
//@ts-ignore
import { launchUpdateFromVNode } from '../../renderer/TreeBuilder'; import { launchUpdateFromVNode } from '../../renderer/TreeBuilder';
import { getProcessingVNode } from '../../renderer/GlobalVar'; import { getProcessingVNode } from '../../renderer/GlobalVar';
import { VNode } from '../../renderer/vnode/VNode'; import { VNode } from '../../renderer/vnode/VNode';
export interface IObserver { export interface IObserver {
useProp: (key: string) => void; useProp: (key: string) => void;
@ -24,6 +35,9 @@ export interface IObserver {
clearByVNode: (vNode: any) => void; clearByVNode: (vNode: any) => void;
} }
/**
* Observer
*/
export class Observer implements IObserver { export class Observer implements IObserver {
vNodeKeys = new WeakMap(); vNodeKeys = new WeakMap();
@ -33,18 +47,18 @@ export class Observer implements IObserver {
watchers = {} as { [key: string]: ((key: string, oldValue: any, newValue: any) => void)[] }; watchers = {} as { [key: string]: ((key: string, oldValue: any, newValue: any) => void)[] };
watchers={} as {[key:string]:((key:string, oldValue:any, newValue:any)=>void)[]} // 对象的属性被使用时调用
useProp(key: string | symbol): void { useProp(key: string | symbol): void {
const processingVNode = getProcessingVNode(); const processingVNode = getProcessingVNode();
if (processingVNode === null || !processingVNode.observers) { if (processingVNode === null || !processingVNode.observers) {
// 异常场景
return; return;
} }
// vNode -> Observers // vNode -> Observers
processingVNode.observers.add(this); processingVNode.observers.add(this);
// key -> vNodes // key -> vNodes记录这个prop被哪些VNode使用了
let vNodes = this.keyVNodes.get(key); let vNodes = this.keyVNodes.get(key);
if (!vNodes) { if (!vNodes) {
vNodes = new Set(); vNodes = new Set();
@ -52,7 +66,7 @@ export class Observer implements IObserver {
} }
vNodes.add(processingVNode); vNodes.add(processingVNode);
// vNode -> keys // vNode -> keys记录这个VNode使用了哪些props
let keys = this.vNodeKeys.get(processingVNode); let keys = this.vNodeKeys.get(processingVNode);
if (!keys) { if (!keys) {
keys = new Set(); keys = new Set();
@ -61,6 +75,32 @@ export class Observer implements IObserver {
keys.add(key); keys.add(key);
} }
// 对象的属性被赋值时调用
setProp(key: string | symbol): void {
const vNodes = this.keyVNodes.get(key);
vNodes?.forEach((vNode: VNode) => {
if (vNode.isStoreChange) {
// VNode已经被触发过不再重复触发
return;
}
vNode.isStoreChange = true;
// 触发vNode更新
this.triggerUpdate(vNode);
});
this.triggerChangeListeners();
}
triggerUpdate(vNode: VNode): void {
if (!vNode) {
return;
}
// 触发VNode更新
launchUpdateFromVNode(vNode);
}
addListener(listener: () => void): void { addListener(listener: () => void): void {
this.listeners.push(listener); this.listeners.push(listener);
} }
@ -69,34 +109,13 @@ export class Observer implements IObserver {
this.listeners = this.listeners.filter(item => item != listener); this.listeners = this.listeners.filter(item => item != listener);
} }
setProp(key: string | symbol): void {
const vNodes = this.keyVNodes.get(key);
vNodes?.forEach((vNode: VNode) => {
if (vNode.isStoreChange) {
// update already triggered
return;
}
vNode.isStoreChange = true;
// 触发vNode更新
this.triggerUpdate(vNode);
});
this.triggerChangeListeners();
}
triggerChangeListeners(): void { triggerChangeListeners(): void {
this.listeners.forEach(listener => listener()); this.listeners.forEach(listener => listener());
} }
triggerUpdate(vNode: VNode): void { // 触发所有使用的props的VNode更新
if (!vNode) {
return;
}
launchUpdateFromVNode(vNode);
}
allChange(): void { allChange(): void {
let keyIt = this.keyVNodes.keys(); const keyIt = this.keyVNodes.keys();
let keyItem = keyIt.next(); let keyItem = keyIt.next();
while (!keyItem.done) { while (!keyItem.done) {
this.setProp(keyItem.value); this.setProp(keyItem.value);
@ -104,6 +123,7 @@ export class Observer implements IObserver {
} }
} }
// 删除Observer中保存的这个VNode的关系数据
clearByVNode(vNode: VNode): void { clearByVNode(vNode: VNode): void {
const keys = this.vNodeKeys.get(vNode); const keys = this.vNodeKeys.get(vNode);
if (keys) { if (keys) {

View File

@ -1,22 +1,39 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { createObjectProxy } from './handlers/ObjectProxyHandler'; import { createObjectProxy } from './handlers/ObjectProxyHandler';
import { Observer } from './Observer'; import { Observer } from './Observer';
import { HooklessObserver } from './HooklessObserver'; import { HooklessObserver } from './HooklessObserver';
import { isArray, isCollection, isObject } from '../CommonUtils'; import { isArray, isCollection, isObject } from '../CommonUtils';
import { createArrayProxy } from './handlers/ArrayProxyHandler'; import { createArrayProxy } from './handlers/ArrayProxyHandler';
import { createCollectionProxy } from './handlers/CollectionProxyHandler'; import { createCollectionProxy } from './handlers/CollectionProxyHandler';
import { IObserver } from '../types'; import type { IObserver } from '../types';
import { OBSERVER_KEY } from '../Constants'; import { OBSERVER_KEY } from '../Constants';
// 保存rawObj -> Proxy
const proxyMap = new WeakMap(); const proxyMap = new WeakMap();
export const hookObserverMap = new WeakMap(); export const hookObserverMap = new WeakMap();
export function createProxy(rawObj: any, hookObserver = true): any { export function createProxy(rawObj: any, isHookObserver = true): any {
// 不是对象(是原始数据类型)不用代理 // 不是对象(是原始数据类型)不用代理
if (!isObject(rawObj)) { if (!isObject(rawObj)) {
return rawObj; return rawObj;
} }
// 已代理过
const existProxy = proxyMap.get(rawObj); const existProxy = proxyMap.get(rawObj);
if (existProxy) { if (existProxy) {
return existProxy; return existProxy;
@ -30,16 +47,16 @@ export function createProxy(rawObj: any, hookObserver = true): any {
// 创建Observer // 创建Observer
let observer: IObserver = getObserver(rawObj); let observer: IObserver = getObserver(rawObj);
if (!observer) { if (!observer) {
observer = hookObserver ? new Observer() : new HooklessObserver(); observer = isHookObserver ? new Observer() : new HooklessObserver();
rawObj[OBSERVER_KEY] = observer; rawObj[OBSERVER_KEY] = observer;
} }
hookObserverMap.set(rawObj, hookObserver); hookObserverMap.set(rawObj, isHookObserver);
// 创建Proxy // 创建Proxy
let proxyObj; let proxyObj;
if (!hookObserver) { if (!isHookObserver) {
proxyObj = createObjectProxy(rawObj,true); proxyObj = createObjectProxy(rawObj, true);
} else if (isArray(rawObj)) { } else if (isArray(rawObj)) {
// 数组 // 数组
proxyObj = createArrayProxy(rawObj as []); proxyObj = createArrayProxy(rawObj as []);

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { getObserver } from '../ProxyHandler'; import { getObserver } from '../ProxyHandler';
import { isSame, isValidIntegerKey } from '../../CommonUtils'; import { isSame, isValidIntegerKey } from '../../CommonUtils';
import { get as objectGet } from './ObjectProxyHandler'; import { get as objectGet } from './ObjectProxyHandler';
@ -29,6 +44,7 @@ function get(rawObj: any[], key: string, receiver: any) {
if (isValidIntegerKey(key) || key === 'length') { if (isValidIntegerKey(key) || key === 'length') {
return objectGet(rawObj, key, receiver); return objectGet(rawObj, key, receiver);
} }
return Reflect.get(rawObj, key, receiver); return Reflect.get(rawObj, key, receiver);
} }
@ -43,16 +59,19 @@ function set(rawObj: any[], key: string, value: any, receiver: any) {
const observer = getObserver(rawObj); const observer = getObserver(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); cb(key, oldValue, newValue);
}); });
} }
// 触发属性变化
observer.setProp(key); observer.setProp(key);
} }
if (oldLength !== newLength) { if (oldLength !== newLength) {
// 触发数组的大小变化
observer.setProp('length'); observer.setProp('length');
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { createProxy, getObserver, hookObserverMap } from '../ProxyHandler'; import { createProxy, getObserver, hookObserverMap } from '../ProxyHandler';
import { isMap, isWeakMap, isSame } from '../../CommonUtils'; import { isMap, isWeakMap, isSame } from '../../CommonUtils';
@ -13,7 +28,8 @@ const handler = {
forEach, forEach,
keys, keys,
values, values,
[Symbol.iterator]: forOf, // 判断Symbol类型兼容IE
[typeof Symbol === 'function' ? Symbol.iterator : '@@iterator']: forOf,
}; };
export function createCollectionProxy(rawObj: Object, hookObserver = true): Object { export function createCollectionProxy(rawObj: Object, hookObserver = true): Object {
@ -199,7 +215,8 @@ function wrapIterator(rawObj: Object, rawIt: { next: () => { value: any; done: b
return { value: newVal, done }; return { value: newVal, done };
}, },
[Symbol.iterator]() { // 判断Symbol类型兼容IE
[typeof Symbol === 'function' ? Symbol.iterator : '@@iterator']() {
return this; return this;
}, },
}; };

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { isSame } from '../../CommonUtils'; import { isSame } from '../../CommonUtils';
import { createProxy, getObserver, hookObserverMap } from '../ProxyHandler'; import { createProxy, getObserver, hookObserverMap } from '../ProxyHandler';
import { OBSERVER_KEY } from '../../Constants'; import { OBSERVER_KEY } from '../../Constants';
@ -19,16 +34,16 @@ export function get(rawObj: object, key: string | symbol, receiver: any, singleL
const observer = getObserver(rawObj); const observer = getObserver(rawObj);
if (key === 'watch'){ if (key === 'watch') {
return (prop, handler:(key:string, oldValue:any, newValue:any)=>void)=>{ return (prop, handler: (key: string, oldValue: any, newValue: any) => void) => {
if(!observer.watchers[prop]){ if (!observer.watchers[prop]) {
observer.watchers[prop]=[] as ((key:string, oldValue:any, newValue:any)=>void)[]; observer.watchers[prop] = [] as ((key: string, oldValue: any, newValue: any) => void)[];
} }
observer.watchers[prop].push(handler); observer.watchers[prop].push(handler);
return ()=>{ return () => {
observer.watchers[prop]=observer.watchers[prop].filter(cb=>cb!==handler); observer.watchers[prop] = observer.watchers[prop].filter(cb => cb !== handler);
} };
} };
} }
if (key === 'addListener') { if (key === 'addListener') {
@ -66,7 +81,7 @@ export function set(rawObj: object, key: string, value: any, receiver: any): boo
const ret = Reflect.set(rawObj, key, newValue, receiver); const ret = Reflect.set(rawObj, key, newValue, receiver);
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); cb(key, oldValue, newValue);
}); });

View File

@ -1,14 +1,30 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { isObject } from '../CommonUtils'; import { isObject } from '../CommonUtils';
export function readonlyProxy<T extends object>(target: T): ProxyHandler<T> { export function readonlyProxy<T extends object>(rawObj: T): ProxyHandler<T> {
return new Proxy(target, { return new Proxy(rawObj, {
get(target, property, receiver) { get(rawObj, property, receiver) {
const result = Reflect.get(target, property, receiver); const result = Reflect.get(rawObj, property, receiver);
try { try {
if (isObject(result)) { if (isObject(result)) {
return readonlyProxy(result); return readonlyProxy(result);
} }
} catch(err) { } catch (err) {
// 不处理 // 不处理
} }
return result; return result;

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export function watch(stateVariable: any, listener: (state: any) => void) { export function watch(stateVariable: any, listener: (state: any) => void) {
listener = listener.bind(null, stateVariable); listener = listener.bind(null, stateVariable);
stateVariable.addListener(listener); stateVariable.addListener(listener);

View File

@ -1,11 +1,37 @@
//@ts-ignore /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { useEffect, useRef } from '../../renderer/hooks/HookExternal'; import { useEffect, useRef } from '../../renderer/hooks/HookExternal';
import { getProcessingVNode } from '../../renderer/GlobalVar'; import { getProcessingVNode } from '../../renderer/GlobalVar';
import { createProxy } from '../proxy/ProxyHandler'; import { createProxy } from '../proxy/ProxyHandler';
import readonlyProxy from '../proxy/readonlyProxy'; import readonlyProxy from '../proxy/readonlyProxy';
import { Observer } from '../proxy/Observer'; import { Observer } from '../proxy/Observer';
import { FunctionComponent, ClassComponent } from '../Constants'; import { FunctionComponent, ClassComponent } from '../../renderer/vnode/VNodeTags';
import { VNode } from '../../renderer/Types'; import { isPromise } from '../CommonUtils';
import type {
ActionFunction,
ComputedValues,
PlannedAction,
QueuedStoreActions,
StoreActions,
StoreConfig,
StoreObj,
UserActions,
UserComputedValues,
} from '../types';
import { VNode } from '../../renderer/vnode/VNode';
import { devtools } from '../devtools'; import { devtools } from '../devtools';
import { import {
ACTION, ACTION,
@ -24,144 +50,49 @@ const idGenerator = {
}, },
}; };
const storeMap = new Map<string, StoreHandler<any, any, any>>(); const storeMap = new Map<string, StoreObj<any, any, any>>();
function isPromise(obj: any): boolean {
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
}
type StoreConfig<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>> = {
state?: S;
actions?: A;
id?: string;
computed?: C;
};
export type ReduxStoreHandler = {
reducer: (state: any, action: { type: string }) => any;
dispatch: (action: { type: string }) => void;
getState: () => any;
subscribe: (listener: () => void) => () => void;
replaceReducer: (reducer: (state: any, action: { type: string }) => any) => void;
};
type StoreHandler<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>> = {
$subscribe: (listener: () => void) => void;
$unsubscribe: (listener: () => void) => void;
$s: S;
$queue: QueuedStoreActions<S, A>;
$a: StoreActions<S, A>;
$c: UserComputedValues<S>;
} & { [K in keyof S]: S[K] } & { [K in keyof A]: Action<A[K], S> } & { [K in keyof C]: ReturnType<C[K]> };
type PlannedAction<S extends object, F extends ActionFunction<S>> = {
action: string;
payload: any[];
resolve: ReturnType<F>;
};
type RemoveFirstFromTuple<T extends any[]> = T['length'] extends 0
? []
: ((...b: T) => void) extends (a, ...b: infer I) => void
? I
: [];
type UserActions<S extends object> = { [K: string]: ActionFunction<S> };
type UserComputedValues<S extends object> = { [K: string]: ComputedFunction<S> };
type ActionFunction<S extends object> = (this: StoreHandler<S, any, any>, state: S, ...args: any[]) => any;
type ComputedFunction<S extends object> = (state: S) => any;
type Action<T extends ActionFunction<any>, S extends object> = (
this: StoreHandler<S, any, any>,
...args: RemoveFirstFromTuple<Parameters<T>>
) => ReturnType<T>;
type AsyncAction<T extends ActionFunction<any>, S extends object> = (
this: StoreHandler<S, any, any>,
...args: RemoveFirstFromTuple<Parameters<T>>
) => Promise<ReturnType<T>>;
type StoreActions<S extends object, A extends UserActions<S>> = { [K in keyof A]: Action<A[K], S> };
type QueuedStoreActions<S extends object, A extends UserActions<S>> = { [K in keyof A]: AsyncAction<A[K], S> };
type ComputedValues<S extends object, C extends UserComputedValues<S>> = { [K in keyof C]: ReturnType<C[K]> };
type PostponedAction = (state: object, ...args: any[]) => Promise<any>;
type PostponedActions = { [key: string]: PostponedAction };
export function createStore<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>>( export function createStore<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>>(
config: StoreConfig<S, A, C> config: StoreConfig<S, A, C>
): () => StoreHandler<S, A, C> { ): () => StoreObj<S, A, C> {
//create a local shalow copy to ensure consistency (if user would change the config object after store creation)
config = {
id: config.id || idGenerator.get('UNKNOWN_STORE_'),
/* @ts-ignore*/
options: config.options,
state: config.state,
actions: config.actions ? { ...config.actions } : undefined,
computed: config.computed ? { ...config.computed } : undefined,
};
// 校验 // 校验
if (Object.prototype.toString.call(config) !== '[object Object]') { if (Object.prototype.toString.call(config) !== '[object Object]') {
throw new Error('store obj must be pure object'); throw new Error('store obj must be pure object');
} }
/* @ts-ignore*/ const proxyObj = createProxy(config.state, !config.options?.isReduxAdapter);
const proxyObj = createProxy(config.state, !config.options?.reduxAdapter);
proxyObj.$pending = false; proxyObj.$pending = false;
const $subscribe = listener => {
devtools.emit(SUBSCRIBED, { store: handler, listener });
proxyObj.addListener(listener);
};
const $unsubscribe = listener => {
devtools.emit(UNSUBSCRIBED, handler);
proxyObj.removeListener(listener);
};
const plannedActions: PlannedAction<S, ActionFunction<S>>[] = [];
const $a: Partial<StoreActions<S, A>> = {}; const $a: Partial<StoreActions<S, A>> = {};
const $queue: Partial<StoreActions<S, A>> = {}; const $queue: Partial<StoreActions<S, A>> = {};
const $c: Partial<ComputedValues<S, C>> = {}; const $c: Partial<ComputedValues<S, C>> = {};
const handler = { const storeObj = {
$subscribe,
$unsubscribe,
$a: $a as StoreActions<S, A>,
$s: proxyObj, $s: proxyObj,
$a: $a as StoreActions<S, A>,
$c: $c as ComputedValues<S, C>, $c: $c as ComputedValues<S, C>,
$config: config,
$queue: $queue as QueuedStoreActions<S, A>, $queue: $queue as QueuedStoreActions<S, A>,
} as unknown as StoreHandler<S, A, C>; $config: config,
$subscribe: listener => {
devtools.emit(SUBSCRIBED, { store: storeObj, listener });
proxyObj.addListener(listener);
},
$unsubscribe: listener => {
devtools.emit(UNSUBSCRIBED, storeObj);
proxyObj.removeListener(listener);
},
} as unknown as StoreObj<S, A, C>;
function tryNextAction() { const plannedActions: PlannedAction<S, ActionFunction<S>>[] = [];
if (!plannedActions.length) {
devtools.emit(QUEUE_FINISHED, { store: handler });
proxyObj.$pending = false;
return;
}
const nextAction = plannedActions.shift()!;
devtools.emit(ACTION, { store: handler, action: nextAction, fromQueue: true });
const result = config.actions
? config.actions[nextAction.action].bind(handler, proxyObj)(...nextAction.payload)
: undefined;
if (isPromise(result)) {
result.then(value => {
nextAction.resolve(value);
tryNextAction();
});
} else {
nextAction.resolve(result);
tryNextAction();
}
}
// 包装actions // 包装actions
if (config.actions) { if (config.actions) {
Object.keys(config.actions).forEach(action => { Object.keys(config.actions).forEach(action => {
// 让store.$queue[action]可以访问到action方法
// 要达到的效果如果通过store.$queue[action1]调用的action1返回promise,会阻塞下一个store.$queue[action2]
($queue as any)[action] = (...payload) => { ($queue as any)[action] = (...payload) => {
devtools.emit(ACTION_QUEUED, { devtools.emit(ACTION_QUEUED, {
store: handler, store: storeObj,
action: { action: {
action, action,
payload, payload,
@ -171,18 +102,20 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
return new Promise(resolve => { return new Promise(resolve => {
if (!proxyObj.$pending) { if (!proxyObj.$pending) {
proxyObj.$pending = true; proxyObj.$pending = true;
const result = config.actions![action].bind(handler, proxyObj)(...payload);
const result = config.actions![action].bind(storeObj, proxyObj)(...payload);
if (isPromise(result)) { if (isPromise(result)) {
result.then(value => { result.then(value => {
resolve(value); resolve(value);
tryNextAction(); tryNextAction(storeObj, proxyObj, config, plannedActions);
}); });
} else { } else {
resolve(result); resolve(result);
tryNextAction(); tryNextAction(storeObj, proxyObj, config, plannedActions);
} }
} else { } else {
// 加入队列
plannedActions.push({ plannedActions.push({
action, action,
payload, payload,
@ -192,52 +125,57 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
}); });
}; };
// 让store.$a[action]可以访问到action方法
($a as any)[action] = function Wrapped(...payload) { ($a as any)[action] = function Wrapped(...payload) {
devtools.emit(ACTION, { devtools.emit(ACTION, {
store: handler, store: storeObj,
action: { action: {
action, action,
payload, payload,
}, },
fromQueue: false, fromQueue: false,
}); });
return config.actions![action].bind(handler, proxyObj)(...payload); return config.actions![action].bind(storeObj, proxyObj)(...payload);
}; };
// direct store access // 让store[action]可以访问到action方法
Object.defineProperty(handler, action, { Object.defineProperty(storeObj, action, {
writable: false, writable: false,
value: (...payload) => { value: (...payload) => {
devtools.emit(ACTION, { devtools.emit(ACTION, {
store: handler, store: storeObj,
action: { action: {
action, action,
payload, payload,
}, },
fromQueue: false, fromQueue: false,
}); });
return config.actions![action].bind(handler, proxyObj)(...payload); return config.actions![action].bind(storeObj, proxyObj)(...payload);
}, },
}); });
}); });
} }
if (config.computed) { if (config.computed) {
Object.keys(config.computed).forEach(key => { Object.keys(config.computed).forEach(computeKey => {
($c as any)[key] = config.computed![key].bind(handler, readonlyProxy(proxyObj)); // 让store.$c[computeKey]可以访问到computed方法
($c as any)[computeKey] = config.computed![computeKey].bind(storeObj, readonlyProxy(proxyObj));
// direct store access // 让store[computeKey]可以访问到computed的值
Object.defineProperty(handler, key, { Object.defineProperty(storeObj, computeKey, {
get: $c[key] as () => any, get: $c[computeKey] as () => any,
}); });
}); });
} }
// direct state access // 让store[key]可以访问到state的值
if (config.state) { if (config.state) {
Object.keys(config.state).forEach(key => { Object.keys(config.state).forEach(key => {
Object.defineProperty(handler, key, { Object.defineProperty(storeObj, key, {
get: () => proxyObj[key], get: () => {
// 从Proxy对象获取值会触发代理
return proxyObj[key];
},
set: value => { set: value => {
proxyObj[key] = value; proxyObj[key] = value;
}, },
@ -246,24 +184,66 @@ export function createStore<S extends object, A extends UserActions<S>, C extend
} }
if (config.id) { if (config.id) {
storeMap.set(config.id, handler); storeMap.set(config.id, storeObj);
} }
devtools.emit(INITIALIZED, { devtools.emit(INITIALIZED, {
store: handler, store: storeObj,
}); });
handler.$subscribe(() => { storeObj.$subscribe(() => {
devtools.emit(STATE_CHANGE, { devtools.emit(STATE_CHANGE, {
store: handler, store: storeObj,
}); });
}); });
return createStoreHook(handler); return createGetStore(storeObj);
} }
export function clearVNodeObservers(vNode) { // 通过该方法执行store.$queue中的action
if (!vNode.observers) return; function tryNextAction(storeObj, proxyObj, config, plannedActions) {
if (!plannedActions.length) {
proxyObj.$pending = false;
return;
}
const nextAction = plannedActions.shift()!;
const result = config.actions
? config.actions[nextAction.action].bind(storeObj, proxyObj)(...nextAction.payload)
: undefined;
if (isPromise(result)) {
result.then(value => {
nextAction.resolve(value);
tryNextAction(storeObj, proxyObj, config, plannedActions);
});
} else {
nextAction.resolve(result);
tryNextAction(storeObj, proxyObj, config, plannedActions);
}
}
// createStore返回的是一个getStore的函数这个函数必须要在组件函数/类组件里面被执行因为要注册VNode销毁时的清理动作
function createGetStore<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>>(
storeObj: StoreObj<S, A, C>
): () => StoreObj<S, A, C> {
const getStore = () => {
if (!storeObj.$config.options?.isReduxAdapter) {
registerDestroyFunction();
}
return storeObj;
};
return getStore;
}
// 删除Observers中保存的这个VNode的相关数据
export function clearVNodeObservers(vNode: VNode) {
if (!vNode.observers) {
return;
}
vNode.observers.forEach(observer => { vNode.observers.forEach(observer => {
observer.clearByVNode(vNode); observer.clearByVNode(vNode);
}); });
@ -271,10 +251,11 @@ export function clearVNodeObservers(vNode) {
vNode.observers.clear(); vNode.observers.clear();
} }
function hookStore() { // 注册VNode销毁时的清理动作
function registerDestroyFunction() {
const processingVNode = getProcessingVNode(); const processingVNode = getProcessingVNode();
// did not execute in a component // 获取不到当前运行的VNode说明不在组件中运行属于非法场景
if (!processingVNode) { if (!processingVNode) {
return; return;
} }
@ -283,10 +264,9 @@ function hookStore() {
processingVNode.observers = new Set<Observer>(); processingVNode.observers = new Set<Observer>();
} }
// 函数组件
if (processingVNode.tag === FunctionComponent) { if (processingVNode.tag === FunctionComponent) {
// from FunctionComponent const vNodeRef = useRef(processingVNode);
const vNodeRef = useRef(null) as unknown as { current: VNode };
vNodeRef.current = processingVNode;
useEffect(() => { useEffect(() => {
return () => { return () => {
@ -295,9 +275,9 @@ function hookStore() {
}; };
}, []); }, []);
} else if (processingVNode.tag === ClassComponent) { } else if (processingVNode.tag === ClassComponent) {
// from ClassComponent // 类组件
if (!processingVNode.classComponentWillUnmount) { if (!processingVNode.classComponentWillUnmount) {
processingVNode.classComponentWillUnmount = function (vNode) { processingVNode.classComponentWillUnmount = vNode => {
clearVNodeObservers(vNode); clearVNodeObservers(vNode);
vNode.observers = null; vNode.observers = null;
}; };
@ -305,28 +285,17 @@ function hookStore() {
} }
} }
function createStoreHook<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>>( // 函数组件中使用的hook
storeHandler: StoreHandler<S, A, C>
): () => StoreHandler<S, A, C> {
const storeHook = () => {
if (!storeHandler.$config.options?.suppressHooks) {
hookStore();
}
return storeHandler;
};
return storeHook;
}
export function useStore<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>>( export function useStore<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>>(
id: string id: string
): StoreHandler<S, A, C> { ): StoreObj<S, A, C> {
const storeObj = storeMap.get(id); const storeObj = storeMap.get(id);
if (storeObj && !storeObj.$config.options?.suppressHooks) hookStore(); if (storeObj && !storeObj.$config.options?.isReduxAdapter) {
registerDestroyFunction();
}
return storeObj as StoreHandler<S, A, C>; return storeObj as StoreObj<S, A, C>;
} }
export function clearStore(id: string): void { export function clearStore(id: string): void {

View File

@ -1,5 +1,19 @@
export interface IObserver { /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export interface IObserver {
useProp: (key: string | symbol) => void; useProp: (key: string | symbol) => void;
addListener: (listener: () => void) => void; addListener: (listener: () => void) => void;
@ -17,65 +31,67 @@ export interface IObserver {
clearByVNode: (vNode: any) => void; clearByVNode: (vNode: any) => void;
} }
type RemoveFirstFromTuple<T extends any[]> = export type StoreConfig<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>> = {
T['length'] extends 0 ? [] : id?: string;
(((...b: T) => void) extends (a, ...b: infer I) => void ? I : []) state?: S;
actions?: A;
computed?: C;
options?: {
isReduxAdapter?: boolean;
};
};
export type UserActions<S extends object> = {
[K: string]: ActionFunction<S>
};
type UserActions<S extends object> = { [K:string]: ActionFunction<S> }; type ActionFunction<S extends object> = (this: StoreObj<S, any, any>, state: S, ...args: any[]) => any;
type UserComputedValues<S extends object> = { [K:string]: ComputedFunction<S> };
export type StoreActions<S extends object, A extends UserActions<S>> = {
[K in keyof A]: Action<A[K], S>
};
type Action<T extends ActionFunction<any>, S extends object> = (
this: StoreObj<S, any, any>,
...args: RemoveFirstFromTuple<Parameters<T>>
) => ReturnType<T>;
export type StoreObj<S extends object, A extends UserActions<S>, C extends UserComputedValues<S>> = {
$s: S;
$a: StoreActions<S, A>;
$c: UserComputedValues<S>;
$queue: QueuedStoreActions<S, A>;
$subscribe: (listener: () => void) => void;
$unsubscribe: (listener: () => void) => void;
} & { [K in keyof S]: S[K] } & { [K in keyof A]: Action<A[K], S> } & { [K in keyof C]: ReturnType<C[K]> };
export type PlannedAction<S extends object, F extends ActionFunction<S>> = {
action: string;
payload: any[];
resolve: ReturnType<F>;
};
type RemoveFirstFromTuple<T extends any[]> = T['length'] extends 0
? []
: ((...b: T) => void) extends (a, ...b: infer I) => void
? I
: [];
export type UserComputedValues<S extends object> = {
[K: string]: ComputedFunction<S>
};
type ActionFunction<S extends object> = (state: S, ...args: any[]) => any;
type ComputedFunction<S extends object> = (state: S) => any; type ComputedFunction<S extends object> = (state: S) => any;
type Action<T extends UserActions<?>> = (...args:RemoveFirstFromTuple<Parameters<T>>)=>ReturnType<T>
type AsyncAction<T extends UserActions<?>> = (...args:RemoveFirstFromTuple<Parameters<T>>)=>Promise<ReturnType<T>>
type StoreActions<S extends object,A extends UserActions<S>> = { [K in keyof A]: Action<A[K]> }; export type AsyncAction<T extends ActionFunction<any>, S extends object> = (
type QueuedStoreActions<S extends object,A extends UserActions<S>> = { [K in keyof A]: AsyncAction<A[K]> }; this: StoreObj<S, any, any>,
type ComputedValues<S extends object,C extends UserComputedValues<S>> = { [K in keyof C]: ReturnType<C[K]> }; ...args: RemoveFirstFromTuple<Parameters<T>>
type PostponedAction = (state: object, ...args: any[]) => Promise<any>; ) => Promise<ReturnType<T>>;
type PostponedActions = { [key:string]: PostponedAction }
export type StoreHandler<S extends object,A extends UserActions<S>,C extends UserComputedValues<S>> = export type QueuedStoreActions<S extends object, A extends UserActions<S>> = {
{$subscribe: ((listener: () => void) => void), [K in keyof A]: AsyncAction<A[K], S>
$unsubscribe: ((listener: () => void) => void), };
$state: S,
$config: StoreConfig<S,A,C>,
$queue: QueuedStoreActions<S,A>,
$actions: StoreActions<S,A>,
$computed: ComputedValues<S,C>,
reduxHandler?:ReduxStoreHandler}
&
{[K in keyof S]: S[K]}
&
{[K in keyof A]: Action<A[K]>}
&
{[K in keyof C]: ReturnType<C[K]>}
export type StoreConfig<S extends object,A extends UserActions<S>,C extends UserComputedValues<S>> = { export type ComputedValues<S extends object, C extends UserComputedValues<S>> = {
state?: S, [K in keyof C]: ReturnType<C[K]>
options?:{suppressHooks?: boolean}, };
actions?: A,
id?: string,
computed?: C
}
type ReduxStoreHandler = {
reducer:(state:any,action:{type:string})=>any,
dispatch:(action:{type:string})=>void,
getState:()=>any,
subscribe:(listener:()=>void)=>((listener:()=>void)=>void)
replaceReducer: (reducer: (state:any,action:{type:string})=>any)=>void
_horizonXstore: StoreHandler
}
type ReduxAction = {
type:string
}
type ReduxMiddleware = (store:ReduxStoreHandler, extraArgument?:any) =>
(next:((action:ReduxAction)=>any)) =>
(action:(
ReduxAction|
((dispatch:(action:ReduxAction)=>void,store:ReduxStoreHandler,extraArgument?:any)=>any)
)) => ReduxStoreHandler

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/** /**
* context * context
* capture阶段会修改一些全局的值bubble阶段会恢复 * capture阶段会修改一些全局的值bubble阶段会恢复

View File

@ -1,18 +1,33 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/** /**
* *
*/ */
import type { PromiseType, VNode } from './Types'; import type { PromiseType, VNode } from './Types';
import type {Update} from './UpdateHandler'; import type { Update } from './UpdateHandler';
import {ClassComponent, TreeRoot} from './vnode/VNodeTags'; import { ClassComponent, TreeRoot } from './vnode/VNodeTags';
import {FlagUtils, Interrupted, DidCapture, InitFlag} from './vnode/VNodeFlags'; import { FlagUtils, Interrupted, DidCapture, InitFlag } from './vnode/VNodeFlags';
import {newUpdate, UpdateState, pushUpdate} from './UpdateHandler'; import { newUpdate, UpdateState, pushUpdate } from './UpdateHandler';
import {launchUpdateFromVNode, tryRenderFromRoot} from './TreeBuilder'; import { launchUpdateFromVNode, tryRenderFromRoot } from './TreeBuilder';
import {setRootThrowError} from './submit/Submit'; import { setRootThrowError } from './submit/Submit';
import {handleSuspenseChildThrowError} from './render/SuspenseComponent'; import { handleSuspenseChildThrowError } from './render/SuspenseComponent';
import {updateShouldUpdateOfTree} from './vnode/VNodeShouldUpdate'; import { updateShouldUpdateOfTree } from './vnode/VNodeShouldUpdate';
import {BuildErrored, setBuildResult} from './GlobalVar'; import { BuildErrored, setBuildResult } from './GlobalVar';
function consoleError(error: any): void { function consoleError(error: any): void {
if (isTest) { if (isTest) {
@ -23,18 +38,13 @@ function consoleError(error: any): void {
} }
} }
function handleRootError( function handleRootError(error: any) {
error: any,
) {
// 注意:如果根节点抛出错误,不会销毁整棵树,只打印日志,抛出异常。 // 注意:如果根节点抛出错误,不会销毁整棵树,只打印日志,抛出异常。
setRootThrowError(error); setRootThrowError(error);
consoleError(error); consoleError(error);
} }
function createClassErrorUpdate( function createClassErrorUpdate(vNode: VNode, error: any): Update {
vNode: VNode,
error: any,
): Update {
const update = newUpdate(); const update = newUpdate();
update.type = UpdateState.Error; update.type = UpdateState.Error;
@ -63,13 +73,10 @@ function createClassErrorUpdate(
return update; return update;
} }
function isPromise(error: any): error is PromiseType<any> { function isPromise(error: any): error is PromiseType<any> {
return error !== null && typeof error === 'object' && typeof error.then === 'function' return error !== null && typeof error === 'object' && typeof error.then === 'function';
} }
// 处理capture和bubble阶段抛出的错误 // 处理capture和bubble阶段抛出的错误
export function handleRenderThrowError( export function handleRenderThrowError(sourceVNode: VNode, error: any) {
sourceVNode: VNode,
error: any,
) {
// vNode抛出了异常标记Interrupted中断 // vNode抛出了异常标记Interrupted中断
FlagUtils.markInterrupted(sourceVNode); FlagUtils.markInterrupted(sourceVNode);
// dirtyNodes 不再有效 // dirtyNodes 不再有效
@ -102,10 +109,8 @@ export function handleRenderThrowError(
const instance = vNode.realNode; const instance = vNode.realNode;
if ( if (
(vNode.flags & DidCapture) === InitFlag && (vNode.flags & DidCapture) === InitFlag &&
( (typeof ctor.getDerivedStateFromError === 'function' ||
typeof ctor.getDerivedStateFromError === 'function' || (instance !== null && typeof instance.componentDidCatch === 'function'))
(instance !== null && typeof instance.componentDidCatch === 'function')
)
) { ) {
FlagUtils.markShouldCapture(vNode); FlagUtils.markShouldCapture(vNode);
@ -140,7 +145,6 @@ function triggerUpdate(vNode, state) {
} }
} }
// 处理submit阶段的异常 // 处理submit阶段的异常
export function handleSubmitError(vNode: VNode, error: any) { export function handleSubmitError(vNode: VNode, error: any) {
if (vNode.tag === TreeRoot) { if (vNode.tag === TreeRoot) {
@ -154,20 +158,19 @@ export function handleSubmitError(vNode: VNode, error: any) {
if (node.tag === TreeRoot) { if (node.tag === TreeRoot) {
handleRootError(error); handleRootError(error);
return; return;
} else if (node.tag === ClassComponent) { // 只有 class 组件才可以成为错误边界组件 } else if (node.tag === ClassComponent) {
// 只有 class 组件才可以成为错误边界组件
const ctor = node.type; const ctor = node.type;
const instance = node.realNode; const instance = node.realNode;
if ( if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function') {
typeof ctor.getDerivedStateFromError === 'function' ||
typeof instance.componentDidCatch === 'function'
) {
const getDerivedStateFromError = node.type.getDerivedStateFromError; const getDerivedStateFromError = node.type.getDerivedStateFromError;
if (typeof getDerivedStateFromError === 'function') { if (typeof getDerivedStateFromError === 'function') {
// 打印错误 // 打印错误
consoleError(error); consoleError(error);
const retState = getDerivedStateFromError(error); const retState = getDerivedStateFromError(error);
if (retState) { // 有返回值 if (retState) {
// 有返回值
// 触发更新 // 触发更新
triggerUpdate(node, retState); triggerUpdate(node, retState);
} }
@ -175,7 +178,8 @@ export function handleSubmitError(vNode: VNode, error: any) {
// 处理componentDidCatch // 处理componentDidCatch
if (instance !== null && typeof instance.componentDidCatch === 'function') { if (instance !== null && typeof instance.componentDidCatch === 'function') {
if (typeof getDerivedStateFromError !== 'function') { // 没有getDerivedStateFromError if (typeof getDerivedStateFromError !== 'function') {
// 没有getDerivedStateFromError
// 打印错误 // 打印错误
consoleError(error); consoleError(error);
} }

View File

@ -1,3 +1,17 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export const ByAsync = 'BY_ASYNC'; export const ByAsync = 'BY_ASYNC';
export const BySync = 'BY_SYNC'; export const BySync = 'BY_SYNC';
@ -27,7 +41,7 @@ export function isExecuting() {
} }
export function copyExecuteMode() { export function copyExecuteMode() {
return {...executeMode}; return { ...executeMode };
} }
export function setExecuteMode(mode: typeof executeMode) { export function setExecuteMode(mode: typeof executeMode) {

View File

@ -1,4 +1,19 @@
import type {VNode} from './Types'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode } from './Types';
// 当前处理的classVNode用于设置inst.refs // 当前处理的classVNode用于设置inst.refs
let processingClassVNode: VNode | null = null; let processingClassVNode: VNode | null = null;

View File

@ -1,30 +1,30 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode } from './Types'; import type { VNode } from './Types';
import type { Update } from './UpdateHandler'; import type { Update } from './UpdateHandler';
import { import { asyncUpdates, syncUpdates, runDiscreteUpdates, launchUpdateFromVNode } from './TreeBuilder';
asyncUpdates,
syncUpdates,
runDiscreteUpdates,
launchUpdateFromVNode,
} from './TreeBuilder';
import { runAsyncEffects } from './submit/HookEffectHandler'; import { runAsyncEffects } from './submit/HookEffectHandler';
import { Callback, newUpdate, pushUpdate } from './UpdateHandler'; import { Callback, newUpdate, pushUpdate } from './UpdateHandler';
export { createVNode, createTreeRootVNode } from './vnode/VNodeCreator'; export { createVNode, createTreeRootVNode } from './vnode/VNodeCreator';
export { createPortal } from './components/CreatePortal'; export { createPortal } from './components/CreatePortal';
export { export { asyncUpdates, syncUpdates, runDiscreteUpdates, runAsyncEffects };
asyncUpdates,
syncUpdates,
runDiscreteUpdates,
runAsyncEffects,
};
export function startUpdate( export function startUpdate(element: any, treeRoot: VNode, callback?: Callback) {
element: any,
treeRoot: VNode,
callback?: Callback,
) {
const update: Update = newUpdate(); const update: Update = newUpdate();
update.content = { element }; update.content = { element };
@ -43,4 +43,3 @@ export function getFirstCustomDom(treeRoot?: VNode | null): Element | Text | nul
} }
return null; return null;
} }

View File

@ -1,5 +1,16 @@
/* /*
* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/ */
import { VNode } from './vnode/VNode'; import { VNode } from './vnode/VNode';

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode } from './Types'; import type { VNode } from './Types';
import { callRenderQueueImmediate, pushRenderCallback } from './taskExecutor/RenderQueue'; import { callRenderQueueImmediate, pushRenderCallback } from './taskExecutor/RenderQueue';
@ -30,12 +45,7 @@ import {
isExecuting, isExecuting,
setExecuteMode, setExecuteMode,
} from './ExecuteMode'; } from './ExecuteMode';
import { import { resetContext, resetNamespaceCtx, setContext, setNamespaceCtx } from './ContextSaver';
resetContext,
resetNamespaceCtx,
setContext,
setNamespaceCtx,
} from './ContextSaver';
import { import {
updateChildShouldUpdate, updateChildShouldUpdate,
updateParentsChildShouldUpdate, updateParentsChildShouldUpdate,
@ -95,7 +105,8 @@ function bubbleVNode(vNode: VNode): void {
do { do {
const parent = node.parent; const parent = node.parent;
if ((node.flags & Interrupted) === InitFlag) { // vNode没有抛出异常 if ((node.flags & Interrupted) === InitFlag) {
// vNode没有抛出异常
componentRenders[node.tag].bubbleRender(node); componentRenders[node.tag].bubbleRender(node);
// 设置node的childShouldUpdate属性 // 设置node的childShouldUpdate属性
@ -118,7 +129,8 @@ function bubbleVNode(vNode: VNode): void {
} }
const siblingVNode = node.next; const siblingVNode = node.next;
if (siblingVNode !== null) { // 有兄弟vNode if (siblingVNode !== null) {
// 有兄弟vNode
processing = siblingVNode; processing = siblingVNode;
return; return;
} }
@ -229,7 +241,8 @@ function buildVNodeTree(treeRoot: VNode) {
// 清空toUpdateNodes // 清空toUpdateNodes
treeRoot.toUpdateNodes.clear(); treeRoot.toUpdateNodes.clear();
if (startVNode.tag !== TreeRoot) { // 不是根节点 if (startVNode.tag !== TreeRoot) {
// 不是根节点
// 设置namespace用于createElement // 设置namespace用于createElement
let parent = startVNode.parent; let parent = startVNode.parent;
while (parent !== null) { while (parent !== null) {
@ -275,7 +288,8 @@ function buildVNodeTree(treeRoot: VNode) {
handleError(treeRoot, thrownValue); handleError(treeRoot, thrownValue);
} }
} }
if (startVNode.tag !== TreeRoot) { // 不是根节点 if (startVNode.tag !== TreeRoot) {
// 不是根节点
// 恢复父节点的context // 恢复父节点的context
resetTreeContext(startVNode); resetTreeContext(startVNode);
} }
@ -293,7 +307,7 @@ function recoverTreeContext(vNode: VNode) {
if (parent.tag === ContextProvider) { if (parent.tag === ContextProvider) {
contextProviders.unshift(parent); contextProviders.unshift(parent);
} }
if(parent.tag === DomPortal){ if (parent.tag === DomPortal) {
pushCurrentRoot(parent); pushCurrentRoot(parent);
} }
parent = parent.parent; parent = parent.parent;
@ -311,7 +325,7 @@ function resetTreeContext(vNode: VNode) {
if (parent.tag === ContextProvider) { if (parent.tag === ContextProvider) {
resetContext(parent); resetContext(parent);
} }
if(parent.tag === DomPortal){ if (parent.tag === DomPortal) {
popCurrentRoot(); popCurrentRoot();
} }
parent = parent.parent; parent = parent.parent;
@ -350,9 +364,7 @@ function renderFromRoot(treeRoot) {
export function tryRenderFromRoot(treeRoot: VNode) { export function tryRenderFromRoot(treeRoot: VNode) {
if (treeRoot.shouldUpdate && treeRoot.task === null) { if (treeRoot.shouldUpdate && treeRoot.task === null) {
// 任务放进queue但是调度开始还是异步的 // 任务放进queue但是调度开始还是异步的
treeRoot.task = pushRenderCallback( treeRoot.task = pushRenderCallback(renderFromRoot.bind(null, treeRoot));
renderFromRoot.bind(null, treeRoot),
);
} }
} }
@ -372,8 +384,11 @@ export function launchUpdateFromVNode(vNode: VNode) {
// 保存待刷新的节点 // 保存待刷新的节点
treeRoot.toUpdateNodes?.add(vNode); treeRoot.toUpdateNodes?.add(vNode);
if (checkMode(BySync) && // 非批量 if (
!checkMode(InRender)) { // 不是渲染阶段触发 checkMode(BySync) && // 非批量
!checkMode(InRender)
) {
// 不是渲染阶段触发
// 业务直接调用Horizon.render的时候会进入这个分支同步渲染。 // 业务直接调用Horizon.render的时候会进入这个分支同步渲染。
// 不能改成下面的异步,否则会有时序问题,因为业务可能会依赖这个渲染的完成。 // 不能改成下面的异步,否则会有时序问题,因为业务可能会依赖这个渲染的完成。

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export { VNode } from './vnode/VNode'; export { VNode } from './vnode/VNode';
type Trigger<A> = (A) => void; type Trigger<A> = (A) => void;

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode } from './Types'; import type { VNode } from './Types';
import { FlagUtils, ShouldCapture } from './vnode/VNodeFlags'; import { FlagUtils, ShouldCapture } from './vnode/VNodeFlags';
@ -38,13 +53,7 @@ export function pushUpdate(vNode: VNode, update: Update) {
} }
// 根据update获取新的state // 根据update获取新的state
function calcState( function calcState(vNode: VNode, update: Update, inst: any, oldState: any, props: any): any {
vNode: VNode,
update: Update,
inst: any,
oldState: any,
props: any,
): any {
switch (update.type) { switch (update.type) {
case UpdateState.Override: case UpdateState.Override:
const content = update.content; const content = update.content;
@ -58,9 +67,7 @@ function calcState(
case UpdateState.Update: case UpdateState.Update:
const updateContent = update.content; const updateContent = update.content;
const newState = typeof updateContent === 'function' ? updateContent.call(inst, oldState, props) : updateContent; const newState = typeof updateContent === 'function' ? updateContent.call(inst, oldState, props) : updateContent;
return (newState === null || newState === undefined) return newState === null || newState === undefined ? oldState : { ...oldState, ...newState };
? oldState
: { ...oldState, ...newState };
default: default:
return oldState; return oldState;
} }
@ -103,7 +110,6 @@ export function processUpdates(vNode: VNode, inst: any, props: any): void {
calcUpdates(vNode, props, inst, toProcessUpdates); calcUpdates(vNode, props, inst, toProcessUpdates);
} }
} }
} }
export function pushForceUpdate(vNode: VNode) { export function pushForceUpdate(vNode: VNode) {

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/** /**
* Component的api setState和forceUpdate在实例生成阶段实现 * Component的api setState和forceUpdate在实例生成阶段实现
*/ */

View File

@ -1,11 +1,22 @@
import {TYPE_PORTAL} from '../../external/JSXElementType'; /*
import type {PortalType} from '../Types'; * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export function createPortal( import { TYPE_PORTAL } from '../../external/JSXElementType';
children: any, import type { PortalType } from '../Types';
realNode: any,
key: string = '', export function createPortal(children: any, realNode: any, key = ''): PortalType {
): PortalType {
return { return {
vtype: TYPE_PORTAL, vtype: TYPE_PORTAL,
key: key == '' ? '' : '' + key, key: key == '' ? '' : '' + key,

View File

@ -1,4 +1,19 @@
import type {RefType} from '../Types'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { RefType } from '../Types';
export function createRef(): RefType { export function createRef(): RefType {
return { return {

View File

@ -1,4 +1,19 @@
import {TYPE_FORWARD_REF} from '../../external/JSXElementType'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { TYPE_FORWARD_REF } from '../../external/JSXElementType';
export function forwardRef(render: Function) { export function forwardRef(render: Function) {
return { return {

View File

@ -1,6 +1,21 @@
import type {PromiseType} from '../Types'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import {TYPE_LAZY} from '../../external/JSXElementType'; import type { PromiseType } from '../Types';
import { TYPE_LAZY } from '../../external/JSXElementType';
enum LayStatus { enum LayStatus {
UnProcessed = 'UnProcessed', UnProcessed = 'UnProcessed',
@ -11,7 +26,7 @@ enum LayStatus {
type LazyContent<T> = { type LazyContent<T> = {
_status: string; _status: string;
_value: () => PromiseType<{default: T}> | PromiseType<T> | T | any; _value: () => PromiseType<{ default: T }> | PromiseType<T> | T | any;
}; };
export type LazyComponent<T, P> = { export type LazyComponent<T, P> = {
@ -44,7 +59,7 @@ function lazyLoader<T>(lazyContent: LazyContent<T>): any {
lazyContent._status = LayStatus.Rejected; lazyContent._status = LayStatus.Rejected;
lazyContent._value = error; lazyContent._value = error;
} }
}, }
); );
} }
if (lazyContent._status === LayStatus.Fulfilled) { if (lazyContent._status === LayStatus.Fulfilled) {
@ -54,7 +69,7 @@ function lazyLoader<T>(lazyContent: LazyContent<T>): any {
} }
} }
export function lazy<T>(promiseCtor: () => PromiseType<{default: T}>): LazyComponent<T, LazyContent<T>> { export function lazy<T>(promiseCtor: () => PromiseType<{ default: T }>): LazyComponent<T, LazyContent<T>> {
return { return {
vtype: TYPE_LAZY, vtype: TYPE_LAZY,
_content: { _content: {

View File

@ -1,4 +1,19 @@
import {TYPE_MEMO} from '../../external/JSXElementType'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { TYPE_MEMO } from '../../external/JSXElementType';
export function memo<Props>(type, compare?: (oldProps: Props, newProps: Props) => boolean) { export function memo<Props>(type, compare?: (oldProps: Props, newProps: Props) => boolean) {
return { return {

View File

@ -1,6 +1,21 @@
import type {VNode, ContextType} from '../../Types'; /*
import {getHookStage} from '../../hooks/HookStage'; * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
import {throwNotInFuncError} from '../../hooks/BaseHook'; *
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode, ContextType } from '../../Types';
import { getHookStage } from '../../hooks/HookStage';
import { throwNotInFuncError } from '../../hooks/BaseHook';
// 重置依赖 // 重置依赖
export function resetDepContexts(vNode: VNode): void { export function resetDepContexts(vNode: VNode): void {
@ -20,7 +35,7 @@ function collectDeps<T>(vNode: VNode, context: ContextType<T>) {
} }
} }
export function getNewContext<T>(vNode: VNode, ctx: ContextType<T>, isUseContext: boolean = false): T { export function getNewContext<T>(vNode: VNode, ctx: ContextType<T>, isUseContext = false): T {
// 如果来自于useContext则需要在函数组件中调用 // 如果来自于useContext则需要在函数组件中调用
if (isUseContext && getHookStage() === null) { if (isUseContext && getHookStage() === null) {
throwNotInFuncError(); throwNotInFuncError();

View File

@ -1,5 +1,20 @@
import type {ContextType} from '../../Types'; /*
import {TYPE_PROVIDER, TYPE_CONTEXT} from '../../../external/JSXElementType'; * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { ContextType } from '../../Types';
import { TYPE_PROVIDER, TYPE_CONTEXT } from '../../../external/JSXElementType';
export function createContext<T>(val: T): ContextType<T> { export function createContext<T>(val: T): ContextType<T> {
const context: ContextType<T> = { const context: ContextType<T> = {

View File

@ -1,9 +1,24 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode, JSXElement } from '../Types'; import type { VNode, JSXElement } from '../Types';
// 当前vNode和element是同样的类型 // 当前vNode和element是同样的类型
// LazyComponent 会修改type的类型所以特殊处理这种类型 // LazyComponent 会修改type的类型所以特殊处理这种类型
export const isSameType = (vNode: VNode, ele: JSXElement) => export const isSameType = (vNode: VNode, ele: JSXElement) =>
vNode.type === ele.type || (vNode.isLazyComponent && vNode.lazyType === ele.type); vNode.type === ele.type || (vNode.isLazyComponent && vNode.lazyType === ele.type);
export function isTextType(newChild: any) { export function isTextType(newChild: any) {
return typeof newChild === 'string' || typeof newChild === 'number'; return typeof newChild === 'string' || typeof newChild === 'number';

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode } from '../Types'; import type { VNode } from '../Types';
import { FlagUtils } from '../vnode/VNodeFlags'; import { FlagUtils } from '../vnode/VNodeFlags';
import { TYPE_COMMON_ELEMENT, TYPE_FRAGMENT, TYPE_PORTAL } from '../../external/JSXElementType'; import { TYPE_COMMON_ELEMENT, TYPE_FRAGMENT, TYPE_PORTAL } from '../../external/JSXElementType';
@ -9,13 +24,7 @@ import {
createPortalVNode, createPortalVNode,
createDomTextVNode, createDomTextVNode,
} from '../vnode/VNodeCreator'; } from '../vnode/VNodeCreator';
import { import { isSameType, getIteratorFn, isTextType, isIteratorType, isObjectType } from './DiffTools';
isSameType,
getIteratorFn,
isTextType,
isIteratorType,
isObjectType,
} from './DiffTools';
import { travelChildren } from '../vnode/VNodeUtils'; import { travelChildren } from '../vnode/VNodeUtils';
import { markVNodePath } from '../utils/vNodePath'; import { markVNodePath } from '../utils/vNodePath';
@ -105,10 +114,12 @@ function getNodeType(newChild: any): string | null {
function setVNodeAdditionFlag(newNode: VNode, lastPosition: number): number { function setVNodeAdditionFlag(newNode: VNode, lastPosition: number): number {
let position = lastPosition; let position = lastPosition;
if (newNode.isCreated || newNode.eIndex < lastPosition) { // 位置 小于 上一个复用的位置 if (newNode.isCreated || newNode.eIndex < lastPosition) {
// 位置 小于 上一个复用的位置
// 标记为新增 // 标记为新增
FlagUtils.setAddition(newNode); FlagUtils.setAddition(newNode);
} else { // 复用 } else {
// 复用
position = newNode.eIndex; position = newNode.eIndex;
} }
@ -191,15 +202,16 @@ function transRightChildrenToArray(child) {
return rightChildrenArray; return rightChildrenArray;
} }
function transLeftChildrenToMap( function transLeftChildrenToMap(startChild: VNode, rightEndVNode: VNode | null): Map<string | number, VNode> {
startChild: VNode,
rightEndVNode: VNode | null,
): Map<string | number, VNode> {
const leftChildrenMap: Map<string | number, VNode> = new Map(); const leftChildrenMap: Map<string | number, VNode> = new Map();
travelChildren(startChild, node => { travelChildren(
leftChildrenMap.set(node.key !== null ? node.key : node.eIndex, node); startChild,
}, node => node === rightEndVNode); node => {
leftChildrenMap.set(node.key !== null ? node.key : node.eIndex, node);
},
node => node === rightEndVNode
);
return leftChildrenMap; return leftChildrenMap;
} }
@ -220,11 +232,7 @@ function getOldNodeFromMap(nodeMap: Map<string | number, VNode>, newIdx: number,
} }
// diff数组类型的节点核心算法 // diff数组类型的节点核心算法
function diffArrayNodesHandler( function diffArrayNodesHandler(parentNode: VNode, firstChild: VNode | null, newChildren: Array<any>): VNode | null {
parentNode: VNode,
firstChild: VNode | null,
newChildren: Array<any>,
): VNode | null {
let resultingFirstChild: VNode | null = null; let resultingFirstChild: VNode | null = null;
let prevNewNode: VNode | null = null; let prevNewNode: VNode | null = null;
@ -351,13 +359,14 @@ function diffArrayNodesHandler(
// 4. 新节点还有一部分,但是老节点已经没有了 // 4. 新节点还有一部分,但是老节点已经没有了
if (oldNode === null) { if (oldNode === null) {
let isDirectAdd = false; let isDirectAdd = false;
// TODO: 是否可以扩大至非dom类型节点 // TODO: 是否可以扩大至非dom类型节点
// 如果dom节点在上次添加前没有节点说明本次添加时可以直接添加到最后不需要通过 getSiblingDom 函数找到 before 节点 // 如果dom节点在上次添加前没有节点说明本次添加时可以直接添加到最后不需要通过 getSiblingDom 函数找到 before 节点
if (parentNode.tag === DomComponent && if (
parentNode.tag === DomComponent &&
parentNode.oldProps?.children?.length === 0 && parentNode.oldProps?.children?.length === 0 &&
rightIdx - leftIdx === newChildren.length) { rightIdx - leftIdx === newChildren.length
) {
isDirectAdd = true; isDirectAdd = true;
} }
const isAddition = parentNode.tag === DomPortal || !parentNode.isCreated; const isAddition = parentNode.tag === DomPortal || !parentNode.isCreated;
@ -409,7 +418,8 @@ function diffArrayNodesHandler(
const eIndex = newNode.eIndex; const eIndex = newNode.eIndex;
eIndexes.push(eIndex); eIndexes.push(eIndex);
last = eIndexes[result[result.length - 1]]; last = eIndexes[result[result.length - 1]];
if (eIndex > last || last === undefined) { // 大的 eIndex直接放在最后 if (eIndex > last || last === undefined) {
// 大的 eIndex直接放在最后
preIndex[i] = result[result.length - 1]; preIndex[i] = result[result.length - 1];
result.push(i); result.push(i);
} else { } else {
@ -485,7 +495,7 @@ function setVNodesCIndex(startChild: VNode | null, startIdx: number) {
function diffIteratorNodesHandler( function diffIteratorNodesHandler(
parentNode: VNode, parentNode: VNode,
firstChild: VNode | null, firstChild: VNode | null,
newChildrenIterable: Iterable<any>, newChildrenIterable: Iterable<any>
): VNode | null { ): VNode | null {
const iteratorFn = getIteratorFn(newChildrenIterable); const iteratorFn = getIteratorFn(newChildrenIterable);
const iteratorObj = iteratorFn.call(newChildrenIterable); const iteratorObj = iteratorFn.call(newChildrenIterable);
@ -502,12 +512,7 @@ function diffIteratorNodesHandler(
} }
// 新节点是字符串类型 // 新节点是字符串类型
function diffStringNodeHandler( function diffStringNodeHandler(parentNode: VNode, newChild: any, firstChildVNode: VNode, isComparing: boolean) {
parentNode: VNode,
newChild: any,
firstChildVNode: VNode,
isComparing: boolean
) {
let newTextNode: VNode | null = null; let newTextNode: VNode | null = null;
// 第一个vNode是Text则复用 // 第一个vNode是Text则复用

View File

@ -1,5 +1,20 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { Hook } from './HookType'; import type { Hook } from './HookType';
import {getProcessingVNode} from '../GlobalVar'; import { getProcessingVNode } from '../GlobalVar';
// lastTimeHook是上一次执行func时产生的hooks中与currentHook对应的hook // lastTimeHook是上一次执行func时产生的hooks中与currentHook对应的hook
let lastTimeHook: Hook<any, any> | null = null; let lastTimeHook: Hook<any, any> | null = null;
@ -20,9 +35,7 @@ export function setCurrentHook(hook: Hook<any, any> | null) {
} }
export function throwNotInFuncError() { export function throwNotInFuncError() {
throw Error( throw Error('Hooks should be used inside function component.');
'Hooks should be used inside function component.',
);
} }
// 新建一个hook并放到vNode.hooks中 // 新建一个hook并放到vNode.hooks中
@ -48,9 +61,8 @@ export function getNextHook(hook: Hook<any, any>, hooks: Array<Hook<any, any>>)
// 原因1.比对hook的数量有没有变化非必要2.从上一次执行中的hook获取removeEffect // 原因1.比对hook的数量有没有变化非必要2.从上一次执行中的hook获取removeEffect
export function getCurrentHook(): Hook<any, any> { export function getCurrentHook(): Hook<any, any> {
const processingVNode = getProcessingVNode(); const processingVNode = getProcessingVNode();
currentHook = currentHook !== null ? currentHook =
getNextHook(currentHook, processingVNode.hooks) : currentHook !== null ? getNextHook(currentHook, processingVNode.hooks) : processingVNode.hooks[0] || null;
(processingVNode.hooks[0] || null);
if (lastTimeHook !== null) { if (lastTimeHook !== null) {
lastTimeHook = getNextHook(lastTimeHook, processingVNode.oldHooks); lastTimeHook = getNextHook(lastTimeHook, processingVNode.oldHooks);

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export const EffectConstant = { export const EffectConstant = {
NoEffect: 0, NoEffect: 0,
DepsChange: 1, // dependence发生了改变 DepsChange: 1, // dependence发生了改变

View File

@ -1,36 +1,44 @@
import type {ContextType} from '../Types'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import {useRefImpl} from './UseRefHook'; import type { ContextType } from '../Types';
import {useEffectImpl, useLayoutEffectImpl} from './UseEffectHook';
import {useCallbackImpl} from './UseCallbackHook'; import { useRefImpl } from './UseRefHook';
import {useMemoImpl} from './UseMemoHook'; import { useEffectImpl, useLayoutEffectImpl } from './UseEffectHook';
import {useImperativeHandleImpl} from './UseImperativeHook'; import { useCallbackImpl } from './UseCallbackHook';
import {useReducerImpl} from './UseReducerHook'; import { useMemoImpl } from './UseMemoHook';
import {useStateImpl} from './UseStateHook'; import { useImperativeHandleImpl } from './UseImperativeHook';
import {getNewContext} from '../components/context/Context'; import { useReducerImpl } from './UseReducerHook';
import {getProcessingVNode} from '../GlobalVar'; import { useStateImpl } from './UseStateHook';
import {Ref, Trigger} from './HookType'; import { getNewContext } from '../components/context/Context';
import { getProcessingVNode } from '../GlobalVar';
import { Ref, Trigger } from './HookType';
type BasicStateAction<S> = ((S) => S) | S; type BasicStateAction<S> = ((S) => S) | S;
type Dispatch<A> = (A) => void; type Dispatch<A> = (A) => void;
export function useContext<T>(Context: ContextType<T>): T {
export function useContext<T>(
Context: ContextType<T>,
): T {
const processingVNode = getProcessingVNode(); const processingVNode = getProcessingVNode();
return getNewContext(processingVNode!, Context, true); return getNewContext(processingVNode!, Context, true);
} }
export function useState<S>(initialState: (() => S) | S,): [S, Dispatch<BasicStateAction<S>>] { export function useState<S>(initialState: (() => S) | S): [S, Dispatch<BasicStateAction<S>>] {
return useStateImpl(initialState); return useStateImpl(initialState);
} }
export function useReducer<S, I, A>( export function useReducer<S, I, A>(reducer: (S, A) => S, initialArg: I, init?: (I) => S): [S, Trigger<A>] | void {
reducer: (S, A) => S,
initialArg: I,
init?: (I) => S,
): [S, Trigger<A>] | void {
return useReducerImpl(reducer, initialArg, init); return useReducerImpl(reducer, initialArg, init);
} }
@ -38,38 +46,26 @@ export function useRef<T>(initialValue: T): Ref<T> {
return useRefImpl(initialValue); return useRefImpl(initialValue);
} }
export function useEffect( export function useEffect(create: () => (() => void) | void, deps?: Array<any> | null): void {
create: () => (() => void) | void,
deps?: Array<any> | null,
): void {
return useEffectImpl(create, deps); return useEffectImpl(create, deps);
} }
export function useLayoutEffect( export function useLayoutEffect(create: () => (() => void) | void, deps?: Array<any> | null): void {
create: () => (() => void) | void,
deps?: Array<any> | null,
): void {
return useLayoutEffectImpl(create, deps); return useLayoutEffectImpl(create, deps);
} }
export function useCallback<T>( export function useCallback<T>(callback: T, deps?: Array<any> | null): T {
callback: T,
deps?: Array<any> | null,
): T {
return useCallbackImpl(callback, deps); return useCallbackImpl(callback, deps);
} }
export function useMemo<T>( export function useMemo<T>(create: () => T, deps?: Array<any> | null): T {
create: () => T,
deps?: Array<any> | null,
): T {
return useMemoImpl(create, deps); return useMemoImpl(create, deps);
} }
export function useImperativeHandle<T>( export function useImperativeHandle<T>(
ref: {current: T | null} | ((inst: T | null) => any) | null | void, ref: { current: T | null } | ((inst: T | null) => any) | null | void,
create: () => T, create: () => T,
deps?: Array<any> | null, deps?: Array<any> | null
): void { ): void {
return useImperativeHandleImpl(ref, create, deps); return useImperativeHandleImpl(ref, create, deps);
} }

View File

@ -1,18 +1,29 @@
import type {VNode} from '../Types'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { import type { VNode } from '../Types';
getLastTimeHook,
setLastTimeHook, import { getLastTimeHook, setLastTimeHook, setCurrentHook, getNextHook } from './BaseHook';
setCurrentHook, getNextHook import { HookStage, setHookStage } from './HookStage';
} from './BaseHook';
import {HookStage, setHookStage} from './HookStage';
// hook对外入口 // hook对外入口
export function runFunctionWithHooks<Props extends Record<string, any>, Arg>( export function runFunctionWithHooks<Props extends Record<string, any>, Arg>(
funcComp: (props: Props, arg: Arg) => any, funcComp: (props: Props, arg: Arg) => any,
props: Props, props: Props,
arg: Arg, arg: Arg,
processing: VNode, processing: VNode
) { ) {
// 重置全局变量 // 重置全局变量
resetGlobalVariable(); resetGlobalVariable();
@ -52,4 +63,3 @@ function resetGlobalVariable() {
setLastTimeHook(null); setLastTimeHook(null);
setCurrentHook(null); setCurrentHook(null);
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
// hooks阶段 // hooks阶段
export enum HookStage { export enum HookStage {
Init = 1, Init = 1,

View File

@ -1,4 +1,19 @@
import {EffectConstant} from './EffectConstant'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { EffectConstant } from './EffectConstant';
type ValueOf<T> = T[keyof T]; type ValueOf<T> = T[keyof T];
export interface Hook<S, A> { export interface Hook<S, A> {
state: Reducer<S, A> | Effect | Memo<S> | CallBack<S> | Ref<S>; state: Reducer<S, A> | Effect | Memo<S> | CallBack<S> | Ref<S>;
@ -39,7 +54,7 @@ export type CallBack<F> = {
}; };
export type Ref<V> = { export type Ref<V> = {
current: V | null; current: V;
}; };
export type Trigger<A> = (A) => void; export type Trigger<A> = (A) => void;

View File

@ -1,10 +1,21 @@
import { /*
createHook, * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
getCurrentHook, *
throwNotInFuncError * openGauss is licensed under Mulan PSL v2.
} from './BaseHook'; * You can use this software according to the terms and conditions of the Mulan PSL v2.
import {getHookStage, HookStage} from './HookStage'; * You may obtain a copy of Mulan PSL v2 at:
import {isArrayEqual} from '../utils/compare'; *
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { createHook, getCurrentHook, throwNotInFuncError } from './BaseHook';
import { getHookStage, HookStage } from './HookStage';
import { isArrayEqual } from '../utils/compare';
export function useCallbackImpl<F>(func: F, dependencies?: Array<any> | null): F { export function useCallbackImpl<F>(func: F, dependencies?: Array<any> | null): F {
const stage = getHookStage(); const stage = getHookStage();
@ -16,7 +27,7 @@ export function useCallbackImpl<F>(func: F, dependencies?: Array<any> | null): F
const deps = dependencies !== undefined ? dependencies : null; const deps = dependencies !== undefined ? dependencies : null;
if (stage === HookStage.Init) { if (stage === HookStage.Init) {
hook = createHook(); hook = createHook();
hook.state = {func, dependencies: deps}; hook.state = { func, dependencies: deps };
} else if (stage === HookStage.Update) { } else if (stage === HookStage.Update) {
hook = getCurrentHook(); hook = getCurrentHook();
@ -25,7 +36,7 @@ export function useCallbackImpl<F>(func: F, dependencies?: Array<any> | null): F
if (lastState !== null && deps !== null && isArrayEqual(deps, lastState.dependencies)) { if (lastState !== null && deps !== null && isArrayEqual(deps, lastState.dependencies)) {
return lastState.func; return lastState.func;
} }
hook.state = {func, dependencies: deps}; hook.state = { func, dependencies: deps };
} }
return func; return func;

View File

@ -1,17 +1,27 @@
import { /*
createHook, * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
getCurrentHook, *
getLastTimeHook, * openGauss is licensed under Mulan PSL v2.
throwNotInFuncError * You can use this software according to the terms and conditions of the Mulan PSL v2.
} from './BaseHook'; * You may obtain a copy of Mulan PSL v2 at:
import {FlagUtils} from '../vnode/VNodeFlags'; *
import {EffectConstant} from './EffectConstant'; * http://license.coscl.org.cn/MulanPSL2
import type {Effect, EffectList} from './HookType'; *
import {getHookStage, HookStage} from './HookStage'; * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
import {isArrayEqual} from '../utils/compare'; * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
import {getProcessingVNode} from '../GlobalVar'; * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export function useEffectImpl(effectFunc: () => (() => void) | void, deps?: Array<any> | null,): void { import { createHook, getCurrentHook, getLastTimeHook, throwNotInFuncError } from './BaseHook';
import { FlagUtils } from '../vnode/VNodeFlags';
import { EffectConstant } from './EffectConstant';
import type { Effect, EffectList } from './HookType';
import { getHookStage, HookStage } from './HookStage';
import { isArrayEqual } from '../utils/compare';
import { getProcessingVNode } from '../GlobalVar';
export function useEffectImpl(effectFunc: () => (() => void) | void, deps?: Array<any> | null): void {
// 异步触发的effect // 异步触发的effect
useEffect(effectFunc, deps, EffectConstant.Effect); useEffect(effectFunc, deps, EffectConstant.Effect);
} }
@ -21,11 +31,7 @@ export function useLayoutEffectImpl(effectFunc: () => (() => void) | void, deps?
useEffect(effectFunc, deps, EffectConstant.LayoutEffect); useEffect(effectFunc, deps, EffectConstant.LayoutEffect);
} }
function useEffect( function useEffect(effectFunc: () => (() => void) | void, deps: Array<any> | void | null, effectType: number): void {
effectFunc: () => (() => void) | void,
deps: Array<any> | void | null,
effectType: number
): void {
const stage = getHookStage(); const stage = getHookStage();
if (stage === null) { if (stage === null) {
throwNotInFuncError(); throwNotInFuncError();

View File

@ -1,12 +1,27 @@
import {useLayoutEffectImpl} from './UseEffectHook'; /*
import {getHookStage} from './HookStage'; * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
import {throwNotInFuncError} from './BaseHook'; *
import type {Ref} from './HookType'; * openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { useLayoutEffectImpl } from './UseEffectHook';
import { getHookStage } from './HookStage';
import { throwNotInFuncError } from './BaseHook';
import type { Ref } from './HookType';
export function useImperativeHandleImpl<R>( export function useImperativeHandleImpl<R>(
ref: { current: R | null } | ((any) => any) | null | void, ref: { current: R | null } | ((any) => any) | null | void,
func: () => R, func: () => R,
dependencies?: Array<any> | null, dependencies?: Array<any> | null
): void { ): void {
const stage = getHookStage(); const stage = getHookStage();
if (stage === null) { if (stage === null) {
@ -21,10 +36,7 @@ function isNotNull(object: any): boolean {
return object !== null && object !== undefined; return object !== null && object !== undefined;
} }
function effectFunc<R>( function effectFunc<R>(func: () => R, ref: Ref<R> | ((any) => any) | null): (() => void) | void {
func: () => R,
ref: Ref<R> | ((any) => any) | null,
): (() => void) | void {
if (typeof ref === 'function') { if (typeof ref === 'function') {
const value = func(); const value = func();
ref(value); ref(value);

View File

@ -1,12 +1,23 @@
import { /*
createHook, * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
getCurrentHook, *
throwNotInFuncError * openGauss is licensed under Mulan PSL v2.
} from './BaseHook'; * You can use this software according to the terms and conditions of the Mulan PSL v2.
import {getHookStage, HookStage} from './HookStage'; * You may obtain a copy of Mulan PSL v2 at:
import {isArrayEqual} from '../utils/compare'; *
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
export function useMemoImpl<V>(fun: () => V, deps?: Array<any> | null,): V { import { createHook, getCurrentHook, throwNotInFuncError } from './BaseHook';
import { getHookStage, HookStage } from './HookStage';
import { isArrayEqual } from '../utils/compare';
export function useMemoImpl<V>(fun: () => V, deps?: Array<any> | null): V {
const stage = getHookStage(); const stage = getHookStage();
if (stage === null) { if (stage === null) {
throwNotInFuncError(); throwNotInFuncError();
@ -30,6 +41,6 @@ export function useMemoImpl<V>(fun: () => V, deps?: Array<any> | null,): V {
result = fun(); result = fun();
} }
hook.state = {result, dependencies: nextDeps}; hook.state = { result, dependencies: nextDeps };
return hook.state.result; return hook.state.result;
} }

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { Hook, Reducer, Trigger, Update } from './HookType'; import type { Hook, Reducer, Trigger, Update } from './HookType';
import { createHook, getCurrentHook, throwNotInFuncError } from './BaseHook'; import { createHook, getCurrentHook, throwNotInFuncError } from './BaseHook';
import { launchUpdateFromVNode } from '../TreeBuilder'; import { launchUpdateFromVNode } from '../TreeBuilder';
@ -122,7 +137,7 @@ function updateReducerHookState<S, A>(currentHookUpdates, currentHook, reducer):
// 计算stateValue值 // 计算stateValue值
function calculateNewState<S, A>(currentHookUpdates: Array<Update<S, A>>, currentHook, reducer: (S, A) => S) { function calculateNewState<S, A>(currentHookUpdates: Array<Update<S, A>>, currentHook, reducer: (S, A) => S) {
let reducerObj = currentHook.state; const reducerObj = currentHook.state;
let state = reducerObj.stateValue; let state = reducerObj.stateValue;
// 循环遍历更新数组,计算新的状态值 // 循环遍历更新数组,计算新的状态值

View File

@ -1,6 +1,21 @@
import {createHook, getCurrentHook, throwNotInFuncError} from './BaseHook'; /*
import {getHookStage, HookStage} from './HookStage'; * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
import type {Ref} from './HookType'; *
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import { createHook, getCurrentHook, throwNotInFuncError } from './BaseHook';
import { getHookStage, HookStage } from './HookStage';
import type { Ref } from './HookType';
export function useRefImpl<V>(value: V): Ref<V> { export function useRefImpl<V>(value: V): Ref<V> {
const stage = getHookStage(); const stage = getHookStage();
@ -11,7 +26,7 @@ export function useRefImpl<V>(value: V): Ref<V> {
let hook; let hook;
if (stage === HookStage.Init) { if (stage === HookStage.Init) {
hook = createHook(); hook = createHook();
hook.state = {current: value}; hook.state = { current: value };
} else if (stage === HookStage.Update) { } else if (stage === HookStage.Update) {
hook = getCurrentHook(); hook = getCurrentHook();
} }

View File

@ -1,5 +1,20 @@
import type {Trigger} from './HookType'; /*
import {useReducerImpl} from './UseReducerHook'; * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { Trigger } from './HookType';
import { useReducerImpl } from './UseReducerHook';
function defaultReducer<S>(state: S, action: ((S) => S) | S): S { function defaultReducer<S>(state: S, action: ((S) => S) | S): S {
// @ts-ignore // @ts-ignore

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode } from '../Types'; import type { VNode } from '../Types';
import { ContextProvider, DomComponent, DomPortal, TreeRoot, SuspenseComponent } from '../vnode/VNodeTags'; import { ContextProvider, DomComponent, DomPortal, TreeRoot, SuspenseComponent } from '../vnode/VNodeTags';

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode } from '../Types'; import type { VNode } from '../Types';
import { mergeDefaultProps } from './LazyComponent'; import { mergeDefaultProps } from './LazyComponent';
@ -15,9 +30,7 @@ import {
} from './class/ClassLifeCycleProcessor'; } from './class/ClassLifeCycleProcessor';
import { FlagUtils, DidCapture } from '../vnode/VNodeFlags'; import { FlagUtils, DidCapture } from '../vnode/VNodeFlags';
import { markRef } from './BaseComponent'; import { markRef } from './BaseComponent';
import { import { processUpdates } from '../UpdateHandler';
processUpdates,
} from '../UpdateHandler';
import { setProcessingClassVNode } from '../GlobalVar'; import { setProcessingClassVNode } from '../GlobalVar';
import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator'; import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator';
import { createChildrenByDiff } from '../diff/nodeDiffComparator'; import { createChildrenByDiff } from '../diff/nodeDiffComparator';
@ -26,9 +39,7 @@ const emptyContextObj = {};
// 获取当前节点的context // 获取当前节点的context
export function getCurrentContext(clazz, processing: VNode) { export function getCurrentContext(clazz, processing: VNode) {
const context = clazz.contextType; const context = clazz.contextType;
return typeof context === 'object' && context !== null return typeof context === 'object' && context !== null ? getNewContext(processing, context) : emptyContextObj;
? getNewContext(processing, context)
: emptyContextObj;
} }
// 挂载实例 // 挂载实例
@ -69,9 +80,7 @@ function createChildren(clazz: any, processing: VNode) {
const isCatchError = (processing.flags & DidCapture) === DidCapture; const isCatchError = (processing.flags & DidCapture) === DidCapture;
// 按照已有规格如果捕获了错误却没有定义getDerivedStateFromError函数返回的child为null // 按照已有规格如果捕获了错误却没有定义getDerivedStateFromError函数返回的child为null
const newElements = isCatchError && typeof clazz.getDerivedStateFromError !== 'function' const newElements = isCatchError && typeof clazz.getDerivedStateFromError !== 'function' ? null : inst.render();
? null
: inst.render();
processing.child = createChildrenByDiff(processing, processing.child, newElements, !processing.isCreated); processing.child = createChildrenByDiff(processing, processing.child, newElements, !processing.isCreated);
return processing.child; return processing.child;
@ -121,7 +130,8 @@ export function captureRender(processing: VNode): VNode | null {
// 挂载新组件,一定会更新 // 挂载新组件,一定会更新
mountInstance(ctor, processing, nextProps); mountInstance(ctor, processing, nextProps);
shouldUpdate = true; shouldUpdate = true;
} else { // 更新 } else {
// 更新
const newContext = getCurrentContext(ctor, processing); const newContext = getCurrentContext(ctor, processing);
// 子节点抛出异常时如果本class是个捕获异常的处理节点这时候oldProps是null所以需要使用props // 子节点抛出异常时如果本class是个捕获异常的处理节点这时候oldProps是null所以需要使用props
@ -135,9 +145,7 @@ export function captureRender(processing: VNode): VNode | null {
processUpdates(processing, inst, nextProps); processUpdates(processing, inst, nextProps);
// 如果 props, state, context 都没有变化且 isForceUpdate 为 false则不需要更新 // 如果 props, state, context 都没有变化且 isForceUpdate 为 false则不需要更新
shouldUpdate = oldProps !== processing.props || shouldUpdate = oldProps !== processing.props || inst.state !== processing.state || processing.isForceUpdate;
inst.state !== processing.state ||
processing.isForceUpdate;
if (shouldUpdate) { if (shouldUpdate) {
// derivedStateFromProps会修改nextState因此需要调用 // derivedStateFromProps会修改nextState因此需要调用

View File

@ -1,6 +1,21 @@
import type {VNode, ContextType} from '../Types'; /*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import {resetDepContexts, getNewContext} from '../components/context/Context'; import type { VNode, ContextType } from '../Types';
import { resetDepContexts, getNewContext } from '../components/context/Context';
import { createChildrenByDiff } from '../diff/nodeDiffComparator'; import { createChildrenByDiff } from '../diff/nodeDiffComparator';
function captureContextConsumer(processing: VNode) { function captureContextConsumer(processing: VNode) {
@ -21,4 +36,3 @@ export function captureRender(processing: VNode): VNode | null {
} }
export function bubbleRender() {} export function bubbleRender() {}

View File

@ -1,12 +1,24 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode, ContextType, ProviderType } from '../Types'; import type { VNode, ContextType, ProviderType } from '../Types';
import { isSame } from '../utils/compare'; import { isSame } from '../utils/compare';
import { ClassComponent, ContextProvider } from '../vnode/VNodeTags'; import { ClassComponent, ContextProvider } from '../vnode/VNodeTags';
import { pushForceUpdate } from '../UpdateHandler'; import { pushForceUpdate } from '../UpdateHandler';
import { import { resetContext, setContext } from '../ContextSaver';
resetContext,
setContext,
} from '../ContextSaver';
import { travelVNodeTree } from '../vnode/VNodeUtils'; import { travelVNodeTree } from '../vnode/VNodeUtils';
import { launchUpdateFromVNode } from '../TreeBuilder'; import { launchUpdateFromVNode } from '../TreeBuilder';
import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator'; import { onlyUpdateChildVNodes } from '../vnode/VNodeCreator';
@ -47,15 +59,20 @@ function handleContextChange(processing: VNode, context: ContextType<any>): void
let isMatch = false; let isMatch = false;
// 从vNode开始遍历 // 从vNode开始遍历
travelVNodeTree(vNode, node => { travelVNodeTree(
const depContexts = node.depContexts; vNode,
if (depContexts && depContexts.length) { node => {
isMatch = matchDependencies(depContexts, context, node) ?? isMatch; const depContexts = node.depContexts;
} if (depContexts && depContexts.length) {
}, node => isMatch = matchDependencies(depContexts, context, node) ?? isMatch;
// 如果这是匹配的provider则不要更深入地扫描 }
node.tag === ContextProvider && node.type === processing.type },
, processing, null); node =>
// 如果这是匹配的provider则不要更深入地扫描
node.tag === ContextProvider && node.type === processing.type,
processing,
null
);
// 找到了依赖context的子节点触发一次更新 // 找到了依赖context的子节点触发一次更新
if (isMatch) { if (isMatch) {
@ -102,4 +119,3 @@ export function captureRender(processing: VNode): VNode | null {
export function bubbleRender(processing: VNode) { export function bubbleRender(processing: VNode) {
resetContext(processing); resetContext(processing);
} }

View File

@ -1,28 +1,30 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode } from '../Types'; import type { VNode } from '../Types';
import type { Props } from '../../dom/DOMOperator'; import type { Props } from '../../dom/DOMOperator';
import { import { getNamespaceCtx, setNamespaceCtx, resetNamespaceCtx } from '../ContextSaver';
getNamespaceCtx, import { appendChildElement, newDom, initDomProps, getPropChangeList, isTextChild } from '../../dom/DOMOperator';
setNamespaceCtx,
resetNamespaceCtx,
} from '../ContextSaver';
import {
appendChildElement,
newDom,
initDomProps, getPropChangeList,
isTextChild,
} from '../../dom/DOMOperator';
import { FlagUtils } from '../vnode/VNodeFlags'; import { FlagUtils } from '../vnode/VNodeFlags';
import { markRef } from './BaseComponent'; import { markRef } from './BaseComponent';
import { DomComponent, DomPortal, DomText } from '../vnode/VNodeTags'; import { DomComponent, DomPortal, DomText } from '../vnode/VNodeTags';
import { travelVNodeTree } from '../vnode/VNodeUtils'; import { travelVNodeTree } from '../vnode/VNodeUtils';
import { createChildrenByDiff } from '../diff/nodeDiffComparator'; import { createChildrenByDiff } from '../diff/nodeDiffComparator';
function updateDom( function updateDom(processing: VNode, type: any, newProps: Props) {
processing: VNode,
type: any,
newProps: Props,
) {
// 如果oldProps !== newProps意味着存在更新并且需要处理其相关的副作用 // 如果oldProps !== newProps意味着存在更新并且需要处理其相关的副作用
const oldProps = processing.oldProps; const oldProps = processing.oldProps;
if (oldProps === newProps) { if (oldProps === newProps) {
@ -32,12 +34,7 @@ function updateDom(
const dom: Element = processing.realNode; const dom: Element = processing.realNode;
const changeList = getPropChangeList( const changeList = getPropChangeList(dom, type, oldProps, newProps);
dom,
type,
oldProps,
newProps,
);
// 输入类型的直接标记更新 // 输入类型的直接标记更新
if (type === 'input' || type === 'textarea' || type === 'select' || type === 'option') { if (type === 'input' || type === 'textarea' || type === 'select' || type === 'option') {
@ -59,11 +56,7 @@ export function bubbleRender(processing: VNode) {
const newProps = processing.props; const newProps = processing.props;
if (!processing.isCreated && processing.realNode != null) { if (!processing.isCreated && processing.realNode != null) {
// 更新dom属性 // 更新dom属性
updateDom( updateDom(processing, type, newProps);
processing,
type,
newProps,
);
if (processing.oldRef !== processing.ref) { if (processing.oldRef !== processing.ref) {
FlagUtils.markRef(processing); FlagUtils.markRef(processing);
@ -72,25 +65,25 @@ export function bubbleRender(processing: VNode) {
const parentNamespace = getNamespaceCtx(); const parentNamespace = getNamespaceCtx();
// 创建dom // 创建dom
const dom = newDom( const dom = newDom(type, newProps, parentNamespace, processing);
type,
newProps,
parentNamespace,
processing,
);
// 把dom类型的子节点append到parent dom中 // 把dom类型的子节点append到parent dom中
const vNode = processing.child; const vNode = processing.child;
if (vNode !== null) { if (vNode !== null) {
// 向下递归它的子节点,查找所有终端节点。 // 向下递归它的子节点,查找所有终端节点。
travelVNodeTree(vNode, node => { travelVNodeTree(
if (node.tag === DomComponent || node.tag === DomText) { vNode,
appendChildElement(dom, node.realNode); node => {
} if (node.tag === DomComponent || node.tag === DomText) {
}, node => appendChildElement(dom, node.realNode);
// 已经append到父节点或者是DomPortal都不需要处理child了 }
node.tag === DomComponent || node.tag === DomText || node.tag === DomPortal },
, processing, null); node =>
// 已经append到父节点或者是DomPortal都不需要处理child了
node.tag === DomComponent || node.tag === DomText || node.tag === DomPortal,
processing,
null
);
} }
processing.realNode = dom; processing.realNode = dom;

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
import type { VNode } from '../Types'; import type { VNode } from '../Types';
import { resetNamespaceCtx, setNamespaceCtx } from '../ContextSaver'; import { resetNamespaceCtx, setNamespaceCtx } from '../ContextSaver';
import { createChildrenByDiff } from '../diff/nodeDiffComparator'; import { createChildrenByDiff } from '../diff/nodeDiffComparator';

Some files were not shown because too many files have changed in this diff Show More