@mpxjs/core 2.9.38 → 2.9.41-react.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +37 -3
- package/src/convertor/convertor.js +4 -1
- package/src/convertor/getConvertMode.js +3 -1
- package/src/convertor/wxToReact.js +31 -0
- package/src/core/proxy.js +75 -7
- package/src/core/transferOptions.js +9 -1
- package/src/dynamic/astCache.js +25 -0
- package/src/dynamic/dynamicRenderMixin.js +77 -0
- package/src/dynamic/vnode/context.js +17 -0
- package/src/dynamic/vnode/css-select/cssauron.js +445 -0
- package/src/dynamic/vnode/css-select/index.js +116 -0
- package/src/dynamic/vnode/css-select/through.js +19 -0
- package/src/dynamic/vnode/css-select/tokenizer.js +371 -0
- package/src/dynamic/vnode/interpreter.js +449 -0
- package/src/dynamic/vnode/render.js +289 -0
- package/src/{vuePlugin.js → external/vuePlugin.js} +1 -1
- package/src/index.js +8 -2
- package/src/platform/builtInMixins/directiveHelperMixin.android.js +2 -0
- package/src/platform/builtInMixins/directiveHelperMixin.ios.js +15 -0
- package/src/platform/builtInMixins/directiveHelperMixin.js +3 -0
- package/src/platform/builtInMixins/index.js +20 -2
- package/src/platform/builtInMixins/proxyEventMixin.android.js +2 -0
- package/src/platform/builtInMixins/proxyEventMixin.ios.js +49 -0
- package/src/platform/builtInMixins/proxyEventMixin.js +12 -14
- package/src/platform/builtInMixins/refsMixin.android.js +2 -0
- package/src/platform/builtInMixins/refsMixin.ios.js +311 -0
- package/src/platform/builtInMixins/renderHelperMixin.js +2 -2
- package/src/platform/builtInMixins/styleHelperMixin.android.js +2 -0
- package/src/platform/builtInMixins/styleHelperMixin.ios.js +141 -0
- package/src/platform/builtInMixins/styleHelperMixin.js +3 -0
- package/src/platform/createApp.android.js +2 -0
- package/src/platform/createApp.ios.js +103 -0
- package/src/platform/createApp.js +3 -5
- package/src/platform/export/api.web.js +1 -1
- package/src/platform/patch/ali/getDefaultOptions.js +24 -4
- package/src/platform/patch/index.js +9 -6
- package/src/platform/patch/react/getDefaultOptions.android.js +1 -0
- package/src/platform/patch/react/getDefaultOptions.ios.js +270 -0
- package/src/platform/patch/react/getDefaultOptions.js +1 -0
- package/src/platform/patch/swan/getDefaultOptions.js +1 -1
- package/src/platform/patch/web/getDefaultOptions.js +13 -3
- package/src/platform/patch/wx/getDefaultOptions.js +21 -1
- /package/src/{vue.js → external/vue.js} +0 -0
- /package/src/{vue.web.js → external/vue.web.js} +0 -0
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import tokenizer from './tokenizer'
|
|
2
|
+
|
|
3
|
+
export default function language (lookups, matchComparison) {
|
|
4
|
+
return function (selector, moduleId) {
|
|
5
|
+
return parse(
|
|
6
|
+
selector,
|
|
7
|
+
remap(lookups),
|
|
8
|
+
moduleId,
|
|
9
|
+
matchComparison || caseSensitiveComparison
|
|
10
|
+
)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function remap (opts) {
|
|
15
|
+
// 对于字符串类型的 value 转化为函数
|
|
16
|
+
for (const key in opts) {
|
|
17
|
+
if (opt_okay(opts, key)) {
|
|
18
|
+
/* eslint-disable-next-line */
|
|
19
|
+
opts[key] = Function(
|
|
20
|
+
'return function(node, attr) { return node.' + opts[key] + ' }'
|
|
21
|
+
)
|
|
22
|
+
opts[key] = opts[key]()
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return opts
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function opt_okay (opts, key) {
|
|
30
|
+
return Object.prototype.hasOwnProperty.call(opts, key) && typeof opts[key] === 'string'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function parse (selector, options, moduleId, matchComparison) {
|
|
34
|
+
const stream = tokenizer()
|
|
35
|
+
// const default_subj = true
|
|
36
|
+
const selectors = [[]]
|
|
37
|
+
let bits = selectors[0]
|
|
38
|
+
|
|
39
|
+
// 逆向关系
|
|
40
|
+
const traversal = {
|
|
41
|
+
'': any_parents,
|
|
42
|
+
'>': direct_parent,
|
|
43
|
+
'+': direct_sibling,
|
|
44
|
+
'~': any_sibling
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
stream.on('data', group)
|
|
48
|
+
stream.end(selector)
|
|
49
|
+
|
|
50
|
+
function group (token) {
|
|
51
|
+
if (token.type === 'comma') {
|
|
52
|
+
selectors.unshift((bits = []))
|
|
53
|
+
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 获取节点之间的关系路径,匹配的规则从右往左依次进行,因此在后面的匹配规则需要存储在栈结构的前面
|
|
58
|
+
if (token.type === 'op' || token.type === 'any-child') {
|
|
59
|
+
bits.unshift(traversal[token.data]) // 获取节点之间关系的操作数
|
|
60
|
+
bits.unshift(check()) // 添加空的匹配操作数
|
|
61
|
+
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
bits[0] = bits[0] || check()
|
|
66
|
+
const crnt = bits[0]
|
|
67
|
+
|
|
68
|
+
if (token.type === '!') {
|
|
69
|
+
crnt.subject = selectors[0].subject = true
|
|
70
|
+
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
crnt.push(
|
|
75
|
+
token.type === 'class'
|
|
76
|
+
? listContains(token.type, token.data)
|
|
77
|
+
: token.type === 'attr'
|
|
78
|
+
? attr(token)
|
|
79
|
+
: token.type === ':' || token.type === '::'
|
|
80
|
+
? pseudo(token)
|
|
81
|
+
: token.type === '*'
|
|
82
|
+
? Boolean
|
|
83
|
+
: matches(token.type, token.data, matchComparison)
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return selector_fn
|
|
88
|
+
|
|
89
|
+
// 单节点对比
|
|
90
|
+
function selector_fn (node, as_boolean) {
|
|
91
|
+
if (node.data?.moduleId !== moduleId) {
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
let current, length, subj
|
|
95
|
+
|
|
96
|
+
const orig = node
|
|
97
|
+
const set = []
|
|
98
|
+
|
|
99
|
+
for (let i = 0, len = selectors.length; i < len; ++i) {
|
|
100
|
+
bits = selectors[i]
|
|
101
|
+
current = entry // 当前 bits 检测规则
|
|
102
|
+
length = bits.length
|
|
103
|
+
node = orig // 引用赋值
|
|
104
|
+
subj = []
|
|
105
|
+
|
|
106
|
+
let j = 0
|
|
107
|
+
// 步长为2,因为2个节点之间的关系中间会有一个 OP 操作符
|
|
108
|
+
for (j = 0; j < length; j += 2) {
|
|
109
|
+
node = current(node, bits[j], subj)
|
|
110
|
+
|
|
111
|
+
if (!node) {
|
|
112
|
+
break
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// todo 这里的规则和步长设计的很巧妙
|
|
116
|
+
current = bits[j + 1] // 改变当前的 bits 检测规则
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (j >= length) {
|
|
120
|
+
if (as_boolean) {
|
|
121
|
+
return true
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
add(!bits.subject ? [orig] : subj)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (as_boolean) {
|
|
129
|
+
return false
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return !set.length ? false : set.length === 1 ? set[0] : set
|
|
133
|
+
|
|
134
|
+
function add (items) {
|
|
135
|
+
let next
|
|
136
|
+
|
|
137
|
+
while (items.length) {
|
|
138
|
+
next = items.shift()
|
|
139
|
+
|
|
140
|
+
if (set.indexOf(next) === -1) {
|
|
141
|
+
set.push(next)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 匹配操作数
|
|
148
|
+
function check () {
|
|
149
|
+
_check.bits = []
|
|
150
|
+
_check.subject = false
|
|
151
|
+
_check.push = function (token) {
|
|
152
|
+
_check.bits.push(token)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return _check
|
|
156
|
+
|
|
157
|
+
function _check (node, subj) {
|
|
158
|
+
for (let i = 0, len = _check.bits.length; i < len; ++i) {
|
|
159
|
+
if (!_check.bits[i](node)) {
|
|
160
|
+
return false
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (_check.subject) {
|
|
165
|
+
subj.push(node)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return true
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function listContains (type, data) {
|
|
173
|
+
return function (node) {
|
|
174
|
+
let val = options[type](node)
|
|
175
|
+
val = Array.isArray(val) ? val : val ? val.toString().split(/\s+/) : []
|
|
176
|
+
return val.indexOf(data) >= 0
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function attr (token) {
|
|
181
|
+
return token.data.lhs
|
|
182
|
+
? valid_attr(options.attr, token.data.lhs, token.data.cmp, token.data.rhs)
|
|
183
|
+
: valid_attr(options.attr, token.data)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function matches (type, data, matchComparison) {
|
|
187
|
+
return function (node) {
|
|
188
|
+
return matchComparison(type, options[type](node), data)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function any_parents (node, next, subj) {
|
|
193
|
+
do {
|
|
194
|
+
node = options.parent(node)
|
|
195
|
+
} while (node && !next(node, subj))
|
|
196
|
+
|
|
197
|
+
return node
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function direct_parent (node, next, subj) {
|
|
201
|
+
node = options.parent(node)
|
|
202
|
+
|
|
203
|
+
return node && next(node, subj) ? node : null
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function direct_sibling (node, next, subj) {
|
|
207
|
+
const parent = options.parent(node)
|
|
208
|
+
let idx = 0
|
|
209
|
+
|
|
210
|
+
const children = options.children(parent)
|
|
211
|
+
|
|
212
|
+
for (let i = 0, len = children.length; i < len; ++i) {
|
|
213
|
+
if (children[i] === node) {
|
|
214
|
+
idx = i
|
|
215
|
+
|
|
216
|
+
break
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return children[idx - 1] && next(children[idx - 1], subj)
|
|
221
|
+
? children[idx - 1]
|
|
222
|
+
: null
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function any_sibling (node, next, subj) {
|
|
226
|
+
const parent = options.parent(node)
|
|
227
|
+
|
|
228
|
+
const children = options.children(parent)
|
|
229
|
+
|
|
230
|
+
for (let i = 0, len = children.length; i < len; ++i) {
|
|
231
|
+
if (children[i] === node) {
|
|
232
|
+
return null
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (next(children[i], subj)) {
|
|
236
|
+
return children[i]
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return null
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function pseudo (token) {
|
|
244
|
+
return valid_pseudo(options, token.data, matchComparison)
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function entry (node, next, subj) {
|
|
249
|
+
return next(node, subj) ? node : null
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function valid_pseudo (options, match, matchComparison) {
|
|
253
|
+
switch (match) {
|
|
254
|
+
case 'empty':
|
|
255
|
+
return valid_empty(options)
|
|
256
|
+
case 'first-child':
|
|
257
|
+
return valid_first_child(options)
|
|
258
|
+
case 'last-child':
|
|
259
|
+
return valid_last_child(options)
|
|
260
|
+
case 'root':
|
|
261
|
+
return valid_root(options)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (match.indexOf('contains') === 0) {
|
|
265
|
+
return valid_contains(options, match.slice(9, -1))
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (match.indexOf('any') === 0) {
|
|
269
|
+
return valid_any_match(options, match.slice(4, -1), matchComparison)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (match.indexOf('not') === 0) {
|
|
273
|
+
return valid_not_match(options, match.slice(4, -1), matchComparison)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (match.indexOf('nth-child') === 0) {
|
|
277
|
+
return valid_nth_child(options, match.slice(10, -1))
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return function () {
|
|
281
|
+
return false
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function valid_not_match (options, selector, matchComparison) {
|
|
286
|
+
const fn = parse(selector, options, matchComparison)
|
|
287
|
+
|
|
288
|
+
return not_function
|
|
289
|
+
|
|
290
|
+
function not_function (node) {
|
|
291
|
+
return !fn(node, true)
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function valid_any_match (options, selector, matchComparison) {
|
|
296
|
+
const fn = parse(selector, options, matchComparison)
|
|
297
|
+
|
|
298
|
+
return fn
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function valid_attr (fn, lhs, cmp, rhs) {
|
|
302
|
+
return function (node) {
|
|
303
|
+
const attr = fn(node, lhs)
|
|
304
|
+
|
|
305
|
+
if (!cmp) {
|
|
306
|
+
return !!attr
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (cmp.length === 1) {
|
|
310
|
+
return attr === rhs
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (attr === undefined || attr === null) {
|
|
314
|
+
return false
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return checkattr[cmp.charAt(0)](attr, rhs)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function valid_first_child (options) {
|
|
322
|
+
return function (node) {
|
|
323
|
+
return options.children(options.parent(node))[0] === node
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function valid_last_child (options) {
|
|
328
|
+
return function (node) {
|
|
329
|
+
const children = options.children(options.parent(node))
|
|
330
|
+
|
|
331
|
+
return children[children.length - 1] === node
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function valid_empty (options) {
|
|
336
|
+
return function (node) {
|
|
337
|
+
return options.children(node).length === 0
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function valid_root (options) {
|
|
342
|
+
return function (node) {
|
|
343
|
+
return !options.parent(node)
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function valid_contains (options, contents) {
|
|
348
|
+
return function (node) {
|
|
349
|
+
return options.contents(node).indexOf(contents) !== -1
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function valid_nth_child (options, nth) {
|
|
354
|
+
let test = function () {
|
|
355
|
+
return false
|
|
356
|
+
}
|
|
357
|
+
if (nth === 'odd') {
|
|
358
|
+
nth = '2n+1'
|
|
359
|
+
} else if (nth === 'even') {
|
|
360
|
+
nth = '2n'
|
|
361
|
+
}
|
|
362
|
+
const regexp = /( ?([-|+])?(\d*)n)? ?((\+|-)? ?(\d+))? ?/
|
|
363
|
+
const matches = nth.match(regexp)
|
|
364
|
+
if (matches) {
|
|
365
|
+
let growth = 0
|
|
366
|
+
if (matches[1]) {
|
|
367
|
+
const positiveGrowth = matches[2] !== '-'
|
|
368
|
+
growth = parseInt(matches[3] === '' ? 1 : matches[3])
|
|
369
|
+
growth = growth * (positiveGrowth ? 1 : -1)
|
|
370
|
+
}
|
|
371
|
+
let offset = 0
|
|
372
|
+
if (matches[4]) {
|
|
373
|
+
offset = parseInt(matches[6])
|
|
374
|
+
const positiveOffset = matches[5] !== '-'
|
|
375
|
+
offset = offset * (positiveOffset ? 1 : -1)
|
|
376
|
+
}
|
|
377
|
+
if (growth === 0) {
|
|
378
|
+
if (offset !== 0) {
|
|
379
|
+
test = function (children, node) {
|
|
380
|
+
return children[offset - 1] === node
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
} else {
|
|
384
|
+
test = function (children, node) {
|
|
385
|
+
const validPositions = []
|
|
386
|
+
const len = children.length
|
|
387
|
+
for (let position = 1; position <= len; position++) {
|
|
388
|
+
const divisible = (position - offset) % growth === 0
|
|
389
|
+
if (divisible) {
|
|
390
|
+
if (growth > 0) {
|
|
391
|
+
validPositions.push(position)
|
|
392
|
+
} else {
|
|
393
|
+
if ((position - offset) / growth >= 0) {
|
|
394
|
+
validPositions.push(position)
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
for (let i = 0; i < validPositions.length; i++) {
|
|
400
|
+
if (children[validPositions[i] - 1] === node) {
|
|
401
|
+
return true
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return false
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return function (node) {
|
|
409
|
+
const children = options.children(options.parent(node))
|
|
410
|
+
|
|
411
|
+
return test(children, node)
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const checkattr = {
|
|
416
|
+
$: check_end,
|
|
417
|
+
'^': check_beg,
|
|
418
|
+
'*': check_any,
|
|
419
|
+
'~': check_spc,
|
|
420
|
+
'|': check_dsh
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function check_end (l, r) {
|
|
424
|
+
return l.slice(l.length - r.length) === r
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
function check_beg (l, r) {
|
|
428
|
+
return l.slice(0, r.length) === r
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function check_any (l, r) {
|
|
432
|
+
return l.indexOf(r) > -1
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
function check_spc (l, r) {
|
|
436
|
+
return l.split(/\s+/).indexOf(r) > -1
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
function check_dsh (l, r) {
|
|
440
|
+
return l.split('-').indexOf(r) > -1
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function caseSensitiveComparison (type, pattern, data) {
|
|
444
|
+
return pattern === data
|
|
445
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import cssauron from './cssauron'
|
|
2
|
+
|
|
3
|
+
const language = cssauron({
|
|
4
|
+
tag: function (node) {
|
|
5
|
+
return node.nodeType
|
|
6
|
+
},
|
|
7
|
+
class: function (node) {
|
|
8
|
+
return node.data?.class
|
|
9
|
+
},
|
|
10
|
+
id: function (node) {
|
|
11
|
+
return node.data?.id
|
|
12
|
+
},
|
|
13
|
+
children: function (node) {
|
|
14
|
+
return node.children
|
|
15
|
+
},
|
|
16
|
+
parent: function (node) {
|
|
17
|
+
return node.parent
|
|
18
|
+
},
|
|
19
|
+
contents: function (node) {
|
|
20
|
+
return node.contents || ''
|
|
21
|
+
},
|
|
22
|
+
attr: function (node, attr) {
|
|
23
|
+
if (node.properties) {
|
|
24
|
+
const attrs = node.properties.attributes
|
|
25
|
+
if (attrs && attrs[attr]) {
|
|
26
|
+
return attrs[attr]
|
|
27
|
+
}
|
|
28
|
+
return node.properties[attr]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
export default function cssSelect (sel, options) {
|
|
34
|
+
options = options || {}
|
|
35
|
+
const selector = language(sel, options.moduleId)
|
|
36
|
+
function match (vtree) {
|
|
37
|
+
const node = mapTree(vtree, null, options) || {}
|
|
38
|
+
const matched = []
|
|
39
|
+
|
|
40
|
+
// Traverse each node in the tree and see if it matches our selector
|
|
41
|
+
traverse(node, function (node) {
|
|
42
|
+
let result = selector(node)
|
|
43
|
+
if (result) {
|
|
44
|
+
if (!Array.isArray(result)) {
|
|
45
|
+
result = [result]
|
|
46
|
+
}
|
|
47
|
+
matched.push.apply(matched, result)
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const results = mapResult(matched)
|
|
52
|
+
if (results.length === 0) {
|
|
53
|
+
return null
|
|
54
|
+
}
|
|
55
|
+
return results
|
|
56
|
+
}
|
|
57
|
+
match.matches = function (vtree) {
|
|
58
|
+
const node = mapTree(vtree, null, options)
|
|
59
|
+
return !!selector(node)
|
|
60
|
+
}
|
|
61
|
+
return match
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function traverse (vtree, fn) {
|
|
65
|
+
fn(vtree)
|
|
66
|
+
if (vtree.children) {
|
|
67
|
+
vtree.children.forEach(function (vtree) {
|
|
68
|
+
traverse(vtree, fn)
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function mapResult (result) {
|
|
74
|
+
return result
|
|
75
|
+
.filter(function (node) {
|
|
76
|
+
return !!node.vtree
|
|
77
|
+
})
|
|
78
|
+
.map(function (node) {
|
|
79
|
+
return node.vtree
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getNormalizeCaseFn (caseSensitive) {
|
|
84
|
+
return caseSensitive
|
|
85
|
+
? function noop (str) {
|
|
86
|
+
return str
|
|
87
|
+
}
|
|
88
|
+
: function toLowerCase (str) {
|
|
89
|
+
return str.toLowerCase()
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Map a virtual-dom node tree into a data structure that cssauron can use to
|
|
94
|
+
// traverse.
|
|
95
|
+
function mapTree (vtree, parent, options) {
|
|
96
|
+
const normalizeTagCase = getNormalizeCaseFn(options.caseSensitiveTag)
|
|
97
|
+
|
|
98
|
+
if (vtree.nt != null) {
|
|
99
|
+
const node = {}
|
|
100
|
+
node.parent = parent
|
|
101
|
+
node.vtree = vtree
|
|
102
|
+
node.nodeType = normalizeTagCase(vtree.nt)
|
|
103
|
+
if (vtree.d) {
|
|
104
|
+
node.data = vtree.d
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (vtree.c) {
|
|
108
|
+
node.children = vtree.c
|
|
109
|
+
.map(function (child) {
|
|
110
|
+
return mapTree(child, node, options)
|
|
111
|
+
})
|
|
112
|
+
.filter(Boolean)
|
|
113
|
+
}
|
|
114
|
+
return node
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export default function through (onData) {
|
|
2
|
+
let dataCb = null
|
|
3
|
+
|
|
4
|
+
return {
|
|
5
|
+
on: function (name, callback) {
|
|
6
|
+
if (name === 'data') {
|
|
7
|
+
dataCb = callback
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
end: function (data) {
|
|
11
|
+
onData(data)
|
|
12
|
+
},
|
|
13
|
+
queue: function (data) {
|
|
14
|
+
if (dataCb) {
|
|
15
|
+
dataCb(data)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|