1 | import Taro from '@tarojs/api';
|
2 | import { isFunction } from '@tarojs/shared';
|
3 | import { findDOM } from '../../utils/index.js';
|
4 | import { CanvasContext } from '../canvas/CanvasContext.js';
|
5 | import { NodesRef } from './nodesRef.js';
|
6 |
|
7 | function filter(fields, dom, selector) {
|
8 | if (!dom)
|
9 | return null;
|
10 | const isViewport = selector === '.taro_page';
|
11 | const { id, dataset, rect, size, scrollOffset, properties = [], computedStyle = [], nodeCanvasType, node, context } = fields;
|
12 | const res = {};
|
13 | if (nodeCanvasType && node) {
|
14 | const tagName = dom.tagName;
|
15 | res.node = {
|
16 | id: dom.id,
|
17 | $taroElement: dom
|
18 | };
|
19 | if (/^taro-canvas-core/i.test(tagName)) {
|
20 | const type = dom.type || '';
|
21 | res.nodeCanvasType = type;
|
22 | const canvas = dom.getElementsByTagName('canvas')[0];
|
23 | if (/^(2d|webgl)/i.test(type) && canvas) {
|
24 | res.node = canvas;
|
25 | }
|
26 | else {
|
27 | res.node = null;
|
28 | }
|
29 | }
|
30 | else if (/^taro-scroll-view-core/i.test(tagName)) {
|
31 |
|
32 | res.nodeCanvasType = '';
|
33 | res.node = dom;
|
34 | dom.scrollTo = dom.mpScrollToMethod;
|
35 | dom.scrollIntoView = dom.mpScrollIntoViewMethod;
|
36 | }
|
37 | else {
|
38 | res.nodeCanvasType = '';
|
39 | res.node = dom;
|
40 | }
|
41 | return res;
|
42 | }
|
43 | if (context) {
|
44 | const tagName = dom.tagName;
|
45 | if (/^taro-video-core/i.test(tagName)) {
|
46 |
|
47 | return { context: dom };
|
48 | }
|
49 | else if (/^taro-canvas-core/i.test(tagName)) {
|
50 | const type = dom.type || '2d';
|
51 | const canvas = dom === null || dom === void 0 ? void 0 : dom.querySelector('canvas');
|
52 | const ctx = canvas === null || canvas === void 0 ? void 0 : canvas.getContext(type);
|
53 | return { context: new CanvasContext(canvas, ctx) };
|
54 | }
|
55 | else if (/^taro-live-player-core/i.test(tagName)) {
|
56 | console.error('暂时不支持通过 NodesRef.context 获取 LivePlayerContext');
|
57 | }
|
58 | else if (/^taro-editor-core/i.test(tagName)) {
|
59 | console.error('暂时不支持通过 NodesRef.context 获取 EditorContext');
|
60 | }
|
61 | else if (/^taro-map-core/i.test(tagName)) {
|
62 | console.error('暂时不支持通过 NodesRef.context 获取 MapContext');
|
63 | }
|
64 | return;
|
65 | }
|
66 | if (id)
|
67 | res.id = dom.id;
|
68 | if (dataset)
|
69 | res.dataset = Object.assign({}, dom.dataset);
|
70 | if (rect || size) {
|
71 | const { left, right, top, bottom, width, height } = dom.getBoundingClientRect();
|
72 | if (rect) {
|
73 | if (!isViewport) {
|
74 | res.left = left;
|
75 | res.right = right;
|
76 | res.top = top;
|
77 | res.bottom = bottom;
|
78 | }
|
79 | else {
|
80 | res.left = 0;
|
81 | res.right = 0;
|
82 | res.top = 0;
|
83 | res.bottom = 0;
|
84 | }
|
85 | }
|
86 | if (size) {
|
87 | if (!isViewport) {
|
88 | res.width = width;
|
89 | res.height = height;
|
90 | }
|
91 | else {
|
92 | res.width = dom.clientWidth;
|
93 | res.height = dom.clientHeight;
|
94 | }
|
95 | }
|
96 | }
|
97 | if (scrollOffset) {
|
98 | res.scrollLeft = dom.scrollLeft;
|
99 | res.scrollTop = dom.scrollTop;
|
100 | }
|
101 | if (properties.length) {
|
102 | properties.forEach(prop => {
|
103 | const attr = dom.getAttribute(prop);
|
104 | if (attr)
|
105 | res[prop] = attr;
|
106 | });
|
107 | }
|
108 | if (computedStyle.length) {
|
109 | const styles = window.getComputedStyle(dom);
|
110 | computedStyle.forEach(key => {
|
111 | const value = styles.getPropertyValue(key) || styles[key];
|
112 | if (value)
|
113 | res[key] = value;
|
114 | });
|
115 | }
|
116 | return res;
|
117 | }
|
118 |
|
119 |
|
120 |
|
121 |
|
122 | function queryBat(queue, cb) {
|
123 | const result = [];
|
124 | queue.forEach(item => {
|
125 | var _a;
|
126 | const { selector, single, fields, component } = item;
|
127 |
|
128 |
|
129 | const container = (component !== null ?
|
130 | (findDOM(component) || document) :
|
131 | document);
|
132 |
|
133 |
|
134 | let selectSelf = false;
|
135 | if (container !== document) {
|
136 | const $nodeList = (_a = container.parentNode) === null || _a === void 0 ? void 0 : _a.querySelectorAll(selector);
|
137 | if ($nodeList) {
|
138 | for (let i = 0, len = $nodeList.length; i < len; ++i) {
|
139 | if (container === $nodeList[i]) {
|
140 | selectSelf = true;
|
141 | break;
|
142 | }
|
143 | }
|
144 | }
|
145 | }
|
146 | if (single) {
|
147 | const el = selectSelf === true ? container : container.querySelector(selector);
|
148 | result.push(filter(fields, el, selector));
|
149 | }
|
150 | else {
|
151 | const $children = container.querySelectorAll(selector);
|
152 | const children = [];
|
153 | selectSelf === true && children.push(container);
|
154 | for (let i = 0, len = $children.length; i < len; ++i) {
|
155 | children.push($children[i]);
|
156 | }
|
157 | result.push(children.map(dom => filter(fields, dom)));
|
158 | }
|
159 | });
|
160 | cb(result);
|
161 | }
|
162 | class SelectorQuery {
|
163 | constructor() {
|
164 | this._defaultWebviewId = null;
|
165 | this._webviewId = null;
|
166 | this._queue = [];
|
167 | this._queueCb = [];
|
168 | this._component;
|
169 | }
|
170 | in(component) {
|
171 | this._component = component;
|
172 | return this;
|
173 | }
|
174 | select(selector) {
|
175 |
|
176 | if (typeof selector === 'string')
|
177 | selector = selector.replace('>>>', '>');
|
178 | return new NodesRef(selector, this, true);
|
179 | }
|
180 | selectAll(selector) {
|
181 |
|
182 | if (typeof selector === 'string')
|
183 | selector = selector.replace('>>>', '>');
|
184 | return new NodesRef(selector, this, false);
|
185 | }
|
186 | selectViewport() {
|
187 | return new NodesRef('.taro_page', this, true);
|
188 | }
|
189 | exec(cb) {
|
190 | Taro.nextTick(() => {
|
191 | queryBat(this._queue, res => {
|
192 | const _queueCb = this._queueCb;
|
193 | res.forEach((item, index) => {
|
194 | const cb = _queueCb[index];
|
195 | isFunction(cb) && cb.call(this, item);
|
196 | });
|
197 | isFunction(cb) && cb.call(this, res);
|
198 | });
|
199 | });
|
200 | return this;
|
201 | }
|
202 | _push(selector, component, single, fields, callback = null) {
|
203 | this._queue.push({
|
204 | component,
|
205 | selector,
|
206 | single,
|
207 | fields
|
208 | });
|
209 | this._queueCb.push(callback);
|
210 | }
|
211 | }
|
212 |
|
213 | export { SelectorQuery };
|
214 |
|