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