@mpxjs/webpack-plugin 2.10.3-beta.7 → 2.10.3-beta.9
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/lib/index.js +71 -51
- package/lib/platform/template/wx/component-config/index.js +3 -1
- package/lib/runtime/components/web/mpx-titlebar.vue +243 -0
- package/lib/template-compiler/compiler.js +8 -1
- package/lib/web/processMainScript.js +3 -1
- package/package.json +1 -1
- package/lib/runtime/components/react/dist/mpx-icon/icons/cancel.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/clear.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/download.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/info.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/search.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/success.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/success_no_circle.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/waiting.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/warn.png +0 -0
package/lib/index.js
CHANGED
|
@@ -1806,72 +1806,92 @@ try {
|
|
|
1806
1806
|
normalModuleFactory.hooks.afterResolve.tap('MpxWebpackPlugin', ({ createData }) => {
|
|
1807
1807
|
const { queryObj } = parseRequest(createData.request)
|
|
1808
1808
|
const loaders = createData.loaders
|
|
1809
|
-
|
|
1810
|
-
|
|
1809
|
+
const type = queryObj.type
|
|
1810
|
+
const mpxProcessFlag = queryObj.mpx && queryObj.mpx !== MPX_PROCESSED_FLAG
|
|
1811
|
+
const vueProcessFlag = queryObj.vue && queryObj.mpx !== MPX_PROCESSED_FLAG
|
|
1812
|
+
if (mpxProcessFlag || vueProcessFlag) {
|
|
1811
1813
|
const extract = queryObj.extract
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1814
|
+
if (type === 'styles' || type === 'style') {
|
|
1815
|
+
const loaderTypes = {
|
|
1816
|
+
'node_modules/stylus-loader': -1,
|
|
1817
|
+
'node_modules/sass-loader': -1,
|
|
1818
|
+
'node_modules/less-loader': -1,
|
|
1819
|
+
'node_modules/css-loader': -1
|
|
1820
|
+
}
|
|
1816
1821
|
loaders.forEach((loader, index) => {
|
|
1817
1822
|
const currentLoader = toPosix(loader.loader)
|
|
1818
|
-
|
|
1819
|
-
|
|
1823
|
+
for (const key in loaderTypes) {
|
|
1824
|
+
if (currentLoader.includes(key)) {
|
|
1825
|
+
loaderTypes[key] = index
|
|
1826
|
+
break
|
|
1827
|
+
}
|
|
1820
1828
|
}
|
|
1821
1829
|
})
|
|
1830
|
+
const insertStripLoaders = (index) => {
|
|
1831
|
+
if (index !== -1) {
|
|
1832
|
+
loaders.splice(index, 0, { loader: styleStripConditionalPath, options: {id: 0} })
|
|
1833
|
+
loaders.splice(index + 2, 0, { loader: styleStripConditionalPath, options: {id: 1} })
|
|
1834
|
+
return true
|
|
1835
|
+
}
|
|
1836
|
+
return false
|
|
1837
|
+
}
|
|
1822
1838
|
|
|
1823
|
-
|
|
1824
|
-
|
|
1839
|
+
const priorities = ['node_modules/stylus-loader', 'node_modules/less-loader', 'node_modules/sass-loader', 'node_modules/css-loader']
|
|
1840
|
+
for (const loaderKey of priorities) {
|
|
1841
|
+
if (insertStripLoaders(loaderTypes[loaderKey])) {
|
|
1842
|
+
break
|
|
1843
|
+
}
|
|
1825
1844
|
}
|
|
1826
|
-
loaders.push({ loader: styleStripConditionalPath })
|
|
1827
1845
|
}
|
|
1828
1846
|
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
if (insertBeforeIndex > -1) {
|
|
1844
|
-
loaders.splice(insertBeforeIndex + 1, 0, {
|
|
1845
|
-
loader: info[2]
|
|
1847
|
+
if (mpxProcessFlag) {
|
|
1848
|
+
switch (type) {
|
|
1849
|
+
case 'styles':
|
|
1850
|
+
case 'template': {
|
|
1851
|
+
let insertBeforeIndex = -1
|
|
1852
|
+
const info = typeLoaderProcessInfo[type]
|
|
1853
|
+
loaders.forEach((loader, index) => {
|
|
1854
|
+
const currentLoader = toPosix(loader.loader)
|
|
1855
|
+
if (currentLoader.includes(info[0])) {
|
|
1856
|
+
loader.loader = info[1]
|
|
1857
|
+
insertBeforeIndex = index
|
|
1858
|
+
} else if (currentLoader.includes(info[1])) {
|
|
1859
|
+
insertBeforeIndex = index
|
|
1860
|
+
}
|
|
1846
1861
|
})
|
|
1862
|
+
if (insertBeforeIndex > -1) {
|
|
1863
|
+
loaders.splice(insertBeforeIndex + 1, 0, {
|
|
1864
|
+
loader: info[2]
|
|
1865
|
+
})
|
|
1866
|
+
}
|
|
1867
|
+
break
|
|
1847
1868
|
}
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1869
|
+
case 'json':
|
|
1870
|
+
if (queryObj.isTheme) {
|
|
1871
|
+
loaders.unshift({
|
|
1872
|
+
loader: jsonThemeCompilerPath
|
|
1873
|
+
})
|
|
1874
|
+
} else if (queryObj.isPlugin) {
|
|
1875
|
+
loaders.unshift({
|
|
1876
|
+
loader: jsonPluginCompilerPath
|
|
1877
|
+
})
|
|
1878
|
+
} else {
|
|
1879
|
+
loaders.unshift({
|
|
1880
|
+
loader: jsonCompilerPath
|
|
1881
|
+
})
|
|
1882
|
+
}
|
|
1883
|
+
break
|
|
1884
|
+
case 'wxs':
|
|
1860
1885
|
loaders.unshift({
|
|
1861
|
-
loader:
|
|
1886
|
+
loader: wxsLoaderPath
|
|
1862
1887
|
})
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1888
|
+
break
|
|
1889
|
+
}
|
|
1890
|
+
if (extract) {
|
|
1866
1891
|
loaders.unshift({
|
|
1867
|
-
loader:
|
|
1892
|
+
loader: extractorPath
|
|
1868
1893
|
})
|
|
1869
|
-
|
|
1870
|
-
}
|
|
1871
|
-
if (extract) {
|
|
1872
|
-
loaders.unshift({
|
|
1873
|
-
loader: extractorPath
|
|
1874
|
-
})
|
|
1894
|
+
}
|
|
1875
1895
|
}
|
|
1876
1896
|
createData.resource = addQuery(createData.resource, { mpx: MPX_PROCESSED_FLAG }, true)
|
|
1877
1897
|
}
|
|
@@ -42,6 +42,7 @@ const wxs = require('./wxs')
|
|
|
42
42
|
const component = require('./component')
|
|
43
43
|
const fixComponentName = require('./fix-component-name')
|
|
44
44
|
const rootPortal = require('./root-portal')
|
|
45
|
+
const titlebar = require('./titlebar')
|
|
45
46
|
|
|
46
47
|
module.exports = function getComponentConfigs ({ warn, error }) {
|
|
47
48
|
/**
|
|
@@ -125,6 +126,7 @@ module.exports = function getComponentConfigs ({ warn, error }) {
|
|
|
125
126
|
hyphenTagName({ print }),
|
|
126
127
|
label({ print }),
|
|
127
128
|
component(),
|
|
128
|
-
rootPortal({ print })
|
|
129
|
+
rootPortal({ print }),
|
|
130
|
+
titlebar({ print })
|
|
129
131
|
]
|
|
130
132
|
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import mpx from '@mpxjs/core'
|
|
3
|
+
export default {
|
|
4
|
+
name: 'mpx-titlebar',
|
|
5
|
+
props: {
|
|
6
|
+
// 来自 app.json 中 window 的 titlebar 相关配置
|
|
7
|
+
windowConfig: {
|
|
8
|
+
type: Object,
|
|
9
|
+
default: () => global.__mpxPageConfig
|
|
10
|
+
},
|
|
11
|
+
// 来自 页面 json 中的 titlebar 相关配置,会覆盖 windowConfig
|
|
12
|
+
pageConfig: {
|
|
13
|
+
type: Object,
|
|
14
|
+
default: () => ({})
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
computed: {
|
|
18
|
+
// 合并全局 window 配置与页面配置(页面配置覆盖全局配置)
|
|
19
|
+
cfg () {
|
|
20
|
+
return Object.assign({}, this.windowConfig || {}, this.pageConfig || {})
|
|
21
|
+
},
|
|
22
|
+
// 标题文本(兼容常见字段名)
|
|
23
|
+
titleText () {
|
|
24
|
+
return this.cfg.navigationBarTitleText || this.cfg.title || ''
|
|
25
|
+
},
|
|
26
|
+
// 背景色(兼容常见字段)
|
|
27
|
+
backgroundColor () {
|
|
28
|
+
return this.cfg.navigationBarBackgroundColor || '#ffffff'
|
|
29
|
+
},
|
|
30
|
+
// 文本颜色,微信小程序中 navigationBarTextStyle 为 white 或 black
|
|
31
|
+
textColor () {
|
|
32
|
+
const style = this.cfg.navigationBarTextStyle || 'black'
|
|
33
|
+
return style === 'white' ? '#ffffff' : '#000000'
|
|
34
|
+
},
|
|
35
|
+
// navigationStyle: 'default' | 'custom',custom 表示需要自定义绘制
|
|
36
|
+
navigationStyle () {
|
|
37
|
+
return this.cfg.navigationStyle || 'default'
|
|
38
|
+
},
|
|
39
|
+
// 是否隐藏(navigationStyle 为 'custom' 时也应隐藏)
|
|
40
|
+
hidden () {
|
|
41
|
+
return mpx.config?.webConfig?.enableTitleBar !== true || this.navigationStyle === 'custom'
|
|
42
|
+
},
|
|
43
|
+
// 是否展示返回按钮:根据浏览器历史判断(不依赖额外 page 配置)
|
|
44
|
+
showBack () {
|
|
45
|
+
console.log('showBack', this.$router.stack.length)
|
|
46
|
+
try {
|
|
47
|
+
return this.$router.stack.length > 1
|
|
48
|
+
} catch (e) {
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
// safe area 顶部 padding,使用 env(safe-area-inset-top)
|
|
53
|
+
safeStyle () {
|
|
54
|
+
// 多数浏览器支持 env(), 为兼容也使用 constant() 备选(旧 iOS Safari)
|
|
55
|
+
return {
|
|
56
|
+
paddingTop: 'env(safe-area-inset-top, 0px)'
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
// 内部标题栏高度(遵循小程序常见平台差异)
|
|
60
|
+
innerHeight () {
|
|
61
|
+
const isIOS = /iP(hone|od|ad)/.test(navigator.userAgent)
|
|
62
|
+
return (isIOS ? 44 : 48) + 'px'
|
|
63
|
+
},
|
|
64
|
+
rootStyle () {
|
|
65
|
+
return {
|
|
66
|
+
background: this.backgroundColor,
|
|
67
|
+
color: this.textColor
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
innerStyle () {
|
|
71
|
+
return {
|
|
72
|
+
height: this.innerHeight
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
,
|
|
76
|
+
// content wrapper style: padding-top to avoid being covered by fixed titlebar
|
|
77
|
+
contentStyle () {
|
|
78
|
+
// use calc to combine innerHeight and safe-area inset
|
|
79
|
+
return {
|
|
80
|
+
paddingTop: this.hidden ? '0px' : `calc(${this.innerHeight} + env(safe-area-inset-top, 0px))`,
|
|
81
|
+
// create its own layer to avoid overlapping issues
|
|
82
|
+
transform: 'translateZ(0)',
|
|
83
|
+
willChange: 'transform'
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
methods: {
|
|
88
|
+
// 左侧点击:派发事件并在可回退时回退
|
|
89
|
+
onLeftClick (e) {
|
|
90
|
+
this.$emit('click-left', e)
|
|
91
|
+
if (this.showBack) {
|
|
92
|
+
try { window.history.back() } catch (err) {}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
render (h) {
|
|
97
|
+
const leftChildren = []
|
|
98
|
+
|
|
99
|
+
// default back button (SVG) — no left slot support
|
|
100
|
+
if (this.showBack) {
|
|
101
|
+
leftChildren.push(
|
|
102
|
+
h('button', {
|
|
103
|
+
class: 'mpx-titlebar__back',
|
|
104
|
+
attrs: { 'aria-label': 'back', type: 'button' }
|
|
105
|
+
}, [
|
|
106
|
+
h('svg', {
|
|
107
|
+
attrs: {
|
|
108
|
+
viewBox: '0 0 24 24',
|
|
109
|
+
width: '20',
|
|
110
|
+
height: '20',
|
|
111
|
+
fill: 'none',
|
|
112
|
+
xmlns: 'http://www.w3.org/2000/svg',
|
|
113
|
+
focusable: 'false',
|
|
114
|
+
'aria-hidden': 'true'
|
|
115
|
+
}
|
|
116
|
+
}, [
|
|
117
|
+
h('path', {
|
|
118
|
+
attrs: {
|
|
119
|
+
d: 'M15 18l-6-6 6-6',
|
|
120
|
+
stroke: 'currentColor',
|
|
121
|
+
'stroke-width': '2',
|
|
122
|
+
'stroke-linecap': 'round',
|
|
123
|
+
'stroke-linejoin': 'round'
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
])
|
|
127
|
+
])
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// center shows title; only default slot (page content) is supported
|
|
132
|
+
const centerChildren = [
|
|
133
|
+
h('div', { class: 'mpx-titlebar__title', style: { color: this.textColor } }, [this.titleText])
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
// top-level wrapper: contains fixed titlebar and page content wrapper
|
|
137
|
+
return h('page', { class: 'mpx-titlebar-wrapper' }, [
|
|
138
|
+
// fixed titlebar
|
|
139
|
+
h('div', {
|
|
140
|
+
class: ['mpx-titlebar', { 'mpx-titlebar--hidden': this.hidden }],
|
|
141
|
+
style: this.rootStyle
|
|
142
|
+
}, [
|
|
143
|
+
h('div', { class: 'mpx-titlebar__safe', style: this.safeStyle }, [
|
|
144
|
+
h('div', { class: 'mpx-titlebar__inner', style: this.innerStyle }, [
|
|
145
|
+
h('div', { class: 'mpx-titlebar__left', on: { click: this.onLeftClick } }, leftChildren),
|
|
146
|
+
h('div', { class: 'mpx-titlebar__center' }, centerChildren),
|
|
147
|
+
h('div', { class: 'mpx-titlebar__right' }, [])
|
|
148
|
+
])
|
|
149
|
+
])
|
|
150
|
+
]),
|
|
151
|
+
|
|
152
|
+
// page content wrapper: default slot is page content
|
|
153
|
+
h('div', { class: 'mpx-titlebar__content', style: this.contentStyle }, this.$slots.default || [])
|
|
154
|
+
])
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
</script>
|
|
158
|
+
|
|
159
|
+
<style scoped>
|
|
160
|
+
.mpx-titlebar {
|
|
161
|
+
width: 100%;
|
|
162
|
+
box-sizing: border-box;
|
|
163
|
+
-webkit-font-smoothing: antialiased;
|
|
164
|
+
}
|
|
165
|
+
.mpx-titlebar--hidden {
|
|
166
|
+
display: none;
|
|
167
|
+
}
|
|
168
|
+
.mpx-titlebar__safe {
|
|
169
|
+
/* safe area handled by padding-top; include both env and constant for broader iOS support */
|
|
170
|
+
padding-top: env(safe-area-inset-top, 0px);
|
|
171
|
+
padding-top: constant(safe-area-inset-top, 0px);
|
|
172
|
+
}
|
|
173
|
+
.mpx-titlebar__inner {
|
|
174
|
+
display: flex;
|
|
175
|
+
align-items: center;
|
|
176
|
+
justify-content: space-between;
|
|
177
|
+
padding: 0 12px;
|
|
178
|
+
box-sizing: border-box;
|
|
179
|
+
}
|
|
180
|
+
.mpx-titlebar__left,
|
|
181
|
+
.mpx-titlebar__right {
|
|
182
|
+
flex: 0 0 auto;
|
|
183
|
+
min-width: 44px;
|
|
184
|
+
display: flex;
|
|
185
|
+
align-items: center;
|
|
186
|
+
}
|
|
187
|
+
.mpx-titlebar__center {
|
|
188
|
+
flex: 1 1 auto;
|
|
189
|
+
display: flex;
|
|
190
|
+
align-items: center;
|
|
191
|
+
justify-content: center;
|
|
192
|
+
overflow: hidden;
|
|
193
|
+
padding: 0 8px;
|
|
194
|
+
}
|
|
195
|
+
.mpx-titlebar__title {
|
|
196
|
+
font-size: 17px;
|
|
197
|
+
white-space: nowrap;
|
|
198
|
+
text-overflow: ellipsis;
|
|
199
|
+
overflow: hidden;
|
|
200
|
+
font-weight: 500;
|
|
201
|
+
}
|
|
202
|
+
.mpx-titlebar__back {
|
|
203
|
+
background: none;
|
|
204
|
+
border: none;
|
|
205
|
+
font-size: 20px;
|
|
206
|
+
color: inherit;
|
|
207
|
+
padding: 6px;
|
|
208
|
+
cursor: pointer;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* wrapper and content layout */
|
|
212
|
+
.mpx-titlebar-wrapper {
|
|
213
|
+
position: relative;
|
|
214
|
+
width: 100%;
|
|
215
|
+
height: 100%;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.mpx-titlebar {
|
|
219
|
+
position: fixed;
|
|
220
|
+
top: 0;
|
|
221
|
+
left: 0;
|
|
222
|
+
right: 0;
|
|
223
|
+
z-index: 1000; /* ensure above page content */
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.mpx-titlebar__content {
|
|
227
|
+
position: relative;
|
|
228
|
+
width: 100%;
|
|
229
|
+
min-height: 100%;
|
|
230
|
+
box-sizing: border-box;
|
|
231
|
+
background: transparent;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* SVG icon sizing and inherit color */
|
|
235
|
+
.mpx-titlebar__back svg {
|
|
236
|
+
display: block;
|
|
237
|
+
width: 20px;
|
|
238
|
+
height: 20px;
|
|
239
|
+
}
|
|
240
|
+
.mpx-titlebar__back path {
|
|
241
|
+
stroke: currentColor;
|
|
242
|
+
}
|
|
243
|
+
</style>
|
|
@@ -2476,7 +2476,14 @@ function getVirtualHostRoot (options, meta) {
|
|
|
2476
2476
|
}
|
|
2477
2477
|
}
|
|
2478
2478
|
if (isWeb(mode) && ctorType === 'page') {
|
|
2479
|
-
|
|
2479
|
+
const rootView = createASTElement('mpx-titlebar', [
|
|
2480
|
+
{
|
|
2481
|
+
name: 'pageConfig',
|
|
2482
|
+
value: '{{ this.$options.__mpxPageConfig }}'
|
|
2483
|
+
}
|
|
2484
|
+
])
|
|
2485
|
+
processElement(rootView, rootView, options, meta)
|
|
2486
|
+
return rootView
|
|
2480
2487
|
}
|
|
2481
2488
|
}
|
|
2482
2489
|
return getTempNode()
|
|
@@ -60,7 +60,9 @@ Vue.use(VueRouter)\n`
|
|
|
60
60
|
globalTabBar
|
|
61
61
|
})
|
|
62
62
|
|
|
63
|
-
output += `var App = require(${stringifyRequest(loaderContext, addQuery(loaderContext.resource, { isApp: true }))}).default
|
|
63
|
+
output += `var App = require(${stringifyRequest(loaderContext, addQuery(loaderContext.resource, { isApp: true }))}).default;\n`
|
|
64
|
+
|
|
65
|
+
output += `Vue.component('mpx-titlebar', require(${stringifyRequest(loaderContext, normalize.lib('runtime/components/web/mpx-titlebar.vue'))}).default);\n`
|
|
64
66
|
|
|
65
67
|
output += `
|
|
66
68
|
export default processAppOption({
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|