From 61d51f39a5bcef943d85b05efbc724c6810269a7 Mon Sep 17 00:00:00 2001 From: zoomchan-cxj Date: Sat, 8 Oct 2022 19:51:06 +0800 Subject: [PATCH] feat(vue): add getElemCss scoped judgement --- .../hippy-vue/src/renderer/native/index.js | 15 +--------- .../native/style/__tests__/index.test.js | 28 ++++++++++++++++++- .../native/style/__tests__/parser.test.js | 20 +++++++++++++ packages/hippy-vue/src/runtime/native.js | 2 ++ packages/hippy-vue/src/util/node.js | 25 +++++++++++++++++ 5 files changed, 75 insertions(+), 15 deletions(-) diff --git a/packages/hippy-vue/src/renderer/native/index.js b/packages/hippy-vue/src/renderer/native/index.js index a29979b8e2c..84d3545bb43 100644 --- a/packages/hippy-vue/src/renderer/native/index.js +++ b/packages/hippy-vue/src/renderer/native/index.js @@ -34,14 +34,13 @@ import { warn, deepCopy, isFunction, - isScopedEnabled, capitalizeFirstLetter, convertImageLocalPath, } from '../../util'; import { isRTL, } from '../../util/i18n'; -import { preCacheNode } from '../../util/node'; +import { isStyleMatched, preCacheNode } from '../../util/node'; import { fromAstNodes, SelectorsMap } from './style'; const componentName = ['%c[native]%c', 'color: red', 'color: auto']; @@ -316,18 +315,6 @@ function getTargetNodeAttributes(targetNode) { } } -function isStyleMatched(matchedSelector, targetNode) { - if (!isScopedEnabled()) return true; - if (!targetNode || !matchedSelector) return false; - const nodeScopeId = targetNode.styleScopeId; - // set scopeId as element node attribute for style matching - if (nodeScopeId) targetNode.attributes[nodeScopeId] = true; - const isMatched = matchedSelector.match(targetNode); - // delete scopeId attr after selector matching check - if (nodeScopeId) delete targetNode.attributes[nodeScopeId]; - return isMatched; -} - /** * Render Element to native */ diff --git a/packages/hippy-vue/src/renderer/native/style/__tests__/index.test.js b/packages/hippy-vue/src/renderer/native/style/__tests__/index.test.js index 6f61b66d68c..80b7464f140 100644 --- a/packages/hippy-vue/src/renderer/native/style/__tests__/index.test.js +++ b/packages/hippy-vue/src/renderer/native/style/__tests__/index.test.js @@ -1,3 +1,23 @@ +/* + * Tencent is pleased to support the open source community by making + * Hippy available. + * + * Copyright (C) 2017-2022 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import test, { before } from 'ava'; import { fromAstNodes, SelectorsMap } from '../index'; import ElementNode from '../../../element-node'; @@ -37,6 +57,7 @@ test('AppendSelector test', (t) => { selectors: [ '#id', '*', + '#id[attr="test"]', ], declarations: [ { @@ -49,6 +70,11 @@ test('AppendSelector test', (t) => { property: 'UniversalSelector', value: 'UniversalSelector', }, + { + type: 'declaration', + property: 'AttributeSelector', + value: 'AttributeSelector', + }, ], }]; const appendRules = fromAstNodes(APPEND_AST); @@ -56,5 +82,5 @@ test('AppendSelector test', (t) => { const node = new ElementNode('div'); node.setAttribute('id', 'id'); const matchedCSS = cssMap.query(node); - t.is(matchedCSS.selectors.length, 9); + t.is(matchedCSS.selectors.length, 10); }); diff --git a/packages/hippy-vue/src/renderer/native/style/__tests__/parser.test.js b/packages/hippy-vue/src/renderer/native/style/__tests__/parser.test.js index d950d5153ba..13bda5bff65 100644 --- a/packages/hippy-vue/src/renderer/native/style/__tests__/parser.test.js +++ b/packages/hippy-vue/src/renderer/native/style/__tests__/parser.test.js @@ -1,3 +1,23 @@ +/* + * Tencent is pleased to support the open source community by making + * Hippy available. + * + * Copyright (C) 2017-2022 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import test from 'ava'; import parseSelector from '../parser'; diff --git a/packages/hippy-vue/src/runtime/native.js b/packages/hippy-vue/src/runtime/native.js index 668fc3b47f9..01570bd15bf 100644 --- a/packages/hippy-vue/src/runtime/native.js +++ b/packages/hippy-vue/src/runtime/native.js @@ -30,6 +30,7 @@ import { getCssMap, } from '../renderer/native/index'; +import { isStyleMatched } from '../util/node'; import BackAndroid from './backAndroid'; import * as NetInfo from './netInfo'; @@ -96,6 +97,7 @@ const getElemCss = function getElemCss(element) { const style = Object.create(null); try { getCssMap().query(element).selectors.forEach((matchedSelector) => { + if (!isStyleMatched(matchedSelector, element)) return; matchedSelector.ruleSet.declarations.forEach((cssStyle) => { style[cssStyle.property] = cssStyle.value; }); diff --git a/packages/hippy-vue/src/util/node.js b/packages/hippy-vue/src/util/node.js index 39f6a26f2d7..114aaeb87e5 100644 --- a/packages/hippy-vue/src/util/node.js +++ b/packages/hippy-vue/src/util/node.js @@ -18,6 +18,8 @@ * limitations under the License. */ +import { isScopedEnabled } from './index'; + const nodeCache = new Map(); /** @@ -103,6 +105,28 @@ function cancelIdleCallback(id) { } } +/** + * isStyleMatched - judge whether selector matching + * @param matchedSelector + * @param targetNode + * @returns {boolean|*} + */ +function isStyleMatched(matchedSelector, targetNode) { + if (!isScopedEnabled()) return true; + if (!targetNode || !matchedSelector) return false; + const nodeScopeId = targetNode.styleScopeId; + // set scopeId as element node attribute for style matching + if (nodeScopeId) { + targetNode.attributes[nodeScopeId] = true; + } + const isMatched = matchedSelector.match(targetNode); + // delete scopeId attr after selector matching check + if (nodeScopeId) { + delete targetNode.attributes[nodeScopeId]; + } + return isMatched; +} + export { recursivelyUnCacheNode, requestIdleCallback, @@ -111,4 +135,5 @@ export { unCacheNode, getNodeById, unCacheNodeOnIdle, + isStyleMatched, };