@cloudbase/framework-plugin-low-code 0.6.32 → 0.6.35

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.
Files changed (80) hide show
  1. package/lib/builder/config/index.js +2 -5
  2. package/lib/builder/core/copy.d.ts.map +1 -1
  3. package/lib/builder/mp/materials.d.ts.map +1 -1
  4. package/lib/builder/mp/materials.js +30 -5
  5. package/package.json +5 -3
  6. package/template/webpack/web.prod.js +1 -0
  7. package/template/dist/mp/miniprogram_npm/miniprogram-render/bom/cookie.js +0 -286
  8. package/template/dist/mp/miniprogram_npm/miniprogram-render/bom/history.js +0 -133
  9. package/template/dist/mp/miniprogram_npm/miniprogram-render/bom/local-storage.js +0 -103
  10. package/template/dist/mp/miniprogram_npm/miniprogram-render/bom/location.js +0 -588
  11. package/template/dist/mp/miniprogram_npm/miniprogram-render/bom/miniprogram.js +0 -101
  12. package/template/dist/mp/miniprogram_npm/miniprogram-render/bom/navigator.js +0 -80
  13. package/template/dist/mp/miniprogram_npm/miniprogram-render/bom/performance.js +0 -28
  14. package/template/dist/mp/miniprogram_npm/miniprogram-render/bom/screen.js +0 -31
  15. package/template/dist/mp/miniprogram_npm/miniprogram-render/bom/session-storage.js +0 -96
  16. package/template/dist/mp/miniprogram_npm/miniprogram-render/bom/xml-http-request.js +0 -290
  17. package/template/dist/mp/miniprogram_npm/miniprogram-render/document.js +0 -396
  18. package/template/dist/mp/miniprogram_npm/miniprogram-render/event/custom-event.js +0 -12
  19. package/template/dist/mp/miniprogram_npm/miniprogram-render/event/event-target.js +0 -389
  20. package/template/dist/mp/miniprogram_npm/miniprogram-render/event/event.js +0 -186
  21. package/template/dist/mp/miniprogram_npm/miniprogram-render/index.js +0 -41
  22. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/attribute.js +0 -226
  23. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/class-list.js +0 -153
  24. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/comment.js +0 -80
  25. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element/a.js +0 -165
  26. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element/canvas.js +0 -138
  27. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element/image.js +0 -177
  28. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element/input.js +0 -181
  29. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element/not-support.js +0 -60
  30. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element/option.js +0 -126
  31. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element/select.js +0 -155
  32. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element/textarea.js +0 -178
  33. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element/video.js +0 -165
  34. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element/wx-component.js +0 -84
  35. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element/wx-custom-component.js +0 -64
  36. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/element.js +0 -970
  37. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/node.js +0 -140
  38. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/style-list.js +0 -28
  39. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/style.js +0 -158
  40. package/template/dist/mp/miniprogram_npm/miniprogram-render/node/text-node.js +0 -127
  41. package/template/dist/mp/miniprogram_npm/miniprogram-render/tree/parser.js +0 -269
  42. package/template/dist/mp/miniprogram_npm/miniprogram-render/tree/query-selector.js +0 -420
  43. package/template/dist/mp/miniprogram_npm/miniprogram-render/tree/tree.js +0 -130
  44. package/template/dist/mp/miniprogram_npm/miniprogram-render/util/cache.js +0 -95
  45. package/template/dist/mp/miniprogram_npm/miniprogram-render/util/pool.js +0 -24
  46. package/template/dist/mp/miniprogram_npm/miniprogram-render/util/tool.js +0 -131
  47. package/template/dist/mp/miniprogram_npm/miniprogram-render/window.js +0 -651
  48. package/template/generator/app/common.js +0 -17
  49. package/template/generator/app/global-api.js +0 -163
  50. package/template/generator/app/handlers.js +0 -13
  51. package/template/generator/datasources/config.js.tpl +0 -21
  52. package/template/generator/datasources/dataset-profiles.js.tpl +0 -5
  53. package/template/generator/datasources/datasource-profiles.js.tpl +0 -4
  54. package/template/generator/datasources/index.js.tpl +0 -14
  55. package/template/generator/handlers/NodeRenderer.jsx +0 -471
  56. package/template/generator/handlers/RenderWrapper.jsx +0 -145
  57. package/template/generator/index.jsx +0 -116
  58. package/template/generator/index.less +0 -120
  59. package/template/generator/pages/app.tpl +0 -181
  60. package/template/generator/pages/composite.tpl +0 -267
  61. package/template/generator/router/index.tpl +0 -49
  62. package/template/generator/store/computed.js +0 -11
  63. package/template/generator/store/index.js +0 -5
  64. package/template/generator/utils/ScanCodeComponent.js +0 -345
  65. package/template/generator/utils/actionHandler.js +0 -119
  66. package/template/generator/utils/common.js +0 -225
  67. package/template/generator/utils/computed.js +0 -9
  68. package/template/generator/utils/date.js +0 -324
  69. package/template/generator/utils/error.jsx +0 -14
  70. package/template/generator/utils/eventProxy.js +0 -64
  71. package/template/generator/utils/history.js +0 -35
  72. package/template/generator/utils/hooks.js +0 -10
  73. package/template/generator/utils/index.js +0 -41
  74. package/template/generator/utils/initGlobalVar.js +0 -14
  75. package/template/generator/utils/lifecycle.js +0 -158
  76. package/template/generator/utils/monitor-jssdk.min.js +0 -881
  77. package/template/generator/utils/page.js +0 -10
  78. package/template/generator/utils/scan-code-action.js +0 -27
  79. package/template/generator/utils/style.js +0 -81
  80. package/template/generator/utils/widgets.js +0 -343
@@ -1,269 +0,0 @@
1
- /**
2
- * 感谢 John Resig: https://johnresig.com/files/htmlparser.js
3
- */
4
-
5
- // 正则声明
6
- const doctypeReg = /^<!\s*doctype((?:\s+[\w:]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/i
7
- const startTagReg = /^<([-A-Za-z0-9_]+)((?:\s+[-A-Za-z0-9_:@.]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/i
8
- const endTagReg = /^<\/([-A-Za-z0-9_]+)[^>]*>/i
9
- const attrReg = /([-A-Za-z0-9_:@.]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g
10
-
11
- // 空元素 - https://www.w3.org/TR/html/syntax.html#void-elements
12
- const voidMap = {};
13
- ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'].forEach(n => voidMap[n] = true)
14
-
15
- // 块级元素 - https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements#Elements
16
- const blockMap = {};
17
- ['address', 'article', 'aside', 'blockquote', 'canvas', 'dd', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'li', 'main', 'nav', 'noscript', 'ol', 'output', 'p', 'pre', 'section', 'table', 'tfoot', 'ul', 'video'].forEach(n => blockMap[n] = true)
18
-
19
- // 行内元素 - https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements#Elements
20
- const inlineMap = {};
21
- ['a', 'abbr', 'acronym', 'b', 'bdo', 'big', 'br', 'button', 'cite', 'code', 'dfn', 'em', 'i', 'img', 'input', 'kbd', 'label', 'map', 'object', 'q', 'samp', 'script', 'select', 'small', 'span', 'strong', 'sub', 'sup', 'textarea', 'time', 'tt', 'var'].forEach(n => inlineMap[n] = true)
22
-
23
- // 可能包含任意内容的元素 - https://www.w3.org/TR/html/syntax.html#raw-text
24
- const rawTextMap = {};
25
- ['script', 'style'].forEach(n => rawTextMap[n] = true)
26
-
27
- const longAttributeCache = {}
28
- let seed = 0
29
-
30
- /**
31
- * 分词
32
- */
33
- function tokenize(content, handler) {
34
- const stack = []
35
- let last = content
36
-
37
- stack.last = function() {
38
- return this[this.length - 1]
39
- }
40
-
41
- while (content) {
42
- let isText = true
43
-
44
- if (!stack.last() || !rawTextMap[stack.last()]) {
45
- if (content.indexOf('<!--') === 0) {
46
- // comment
47
- const index = content.indexOf('-->')
48
-
49
- if (index >= 0) {
50
- content = content.substring(index + 3)
51
- if (handler.comment) handler.comment(content)
52
- isText = false
53
- }
54
- } else if (content.indexOf('</') === 0) {
55
- // end tag
56
- const match = content.match(endTagReg)
57
-
58
- if (match) {
59
- content = content.substring(match[0].length)
60
- match[0].replace(endTagReg, parseEndTag)
61
- isText = false
62
- }
63
- } else if (content.indexOf('<') === 0) {
64
- // start tag
65
- let match = content.match(startTagReg)
66
-
67
- if (match) {
68
- content = content.substring(match[0].length)
69
- match[0].replace(startTagReg, parseStartTag)
70
- isText = false
71
- } else {
72
- // 检测 doctype
73
- match = content.match(doctypeReg)
74
-
75
- if (match) {
76
- content = content.substring(match[0].length)
77
- isText = false
78
- }
79
- }
80
- }
81
-
82
- if (isText) {
83
- const index = content.indexOf('<')
84
-
85
- const text = index < 0 ? content : content.substring(0, index)
86
- content = index < 0 ? '' : content.substring(index)
87
-
88
- if (handler.text) handler.text(text)
89
- }
90
- } else {
91
- const execRes = (new RegExp(`</${stack.last()}[^>]*>`)).exec(content)
92
-
93
- if (execRes) {
94
- const text = content.substring(0, execRes.index)
95
- content = content.substring(execRes.index + execRes[0].length)
96
-
97
- text.replace(/<!--(.*?)-->/g, '')
98
- if (text && handler.text) handler.text(text)
99
- }
100
-
101
- parseEndTag('', stack.last())
102
- }
103
-
104
- if (content === last) throw new Error(`parse error: ${content}`)
105
- last = content
106
- }
107
-
108
- // 关闭栈内的标签
109
- parseEndTag()
110
-
111
- function parseStartTag(tag, tagName, rest, unary) {
112
- tagName = tagName.toLowerCase()
113
- unary = !!unary
114
-
115
- // 放宽规则,允许行内元素包含块级元素
116
- // if (blockMap[tagName]) {
117
- // while (stack.last() && inlineMap[stack.last()]) {
118
- // // 自动关闭栈内的行内元素
119
- // parseEndTag('', stack.last())
120
- // }
121
- // }
122
-
123
- unary = voidMap[tagName] || !!unary
124
-
125
- if (!unary) stack.push(tagName)
126
-
127
- if (handler.start) {
128
- const attrs = []
129
-
130
- try {
131
- rest.replace(attrReg, (all, $1, $2, $3, $4) => {
132
- const value = $2 || $3 || $4
133
-
134
- attrs.push({
135
- name: $1,
136
- value,
137
- })
138
- })
139
- } catch (err) {
140
- // 某些安卓机遇到过长的字符串执行属性正则替换会跪(主要是 base 64),这里就先临时过滤掉这种特殊情况
141
- rest = rest.replace(/url\([^)]+\)/ig, all => {
142
- const id = `url(:#|${++seed}|#:)`
143
- longAttributeCache[id] = all
144
- return id
145
- })
146
- rest.replace(attrReg, (all, $1, $2, $3, $4) => {
147
- const value = $2 || $3 || $4
148
-
149
- attrs.push({
150
- name: $1,
151
- value: value.replace(/url\(:#\|\d+\|#:\)/ig, all => longAttributeCache[all] || 'url()'),
152
- })
153
- })
154
- }
155
-
156
- handler.start(tagName, attrs, unary)
157
- }
158
- }
159
-
160
- function parseEndTag(tag, tagName) {
161
- let pos
162
-
163
- if (!tagName) {
164
- pos = 0
165
- } else {
166
- // 找到同名的开始标签
167
- tagName = tagName.toLowerCase()
168
-
169
- for (pos = stack.length - 1; pos >= 0; pos--) {
170
- if (stack[pos] === tagName) break
171
- }
172
- }
173
-
174
- if (pos >= 0) {
175
- // 关闭开始标签和结束标签中的所有标签
176
- for (let i = stack.length - 1; i >= pos; i--) {
177
- if (handler.end) handler.end(stack[i])
178
- }
179
-
180
- stack.length = pos
181
- }
182
- }
183
- }
184
-
185
- /**
186
- * 解析
187
- */
188
- function parse(html) {
189
- const r = {
190
- children: [],
191
- }
192
- const stack = [r]
193
-
194
- stack.last = function() {
195
- return this[this.length - 1]
196
- }
197
-
198
- tokenize(html, {
199
- start(tagName, attrs, unary) {
200
- const node = {
201
- type: 'element',
202
- tagName,
203
- attrs,
204
- unary,
205
- children: [],
206
- }
207
-
208
- stack.last().children.push(node)
209
-
210
- if (!unary) {
211
- stack.push(node)
212
- }
213
- },
214
- // eslint-disable-next-line no-unused-vars
215
- end(tagName) {
216
- const node = stack.pop()
217
-
218
- if (node.tagName === 'table') {
219
- // 补充插入 tbody
220
- let hasTbody = false
221
-
222
- for (const child of node.children) {
223
- if (child.tagName === 'tbody') {
224
- hasTbody = true
225
- break
226
- }
227
- }
228
-
229
- if (!hasTbody) {
230
- node.children = [{
231
- type: 'element',
232
- tagName: 'tbody',
233
- attrs: [],
234
- unary: false,
235
- children: node.children,
236
- }]
237
- }
238
- }
239
- },
240
- text(content) {
241
- content = content.trim()
242
- if (!content) return
243
-
244
- stack.last().children.push({
245
- type: 'text',
246
- content,
247
- })
248
- },
249
- comment(content) {
250
- content = content.trim()
251
-
252
- stack.last().children.push({
253
- type: 'comment',
254
- content,
255
- })
256
- },
257
- })
258
-
259
- return r.children
260
- }
261
-
262
- module.exports = {
263
- tokenize,
264
- parse,
265
- voidMap,
266
- blockMap,
267
- inlineMap,
268
- rawTextMap,
269
- }
@@ -1,420 +0,0 @@
1
- /**
2
- * 感谢 sizzle:https://github.com/jquery/sizzle/tree/master
3
- */
4
-
5
- const PSEUDO_CHECK = {
6
- checked: node => node.checked || node.selected,
7
- disabled: node => node.disabled,
8
- enabled: node => !node.disabled,
9
- 'first-child': node => node.parentNode.children[0] === node,
10
- 'last-child': node => node.parentNode.children[node.parentNode.children.length - 1] === node,
11
- 'nth-child': (node, param) => {
12
- const children = node.parentNode.children
13
- const {a, b} = param
14
- const index = children.indexOf(node) + 1
15
-
16
- if (a) {
17
- return (index - b) % a === 0
18
- } else {
19
- return index === b
20
- }
21
- },
22
- }
23
-
24
- const ATTR_CHECK = {
25
- '=': (nodeVal, val) => nodeVal === val,
26
- '~=': (nodeVal, val) => nodeVal.split(/\s+/).indexOf(val) !== -1,
27
- '|=': (nodeVal, val) => nodeVal === val || nodeVal.indexOf(val + '-') === 0,
28
- '^=': (nodeVal, val) => nodeVal.indexOf(val) === 0,
29
- '$=': (nodeVal, val) => nodeVal.substr(nodeVal.length - val.length) === val,
30
- '*=': (nodeVal, val) => nodeVal.indexOf(val) !== -1,
31
- }
32
-
33
- const KINSHIP_CHECK = {
34
- ' ': (node, kinshipRule) => {
35
- let kinshipNode = node.parentNode
36
-
37
- while (kinshipNode) {
38
- if (checkHit(kinshipNode, kinshipRule)) return kinshipNode
39
-
40
- kinshipNode = kinshipNode.parentNode
41
- }
42
-
43
- return null
44
- },
45
- '>': (node, kinshipRule) => {
46
- const kinshipNode = node.parentNode
47
-
48
- return checkHit(kinshipNode, kinshipRule) ? kinshipNode : null
49
- },
50
- '+': (node, kinshipRule) => {
51
- const children = node.parentNode
52
-
53
- for (let i = 0, len = children.length; i < len; i++) {
54
- const child = children[i]
55
-
56
- if (child === node) {
57
- const kinshipNode = children[i - 1]
58
-
59
- return checkHit(kinshipNode, kinshipRule) ? kinshipNode : null
60
- }
61
- }
62
-
63
- return null
64
- },
65
- '~': (node, kinshipRule) => {
66
- const children = node.parentNode
67
- let foundCurrent = false
68
-
69
- for (let i = children.length - 1; i >= 0; i--) {
70
- const child = children[i]
71
-
72
- if (foundCurrent && checkHit(child, kinshipRule)) return child
73
- if (child === node) foundCurrent = true
74
- }
75
-
76
- return null
77
- },
78
- }
79
-
80
- /**
81
- * 检查节点是否符合规则
82
- */
83
- function checkHit(node, rule) {
84
- if (!node) return false
85
-
86
- const {
87
- id, class: classList, tag, pseudo, attr
88
- } = rule
89
-
90
- // id 选择器
91
- if (id) {
92
- if (node.id !== id) return false
93
- }
94
-
95
- // 类选择器
96
- if (classList && classList.length) {
97
- for (const className of classList) {
98
- if (!node.classList || !node.classList.contains(className)) return false
99
- }
100
- }
101
-
102
- // 标签选择器
103
- if (tag && tag !== '*') {
104
- if (node.tagName !== tag.toUpperCase()) return false
105
- }
106
-
107
- // 伪类选择器
108
- if (pseudo) {
109
- for (const {name, param} of pseudo) {
110
- const checkPseudo = PSEUDO_CHECK[name]
111
- if (!checkPseudo || !checkPseudo(node, param)) return false
112
- }
113
- }
114
-
115
- // 属性选择器
116
- if (attr) {
117
- for (const {name, opr, val} of attr) {
118
- const nodeVal = node[name] || node.getAttribute(name)
119
-
120
- if (nodeVal === undefined) return false
121
- if (opr) {
122
- // 存在操作符
123
- const checkAttr = ATTR_CHECK[opr]
124
- if (!checkAttr || !checkAttr(nodeVal, val)) return false
125
- }
126
- }
127
- }
128
-
129
- return true
130
- }
131
-
132
- /**
133
- * 数组去重
134
- */
135
- function unique(list) {
136
- for (let i = 0; i < list.length; i++) {
137
- const a = list[i]
138
-
139
- for (let j = i + 1; j < list.length; j++) {
140
- const b = list[j]
141
- if (a === b) list.splice(j, 1)
142
- }
143
- }
144
-
145
- return list
146
- }
147
-
148
- /**
149
- * 将节点按照文档顺序排列
150
- */
151
- function sortNodes(list) {
152
- list.sort((a, b) => {
153
- const aList = [a]
154
- const bList = [b]
155
- let aParent = a.parentNode
156
- let bParent = b.parentNode
157
-
158
- if (aParent === bParent) {
159
- // 检查顺序
160
- const children = aParent.children
161
- return children.indexOf(a) - children.indexOf(b)
162
- }
163
-
164
- // a 到根的列表
165
- while (aParent) {
166
- aList.unshift(aParent)
167
- aParent = aParent.parentNode
168
- }
169
-
170
- // b 到根的列表
171
- while (bParent) {
172
- bList.unshift(bParent)
173
- bParent = bParent.parentNode
174
- }
175
-
176
- // 找到最近共同祖先
177
- let i = 0
178
- while (aList[i] === bList[i]) i++
179
-
180
- // 检查顺序
181
- const children = aList[i - 1].children
182
- return children.indexOf(aList[i]) - children.indexOf(bList[i])
183
- })
184
-
185
- return list
186
- }
187
-
188
- class QuerySelector {
189
- constructor() {
190
- this.parseCache = {} // 解析查询串缓存
191
- this.parseCacheKeys = []
192
-
193
- const idReg = '#([\\\\\\w-]+)' // id 选择器
194
- const tagReg = '\\*|wx-component|[a-zA-Z-]\\w*' // 标签选择器
195
- const classReg = '\\.([\\\\\\w-]+)' // 类选择器
196
- const pseudoReg = ':([\\\\\\w-]+)(?:\\(([^\\(\\)]*|(?:\\([^\\)]+\\)|[^\\(\\)]*)+)\\))?' // 伪类选择器
197
- const attrReg = '\\[\\s*([\\\\\\w-]+)(?:([*^$|~!]?=)[\'"]?([^\'"\\[]+)[\'"]?)?\\s*\\]' // 属性选择器
198
- const kinshipReg = '\\s*([>\\s+~](?!=))\\s*' // 亲属选择器
199
- this.regexp = new RegExp(`^(?:(${idReg})|(${tagReg})|(${classReg})|(${pseudoReg})|(${attrReg})|(${kinshipReg}))`)
200
- }
201
-
202
- /**
203
- * 存入解析查询串缓存
204
- */
205
- setParseCache(key, value) {
206
- if (this.parseCacheKeys.length > 50) {
207
- delete this.parseCache[this.parseCacheKeys.shift()]
208
- }
209
-
210
- this.parseCacheKeys.push(key)
211
- this.parseCache[key] = value
212
-
213
- return value
214
- }
215
-
216
- /**
217
- * 获取解析查询串缓存
218
- */
219
- getParseCache(key) {
220
- return this.parseCache[key]
221
- }
222
-
223
- /**
224
- * 解析查询串
225
- */
226
- parse(selector) {
227
- const segment = [{tag: '*'}]
228
- const regexp = this.regexp
229
-
230
- const onProcess = (all, idAll, id, tagAll, classAll, className, pseudoAll, pseudoName, pseudoParam, attrAll, attrName, attrOpr, attrVal, kinshipAll, kinship) => {
231
- if (idAll) {
232
- // id 选择器
233
- segment[segment.length - 1].id = id
234
- } else if (tagAll) {
235
- // 标签选择器
236
- segment[segment.length - 1].tag = tagAll.toLowerCase()
237
- } else if (classAll) {
238
- // 类选择器
239
- const currentRule = segment[segment.length - 1]
240
- currentRule.class = currentRule.class || []
241
-
242
- currentRule.class.push(className)
243
- } else if (pseudoAll) {
244
- // 伪类选择器
245
- const currentRule = segment[segment.length - 1]
246
- currentRule.pseudo = currentRule.pseudo || []
247
- pseudoName = pseudoName.toLowerCase()
248
-
249
- const pseudo = {name: pseudoName}
250
-
251
- if (pseudoParam) pseudoParam = pseudoParam.trim()
252
- if (pseudoName === 'nth-child') {
253
- // 处理 nth-child 伪类,参数统一处理成 an + b 的格式
254
- pseudoParam = pseudoParam.replace(/\s+/g, '')
255
-
256
- if (pseudoParam === 'even') {
257
- // 偶数个
258
- pseudoParam = {a: 2, b: 2}
259
- } else if (pseudoParam === 'odd') {
260
- // 奇数个
261
- pseudoParam = {a: 2, b: 1}
262
- } else if (pseudoParam) {
263
- // 其他表达式
264
- const nthParsed = pseudoParam.match(/^(?:(\d+)|(\d*)?n([+-]\d+)?)$/)
265
-
266
- if (!nthParsed) {
267
- // 解析失败
268
- pseudoParam = {a: 0, b: 1}
269
- } else if (nthParsed[1]) {
270
- // 纯数字
271
- pseudoParam = {a: 0, b: +nthParsed[1]}
272
- } else {
273
- // 表达式
274
- pseudoParam = {
275
- a: nthParsed[2] ? +nthParsed[2] : 1,
276
- b: nthParsed[3] ? +nthParsed[3] : 0,
277
- }
278
- }
279
- } else {
280
- // 默认取第一个
281
- pseudoParam = {a: 0, b: 1}
282
- }
283
- }
284
- if (pseudoParam) pseudo.param = pseudoParam
285
-
286
- currentRule.pseudo.push(pseudo)
287
- } else if (attrAll) {
288
- // 属性选择器
289
- const currentRule = segment[segment.length - 1]
290
-
291
- currentRule.attr = currentRule.attr || []
292
- currentRule.attr.push({
293
- name: attrName,
294
- opr: attrOpr,
295
- val: attrVal
296
- })
297
- } else if (kinshipAll) {
298
- // 亲属选择器
299
- segment[segment.length - 1].kinship = kinship
300
- segment.push({tag: '*'}) // 插入新规则
301
- }
302
-
303
- return ''
304
- }
305
-
306
- // 逐个选择器解析
307
- let lastParse
308
- selector = selector.replace(regexp, onProcess)
309
-
310
- while (lastParse !== selector) {
311
- lastParse = selector
312
- selector = selector.replace(regexp, onProcess)
313
- }
314
-
315
- return selector ? '' : segment
316
- }
317
-
318
- /**
319
- * 查询符合条件的节点
320
- */
321
- exec(selector, extra) {
322
- selector = selector.trim().replace(/\s+/g, ' ').replace(/\s*(,|[>\s+~](?!=)|[*^$|~!]?=)\s*/g, '$1')
323
- const {idMap, tagMap, classMap} = extra
324
-
325
- // 查询缓存
326
- let segment = this.getParseCache(selector)
327
-
328
- // 无缓存,进行解析
329
- if (!segment) {
330
- segment = this.parse(selector)
331
-
332
- // 无法正常解析
333
- if (!segment) return []
334
-
335
- this.setParseCache(selector, segment)
336
- }
337
-
338
- // 无解析结果
339
- if (!segment[0]) return []
340
-
341
- // 执行解析结果
342
- const lastRule = segment[segment.length - 1] // 从右往左
343
- const {id, class: classList, tag} = lastRule
344
- let hitNodes = []
345
-
346
- // 寻找可能符合要求的节点
347
- if (id) {
348
- // id 选择器
349
- const node = idMap[id]
350
- hitNodes = node ? [node] : []
351
- } else if (classList && classList.length) {
352
- // 类选择器
353
- for (const className of classList) {
354
- const classNodes = classMap[className]
355
- if (classNodes) {
356
- for (const classNode of classNodes) {
357
- if (hitNodes.indexOf(classNode) === -1) hitNodes.push(classNode)
358
- }
359
- }
360
- }
361
- } else if (tag && tag !== '*') {
362
- // 标签选择器,查询指定标签
363
- const tagName = tag.toUpperCase()
364
- const tagNodes = tagMap[tagName]
365
- if (tagNodes) hitNodes = tagNodes
366
- } else {
367
- // 标签选择器,查询全部节点
368
- Object.keys(tagMap).forEach(key => {
369
- const tagNodes = tagMap[key]
370
- if (tagNodes) {
371
- for (const tagNode of tagNodes) hitNodes.push(tagNode)
372
- }
373
- })
374
- }
375
-
376
- // 从下往上过滤节点列表
377
- if (hitNodes.length && segment.length) {
378
- for (let i = hitNodes.length - 1; i >= 0; i--) {
379
- let checkNode = hitNodes[i]
380
- let isMatched = false
381
-
382
- // 从右往左进行规则过滤
383
- for (let j = segment.length - 1; j >= 0; j--) {
384
- const prevRule = segment[j - 1]
385
-
386
- // 检查待选节点,后续的亲属节点不需要再检查
387
- if (j === segment.length - 1) isMatched = checkHit(checkNode, lastRule)
388
-
389
- if (isMatched && prevRule) {
390
- // 检查亲属选择器
391
- const kinship = prevRule.kinship
392
- const checkKinship = KINSHIP_CHECK[kinship]
393
-
394
- if (checkKinship) checkNode = checkKinship(checkNode, prevRule)
395
-
396
- if (!checkNode) {
397
- // 亲属检查失败
398
- isMatched = false
399
- break
400
- }
401
- } else {
402
- break
403
- }
404
- }
405
-
406
- if (!isMatched) hitNodes.splice(i, 1) // 不符合,从待选节点列表中删除
407
- }
408
- }
409
-
410
- if (hitNodes.length) {
411
- // 去重、排序
412
- hitNodes = unique(hitNodes)
413
- hitNodes = sortNodes(hitNodes)
414
- }
415
-
416
- return hitNodes
417
- }
418
- }
419
-
420
- module.exports = QuerySelector