UNPKG

6.95 kBJavaScriptView Raw
1import { isFunction } from '@tarojs/shared';
2import { findDOM } from '../../utils/index.js';
3import { CanvasContext } from '../canvas/CanvasContext.js';
4import { NodesRef } from './nodesRef.js';
5
6function 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 // TODO https://developers.weixin.qq.com/miniprogram/dev/api/ui/scroll/ScrollViewContext.html
31 // if (/^taro-scroll-view-core/i.test(tagName))
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 // TODO HTMLVideoElement to VideoContext
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 * WXML节点信息API
114 * @return {Object} SelectorQuery 对象实例
115 */
116function queryBat(queue, cb) {
117 const result = [];
118 queue.forEach(item => {
119 var _a;
120 const { selector, single, fields, component } = item;
121 // selector 的容器节点
122 /* eslint-disable */
123 const container = (component !== null ?
124 (findDOM(component) || document) :
125 document);
126 /* eslint-enable */
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}
156class 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 // 小程序里跨自定义组件的后代选择器 '>>>' 在 h5 替换为普通后代选择器 '>'
170 if (typeof selector === 'string')
171 selector = selector.replace('>>>', '>');
172 return new NodesRef(selector, this, true);
173 }
174 selectAll(selector) {
175 // 小程序里跨自定义组件的后代选择器 '>>>' 在 h5 替换为普通后代选择器 '>'
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
205export { SelectorQuery };
206//# sourceMappingURL=selectorQuery.js.map