@mpxjs/webpack-plugin 2.6.114-alpha.0 → 2.6.114-alpha.3
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/README.md +1 -1
- package/lib/platform/template/wx/index.js +7 -0
- package/lib/runtime/components/tenon/getInnerListeners.js +30 -5
- package/lib/runtime/components/tenon/tenon-input.vue +6 -2
- package/lib/runtime/components/tenon/tenon-rich-text.vue +5 -14
- package/lib/runtime/components/tenon/tenon-scroll-view.vue +8 -2
- package/lib/runtime/components/tenon/tenon-text.vue +1 -1
- package/lib/runtime/components/tenon/tenon-view.vue +5 -1
- package/lib/style-compiler/plugins/hm.js +20 -0
- package/package.json +2 -2
- package/lib/runtime/components/tenon/filterTag.js +0 -402
package/README.md
CHANGED
|
@@ -159,6 +159,9 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
159
159
|
},
|
|
160
160
|
web () {
|
|
161
161
|
return false
|
|
162
|
+
},
|
|
163
|
+
tenon () {
|
|
164
|
+
return false
|
|
162
165
|
}
|
|
163
166
|
},
|
|
164
167
|
{
|
|
@@ -234,6 +237,10 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
234
237
|
name: 'mpxModelEvent',
|
|
235
238
|
value: modelEvent
|
|
236
239
|
},
|
|
240
|
+
{
|
|
241
|
+
name: 'mpxModelEventId',
|
|
242
|
+
value: Math.random().toString(36).substr(3, 8)
|
|
243
|
+
},
|
|
237
244
|
{
|
|
238
245
|
name: '@mpxModel',
|
|
239
246
|
value: `__model(${stringifyWithResolveComputed(modelValue)}, $event, ${stringify(modelValuePathArr)}, ${stringify(modelFilter)})`
|
|
@@ -64,6 +64,22 @@ function createTouch (context, hasLongTap, __mpxTapInfo) {
|
|
|
64
64
|
})
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
function processOriginEvent (listeners) {
|
|
68
|
+
// 给event添加_originEvent属性
|
|
69
|
+
const ignoreEvents = ['onTap', 'onFocus', 'onChange', 'onBlur', 'onConfirm']
|
|
70
|
+
Object.keys(listeners).forEach((key) => {
|
|
71
|
+
if (!ignoreEvents.includes(key)) {
|
|
72
|
+
const listener = listeners[key]
|
|
73
|
+
listeners[key] = function (e) {
|
|
74
|
+
if (e) {
|
|
75
|
+
e._originEvent = { ...e }
|
|
76
|
+
}
|
|
77
|
+
listener.call(this, e)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
67
83
|
function processModel (listeners, context) {
|
|
68
84
|
// 该函数只有wx:model的情况下才调用,而且默认e.detail.value有值
|
|
69
85
|
// 该函数必须在产生merge前执行
|
|
@@ -71,11 +87,20 @@ function processModel (listeners, context) {
|
|
|
71
87
|
// todo 访问$listeners也会导致上述现象,但是为了事件代理还必须访问$listeners,待后续思考处理
|
|
72
88
|
|
|
73
89
|
const modelEvent = context.$attrs.mpxModelEvent
|
|
74
|
-
|
|
90
|
+
const modelEventId = context.$attrs.mpxModelEventId
|
|
91
|
+
if (modelEvent && modelEventId) {
|
|
75
92
|
// 对于modelEvent,内部获得时间后向外部转发,触发外部listener的同时转发为mpxModel事件
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
|
|
94
|
+
const listener = listeners['onInput']
|
|
95
|
+
|
|
96
|
+
listeners['onInput'] = function (e) {
|
|
97
|
+
Hummer.notifyCenter.triggerEvent(modelEventId, {
|
|
98
|
+
detail: e
|
|
99
|
+
})
|
|
100
|
+
context.$emit('mpxModel', {
|
|
101
|
+
detail: e
|
|
102
|
+
})
|
|
103
|
+
listener && listener.call(this, e)
|
|
79
104
|
}
|
|
80
105
|
// 内部listener不需要mpxModel
|
|
81
106
|
delete listeners.mpxModel
|
|
@@ -165,7 +190,6 @@ function mergeListeners (listeners, otherListeners, options = {}, context, __mpx
|
|
|
165
190
|
}
|
|
166
191
|
} else {
|
|
167
192
|
rawListener = listeners[key]
|
|
168
|
-
|
|
169
193
|
if (!rawListener) {
|
|
170
194
|
if (options.force) {
|
|
171
195
|
listeners[key] = listener
|
|
@@ -281,6 +305,7 @@ export default function getInnerListeners (context, options = {}) {
|
|
|
281
305
|
mergeAfterOptions.force = mergeAfter.force
|
|
282
306
|
mergeAfter = mergeAfter.listeners
|
|
283
307
|
}
|
|
308
|
+
processOriginEvent(listeners)
|
|
284
309
|
processModel(listeners, context)
|
|
285
310
|
processTouchAndLtap(listeners, context, __mpxTapInfo)
|
|
286
311
|
mergeListeners(listeners, mergeBefore, mergeBeforeOptions, context, __mpxTapInfo)
|
|
@@ -38,6 +38,11 @@ export default {
|
|
|
38
38
|
default: -1,
|
|
39
39
|
},
|
|
40
40
|
},
|
|
41
|
+
computed: {
|
|
42
|
+
originRef() {
|
|
43
|
+
return this.$refs["mpx-input"]
|
|
44
|
+
}
|
|
45
|
+
},
|
|
41
46
|
render() {
|
|
42
47
|
let inputType = "";
|
|
43
48
|
if (this.password) {
|
|
@@ -59,6 +64,7 @@ export default {
|
|
|
59
64
|
class: "mpx-input",
|
|
60
65
|
value: this.value,
|
|
61
66
|
focus: this.focus,
|
|
67
|
+
ref: "mpx-input",
|
|
62
68
|
placeholder: this.placeholder,
|
|
63
69
|
maxLength: this.maxLength,
|
|
64
70
|
type: inputType,
|
|
@@ -85,11 +91,9 @@ export default {
|
|
|
85
91
|
border 0
|
|
86
92
|
font inherit
|
|
87
93
|
display block
|
|
88
|
-
height 1.4rem
|
|
89
94
|
text-overflow clip
|
|
90
95
|
overflow hidden
|
|
91
96
|
white-space nowrap
|
|
92
97
|
font-family UICTFontTextStyleBody
|
|
93
|
-
min-height 1.4rem
|
|
94
98
|
|
|
95
99
|
</style>
|
|
@@ -1,27 +1,18 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { parse, htmlTranStr } from './filterTag.js'
|
|
3
2
|
import getInnerListeners from './getInnerListeners'
|
|
4
3
|
import { h } from '@hummer/tenon-vue'
|
|
5
4
|
export default {
|
|
6
5
|
name: 'mpx-rich-text',
|
|
7
6
|
props: {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
richText: {
|
|
8
|
+
type: Object,
|
|
9
|
+
value: {}
|
|
11
10
|
}
|
|
12
11
|
},
|
|
13
12
|
render () {
|
|
14
|
-
|
|
15
|
-
let html = ''
|
|
16
|
-
if (typeof this.nodes === 'string') {
|
|
17
|
-
nodes = parse(this.nodes)
|
|
18
|
-
}
|
|
19
|
-
if (Array.isArray(nodes)) {
|
|
20
|
-
html = htmlTranStr(nodes, this.space)
|
|
21
|
-
}
|
|
22
|
-
console.log('html--------', html)
|
|
13
|
+
|
|
23
14
|
const data = {
|
|
24
|
-
richText:
|
|
15
|
+
richText: this.richText,
|
|
25
16
|
...getInnerListeners(this)
|
|
26
17
|
}
|
|
27
18
|
return h('text', data)
|
|
@@ -9,6 +9,11 @@ export default {
|
|
|
9
9
|
scrollX: Boolean,
|
|
10
10
|
// 允许纵向滚动
|
|
11
11
|
scrollY: Boolean,
|
|
12
|
+
// 滚动方向
|
|
13
|
+
scrollDirection: {
|
|
14
|
+
type: String,
|
|
15
|
+
default: "horizontal",
|
|
16
|
+
},
|
|
12
17
|
// 距顶部/左边多远时,触发 scrolltoupper 事件
|
|
13
18
|
upperThreshold: {
|
|
14
19
|
type: [Number, String],
|
|
@@ -100,7 +105,7 @@ export default {
|
|
|
100
105
|
},
|
|
101
106
|
methods: {},
|
|
102
107
|
render() {
|
|
103
|
-
let scrollDirection =
|
|
108
|
+
let scrollDirection = this.scrollDirection;
|
|
104
109
|
if (!this.scrollY && this.scrollX) {
|
|
105
110
|
scrollDirection = "horizontal";
|
|
106
111
|
}
|
|
@@ -109,7 +114,8 @@ export default {
|
|
|
109
114
|
{
|
|
110
115
|
ref: "scroll",
|
|
111
116
|
scrollDirection,
|
|
112
|
-
showScrollBar:
|
|
117
|
+
showScrollBar: false,
|
|
118
|
+
...getInnerListeners(this, {})
|
|
113
119
|
},
|
|
114
120
|
this.$slots.default()
|
|
115
121
|
);
|
|
@@ -21,7 +21,7 @@ export default {
|
|
|
21
21
|
render() {
|
|
22
22
|
let text = "";
|
|
23
23
|
let classNames = ["mpx-text"];
|
|
24
|
-
const nodes = this.$slots.default()
|
|
24
|
+
const nodes = this.$slots.default && this.$slots.default() || []
|
|
25
25
|
nodes.forEach((item) => {
|
|
26
26
|
if (item.shapeFlag === 8 && item.children) {
|
|
27
27
|
text += item.children;
|
|
@@ -38,8 +38,9 @@ export default {
|
|
|
38
38
|
{
|
|
39
39
|
class: this.className,
|
|
40
40
|
...getInnerListeners(this, { mergeAfter }),
|
|
41
|
+
ref: "mpx-view"
|
|
41
42
|
},
|
|
42
|
-
this.$slots.default()
|
|
43
|
+
this.$slots.default && this.$slots.default() || ''
|
|
43
44
|
);
|
|
44
45
|
},
|
|
45
46
|
data() {
|
|
@@ -63,6 +64,9 @@ export default {
|
|
|
63
64
|
}
|
|
64
65
|
return result;
|
|
65
66
|
},
|
|
67
|
+
originRef() {
|
|
68
|
+
return this.$refs["mpx-view"]
|
|
69
|
+
}
|
|
66
70
|
},
|
|
67
71
|
pageConfig: {
|
|
68
72
|
canScroll: false,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const postcss = require('postcss')
|
|
2
|
+
const rpxRegExp = /\b(\d+(\.\d+)?)rpx\b/
|
|
3
|
+
const rpxRegExpG = /\b(\d+(\.\d+)?)rpx\b/g
|
|
4
|
+
|
|
5
|
+
module.exports = postcss.plugin('hm', (options = {}) => root => {
|
|
6
|
+
function transHm (declaration) {
|
|
7
|
+
if (rpxRegExp.test(declaration.value)) {
|
|
8
|
+
declaration.value = declaration.value.replace(rpxRegExpG, function (match, $1) {
|
|
9
|
+
if ($1 === '0') return $1
|
|
10
|
+
return `${$1}hm`
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
root.walkRules(rule => {
|
|
16
|
+
rule.walkDecls(declaration => {
|
|
17
|
+
transHm(declaration)
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpxjs/webpack-plugin",
|
|
3
|
-
"version": "2.6.114-alpha.
|
|
3
|
+
"version": "2.6.114-alpha.3",
|
|
4
4
|
"description": "mpx compile core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mpx"
|
|
@@ -85,5 +85,5 @@
|
|
|
85
85
|
"@types/babel-types": "^7.0.4",
|
|
86
86
|
"webpack": "^4.46.0"
|
|
87
87
|
},
|
|
88
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "951dd877934ec6233bfb67452b790dc982317ccd"
|
|
89
89
|
}
|
|
@@ -1,402 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line
|
|
2
|
-
const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/ // useless escape
|
|
3
|
-
const ncname = `[a-zA-Z_][\\w\\-\\.]*`
|
|
4
|
-
const qname = `((?:${ncname}\\:)?${ncname})`
|
|
5
|
-
const startTagOpen = new RegExp(`^<${qname}`)
|
|
6
|
-
const startTagClose = /^\s*(\/?)>/
|
|
7
|
-
const endTag = new RegExp(`^<\\/${qname}[^>]*>`)
|
|
8
|
-
// eslint-disable-next-line
|
|
9
|
-
const comment = /^<!\--/
|
|
10
|
-
// eslint-disable-next-line
|
|
11
|
-
const invalidAttributeRE = /[\s"'<>\/=]/
|
|
12
|
-
// 当前节点的parent
|
|
13
|
-
let currentParent
|
|
14
|
-
|
|
15
|
-
function makeMap (str, expectsLowerCase) {
|
|
16
|
-
const map = Object.create(null)
|
|
17
|
-
const list = str.split(',')
|
|
18
|
-
for (let i = 0; i < list.length; i++) {
|
|
19
|
-
map[list[i]] = true
|
|
20
|
-
}
|
|
21
|
-
return expectsLowerCase
|
|
22
|
-
? val => map[val.toLowerCase()]
|
|
23
|
-
: val => map[val]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const isTenonTag = makeMap('h1,h2,h3,h4,h5,h6,i,small,span,strong,image,a')
|
|
27
|
-
|
|
28
|
-
const isTenonTextTag = makeMap('h1,h2,h3,h4,h5,h6,i,small,span,strong')
|
|
29
|
-
|
|
30
|
-
const isTextAttrs = makeMap('color,backgroundColor,fontFamily,fontSize,fontWeight,fontStyle,textDecoration')
|
|
31
|
-
|
|
32
|
-
const isImageAttrs = makeMap('image,imageWidth,imageHeight,imageAlign')
|
|
33
|
-
|
|
34
|
-
const isAAttrs = makeMap('href,hrefColor')
|
|
35
|
-
|
|
36
|
-
const isUnaryTag = makeMap(
|
|
37
|
-
'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
|
|
38
|
-
'link,meta,param,source,track,wbr'
|
|
39
|
-
)
|
|
40
|
-
// const isSpace = makeMap('ensp,emsp,nbsp')
|
|
41
|
-
|
|
42
|
-
function makeAttrsMap (attrs) {
|
|
43
|
-
const map = {}
|
|
44
|
-
for (let i = 0, l = attrs.length; i < l; i++) {
|
|
45
|
-
map[attrs[i].name] = attrs[i].value
|
|
46
|
-
}
|
|
47
|
-
return map
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function createASTElement (
|
|
51
|
-
tag,
|
|
52
|
-
attrs
|
|
53
|
-
) {
|
|
54
|
-
return {
|
|
55
|
-
name: tag,
|
|
56
|
-
attrs: makeAttrsMap(attrs),
|
|
57
|
-
children: []
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function parseHTML (html, options) {
|
|
62
|
-
const stack = []
|
|
63
|
-
let index = 0
|
|
64
|
-
// let last
|
|
65
|
-
while (html) {
|
|
66
|
-
// last = html
|
|
67
|
-
// Make sure we're not in a plaintext content element like script/style
|
|
68
|
-
// if (!lastTag) {
|
|
69
|
-
let textEnd = html.indexOf('<')
|
|
70
|
-
if (textEnd === 0) {
|
|
71
|
-
// 如果是注释节点
|
|
72
|
-
if (comment.test(html)) {
|
|
73
|
-
const commentEnd = html.indexOf('-->')
|
|
74
|
-
|
|
75
|
-
if (commentEnd >= 0) {
|
|
76
|
-
options.comment(html.substring(4, commentEnd))
|
|
77
|
-
advance(commentEnd + 3)
|
|
78
|
-
continue
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
// 如果是结束标签
|
|
82
|
-
const endTagMatch = html.match(endTag)
|
|
83
|
-
if (endTagMatch) {
|
|
84
|
-
const curIndex = index
|
|
85
|
-
advance(endTagMatch[0].length)
|
|
86
|
-
parseEndTag(endTagMatch[1], curIndex, index)
|
|
87
|
-
continue
|
|
88
|
-
}
|
|
89
|
-
// 如果是开始的开标签
|
|
90
|
-
const start = html.match(startTagOpen)
|
|
91
|
-
if (start) {
|
|
92
|
-
const match = {
|
|
93
|
-
tagName: start[1],
|
|
94
|
-
attrs: [],
|
|
95
|
-
start: index
|
|
96
|
-
}
|
|
97
|
-
advance(start[0].length)
|
|
98
|
-
let end, attr
|
|
99
|
-
while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) {
|
|
100
|
-
attr.start = index
|
|
101
|
-
advance(attr[0].length)
|
|
102
|
-
attr.end = index
|
|
103
|
-
match.attrs.push(attr)
|
|
104
|
-
}
|
|
105
|
-
if (end) {
|
|
106
|
-
match.unarySlash = end[1]
|
|
107
|
-
advance(end[0].length)
|
|
108
|
-
match.end = index
|
|
109
|
-
handleStartTag(match)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
let text, rest, next
|
|
114
|
-
|
|
115
|
-
if (textEnd >= 0) {
|
|
116
|
-
// 获取剩下的部分
|
|
117
|
-
rest = html.slice(textEnd)
|
|
118
|
-
// 当不是结束标签 开始的开标签 注释标签时
|
|
119
|
-
while (
|
|
120
|
-
!endTag.test(rest) &&
|
|
121
|
-
!startTagOpen.test(rest) &&
|
|
122
|
-
!comment.test(rest)
|
|
123
|
-
) {
|
|
124
|
-
// < in plain text, be forgiving and treat it as text
|
|
125
|
-
// 找下一个对应的<
|
|
126
|
-
next = rest.indexOf('<', 1)
|
|
127
|
-
if (next < 0) break
|
|
128
|
-
textEnd += next
|
|
129
|
-
rest = html.slice(textEnd)
|
|
130
|
-
}
|
|
131
|
-
// 将text截取出来 可能是没找到的
|
|
132
|
-
text = html.substring(0, textEnd)
|
|
133
|
-
}
|
|
134
|
-
// 没有找到<
|
|
135
|
-
if (textEnd < 0) {
|
|
136
|
-
text = html
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (text) {
|
|
140
|
-
advance(text.length)
|
|
141
|
-
}
|
|
142
|
-
if (options.chars && text) {
|
|
143
|
-
// 处理字符串
|
|
144
|
-
options.chars(text)
|
|
145
|
-
}
|
|
146
|
-
// }
|
|
147
|
-
}
|
|
148
|
-
parseEndTag()
|
|
149
|
-
function advance (n) {
|
|
150
|
-
index += n
|
|
151
|
-
html = html.substring(n)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function parseEndTag (tagName, start, end) {
|
|
155
|
-
let pos, lowerCasedTagName
|
|
156
|
-
if (start == null) start = index
|
|
157
|
-
if (end == null) end = index
|
|
158
|
-
// Find the closest opened tag of the same type
|
|
159
|
-
if (tagName) {
|
|
160
|
-
lowerCasedTagName = tagName.toLowerCase()
|
|
161
|
-
for (pos = stack.length - 1; pos >= 0; pos--) {
|
|
162
|
-
if (stack[pos].lowerCasedTag === lowerCasedTagName) {
|
|
163
|
-
break
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
} else {
|
|
167
|
-
// If no tag name is provided, clean shop
|
|
168
|
-
pos = 0
|
|
169
|
-
}
|
|
170
|
-
if (pos >= 0) {
|
|
171
|
-
// Close all the open elements, up the stack
|
|
172
|
-
for (let i = stack.length - 1; i >= pos; i--) {
|
|
173
|
-
if (i > pos || !tagName) {
|
|
174
|
-
console.warn(`tag <${stack[i].tag}> has no matching end tag.`,
|
|
175
|
-
{ start: stack[i].start, end: stack[i].end })
|
|
176
|
-
}
|
|
177
|
-
if (options.end) {
|
|
178
|
-
options.end()
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Remove the open elements from the stack
|
|
183
|
-
stack.length = pos
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
function handleStartTag (match) {
|
|
188
|
-
const tagName = match.tagName.toLowerCase()
|
|
189
|
-
const unarySlash = match.unarySlash
|
|
190
|
-
|
|
191
|
-
const unary = isUnaryTag(tagName) || !!unarySlash
|
|
192
|
-
|
|
193
|
-
const l = match.attrs.length
|
|
194
|
-
const attrs = new Array(l)
|
|
195
|
-
for (let i = 0; i < l; i++) {
|
|
196
|
-
const args = match.attrs[i]
|
|
197
|
-
const value = args[3] || args[4] || args[5] || ''
|
|
198
|
-
attrs[i] = {
|
|
199
|
-
name: args[1],
|
|
200
|
-
value: value
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (!unary) {
|
|
205
|
-
stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs, start: match.start, end: match.end })
|
|
206
|
-
// lastTag = tagName
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (options.start) {
|
|
210
|
-
options.start(tagName, attrs, unary)
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
export function parse (template) {
|
|
216
|
-
let nodes = []
|
|
217
|
-
const stack = []
|
|
218
|
-
let root
|
|
219
|
-
function pushChild (currentParent, child) {
|
|
220
|
-
if (currentParent) {
|
|
221
|
-
currentParent.children.push(child)
|
|
222
|
-
} else {
|
|
223
|
-
nodes.push(child)
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
parseHTML(template, {
|
|
227
|
-
start (tag, attrs, unary) {
|
|
228
|
-
let element = createASTElement(tag, attrs, currentParent)
|
|
229
|
-
if (!unary && !stack.length) {
|
|
230
|
-
root = element
|
|
231
|
-
}
|
|
232
|
-
if (!unary) {
|
|
233
|
-
currentParent = element
|
|
234
|
-
stack.push(element)
|
|
235
|
-
} else if (isUnaryTag(tag)) {
|
|
236
|
-
pushChild(currentParent, element)
|
|
237
|
-
}
|
|
238
|
-
attrs.forEach(attr => {
|
|
239
|
-
if (invalidAttributeRE.test(attr.name)) {
|
|
240
|
-
console.warn(`Invalid dynamic argument expression: attribute names cannot contain ` +
|
|
241
|
-
`spaces, quotes, <, >, / or =.`, {
|
|
242
|
-
start: attr.start + attr.name.indexOf(`[`),
|
|
243
|
-
end: attr.start + attr.name.length
|
|
244
|
-
})
|
|
245
|
-
}
|
|
246
|
-
})
|
|
247
|
-
},
|
|
248
|
-
end () {
|
|
249
|
-
const element = stack[stack.length - 1]
|
|
250
|
-
// pop stack
|
|
251
|
-
stack.length -= 1
|
|
252
|
-
currentParent = stack[stack.length - 1]
|
|
253
|
-
currentParent && currentParent.children.push(element)
|
|
254
|
-
if (!stack.length) {
|
|
255
|
-
nodes.push(root)
|
|
256
|
-
}
|
|
257
|
-
},
|
|
258
|
-
chars (text) {
|
|
259
|
-
const child = {
|
|
260
|
-
type: 'text',
|
|
261
|
-
text
|
|
262
|
-
}
|
|
263
|
-
pushChild(currentParent, child)
|
|
264
|
-
},
|
|
265
|
-
comment (text) {
|
|
266
|
-
const child = {
|
|
267
|
-
type: 'comment',
|
|
268
|
-
text
|
|
269
|
-
}
|
|
270
|
-
pushChild(currentParent, child)
|
|
271
|
-
}
|
|
272
|
-
})
|
|
273
|
-
if (stack.length) {
|
|
274
|
-
let last
|
|
275
|
-
for (let i = stack.length - 1; i >= 0; i--) {
|
|
276
|
-
if (last) {
|
|
277
|
-
stack[i].children.push(last)
|
|
278
|
-
}
|
|
279
|
-
last = stack[i]
|
|
280
|
-
}
|
|
281
|
-
nodes.push(last)
|
|
282
|
-
}
|
|
283
|
-
return nodes
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// function spaceTran (str, space) {
|
|
287
|
-
// const sReg = /( | | | ){1}/g
|
|
288
|
-
// const setSpace = `&${space};`
|
|
289
|
-
// return str.replace(sReg, setSpace)
|
|
290
|
-
// }
|
|
291
|
-
function TenonTagCreater (tagName) {
|
|
292
|
-
if (this instanceof TenonTagCreater) {
|
|
293
|
-
return new this[tagName]()
|
|
294
|
-
}
|
|
295
|
-
return new TenonTagCreater(tagName)
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
TenonTagCreater.prototype = {
|
|
299
|
-
h1: function () {
|
|
300
|
-
return {
|
|
301
|
-
fontWeight: 'bold',
|
|
302
|
-
fontSize: 28
|
|
303
|
-
}
|
|
304
|
-
},
|
|
305
|
-
h2: function () {
|
|
306
|
-
return {
|
|
307
|
-
fontWeight: 'bold',
|
|
308
|
-
fontSize: 21
|
|
309
|
-
}
|
|
310
|
-
},
|
|
311
|
-
h3: function () {
|
|
312
|
-
return {
|
|
313
|
-
fontWeight: 'bold',
|
|
314
|
-
fontSize: 16.38
|
|
315
|
-
}
|
|
316
|
-
},
|
|
317
|
-
h4: function () {
|
|
318
|
-
return {
|
|
319
|
-
fontWeight: 'bold'
|
|
320
|
-
}
|
|
321
|
-
},
|
|
322
|
-
h5: function () {
|
|
323
|
-
return {
|
|
324
|
-
fontWeight: 'bold',
|
|
325
|
-
fontSize: 11.62
|
|
326
|
-
}
|
|
327
|
-
},
|
|
328
|
-
h6: function () {
|
|
329
|
-
return {
|
|
330
|
-
fontWeight: 'bold',
|
|
331
|
-
fontSize: 10.5
|
|
332
|
-
}
|
|
333
|
-
},
|
|
334
|
-
i: function () {
|
|
335
|
-
return {
|
|
336
|
-
fontStyle: 'italic'
|
|
337
|
-
}
|
|
338
|
-
},
|
|
339
|
-
small: function () {
|
|
340
|
-
return {
|
|
341
|
-
fontSize: 11.62
|
|
342
|
-
}
|
|
343
|
-
},
|
|
344
|
-
span: function () {
|
|
345
|
-
return {
|
|
346
|
-
|
|
347
|
-
}
|
|
348
|
-
},
|
|
349
|
-
strong: function () {
|
|
350
|
-
return {
|
|
351
|
-
fontWeight: 'bold'
|
|
352
|
-
}
|
|
353
|
-
},
|
|
354
|
-
image: function () {
|
|
355
|
-
return {
|
|
356
|
-
|
|
357
|
-
}
|
|
358
|
-
},
|
|
359
|
-
a: function () {
|
|
360
|
-
return {
|
|
361
|
-
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
export function htmlTranStr (template, space, parentNode) {
|
|
367
|
-
// 只能解析最外层的
|
|
368
|
-
let richTextArray = []
|
|
369
|
-
template.forEach(item => {
|
|
370
|
-
const name = item.name
|
|
371
|
-
|
|
372
|
-
if (item.type === 'text') {
|
|
373
|
-
// hummer不支持 暂时注释
|
|
374
|
-
// parentNode.text = isSpace(space) ? spaceTran(item.text, space) : item.text
|
|
375
|
-
parentNode.text = item.text
|
|
376
|
-
}
|
|
377
|
-
if (item.type === 'comment') {
|
|
378
|
-
console.warn(`the rich-text nonsupport ${item.type} tag`)
|
|
379
|
-
}
|
|
380
|
-
// 改造判断tenon支持的标签 根据默认样式 然后组合设置的样式
|
|
381
|
-
if (name && isTenonTag(name)) {
|
|
382
|
-
let node = new TenonTagCreater(name)
|
|
383
|
-
|
|
384
|
-
if (item.attrs) {
|
|
385
|
-
const attrs = item.attrs
|
|
386
|
-
for (const key in attrs) {
|
|
387
|
-
const isUnEffAttr = (isTenonTextTag(name) && !isTextAttrs(key)) || (name === 'image' && !isImageAttrs(key)) || (name === 'a' && !isAAttrs(key))
|
|
388
|
-
if (isUnEffAttr) {
|
|
389
|
-
console.warn(`This ${key} attribute is not supported for ${name} tags contained in rich-text`)
|
|
390
|
-
} else {
|
|
391
|
-
node[key] = attrs[key]
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
item.children.length && htmlTranStr(item.children, space, node)
|
|
396
|
-
richTextArray.push(node)
|
|
397
|
-
} else {
|
|
398
|
-
console.warn(`the rich-text is not support ${name} tag`)
|
|
399
|
-
}
|
|
400
|
-
})
|
|
401
|
-
return richTextArray
|
|
402
|
-
}
|