UNPKG

7.24 kBJavaScriptView Raw
1import Taro from '@tarojs/api';
2import { isFunction } from '@tarojs/shared';
3import { findDOM } from '../../utils/index.js';
4import { CanvasContext } from '../canvas/CanvasContext.js';
5import { NodesRef } from './nodesRef.js';
6
7function 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 // Note https://developers.weixin.qq.com/miniprogram/dev/api/ui/scroll/ScrollViewContext.html
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 // TODO HTMLVideoElement to VideoContext
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 * WXML节点信息API
120 * @return {Object} SelectorQuery 对象实例
121 */
122function queryBat(queue, cb) {
123 const result = [];
124 queue.forEach(item => {
125 var _a;
126 const { selector, single, fields, component } = item;
127 // selector 的容器节点
128 /* eslint-disable */
129 const container = (component !== null ?
130 (findDOM(component) || document) :
131 document);
132 /* eslint-enable */
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}
162class 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 // 小程序里跨自定义组件的后代选择器 '>>>' 在 h5 替换为普通后代选择器 '>'
176 if (typeof selector === 'string')
177 selector = selector.replace('>>>', '>');
178 return new NodesRef(selector, this, true);
179 }
180 selectAll(selector) {
181 // 小程序里跨自定义组件的后代选择器 '>>>' 在 h5 替换为普通后代选择器 '>'
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
213export { SelectorQuery };
214//# sourceMappingURL=selectorQuery.js.map