From 90ebeb48f7e0375df6ce724c6515e23909d8c5cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=94=90=E6=98=8E=E6=98=8E?= <970899069@qq.com>
Date: Wed, 30 Dec 2020 10:15:22 +0800
Subject: [PATCH 1/5] =?UTF-8?q?[=E6=96=B0=E5=A2=9E]=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89tabbar=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app.js | 5 +-
app.json | 37 ++----------
components/mallIndex_list/mallIndex_list.wxml | 2 +-
components/mallIndex_list/mallIndex_list.wxss | 3 +-
.../mallIndex_video/mallIndex_video.wxml | 4 +-
.../mallIndex_video/mallIndex_video.wxss | 6 +-
components/storeTabBar/storeTabBar.js | 56 +++++++++++++++++
components/storeTabBar/storeTabBar.json | 4 ++
.../storeTabBar/storeTabBar.wxml | 5 +-
.../storeTabBar/storeTabBar.wxss | 6 +-
custom-tab-bar/index.js | 52 ----------------
custom-tab-bar/index.json | 3 -
pages/company/index.js | 7 ++-
pages/config/config.js | 60 ++++++++++++-------
pages/mall/index.js | 7 +++
pages/mall/index.wxml | 4 +-
pages/shortVideo/index.js | 8 +--
pages/shortVideo/index.wxml | 20 +++----
pages/user/index.wxml | 4 +-
pages/welcome/index.js | 2 +-
project.config.json | 4 +-
21 files changed, 151 insertions(+), 148 deletions(-)
create mode 100644 components/storeTabBar/storeTabBar.js
create mode 100644 components/storeTabBar/storeTabBar.json
rename custom-tab-bar/index.wxml => components/storeTabBar/storeTabBar.wxml (50%)
rename custom-tab-bar/index.wxss => components/storeTabBar/storeTabBar.wxss (90%)
delete mode 100644 custom-tab-bar/index.js
delete mode 100644 custom-tab-bar/index.json
diff --git a/app.js b/app.js
index 8abc9c5..820a03e 100644
--- a/app.js
+++ b/app.js
@@ -14,9 +14,9 @@ App({
wx.$qqMap = new QQMapWX({
key: "3TBBZ-O42LU-HXCVQ-2M66A-NCFTT-LMBHU"
})
-
//挂载api方法
wx.$api = apis
+
},
globalData: {
navAppInfo : {
@@ -24,6 +24,7 @@ App({
envVersion : "trial",
goodUrl : "/pages/goods/show?goodsId=",
cardUrl : "/pages/card/index?cardid="
- }
+ },
+ id : 1
}
})
diff --git a/app.json b/app.json
index 7b734bc..e8be1d5 100644
--- a/app.json
+++ b/app.json
@@ -1,8 +1,7 @@
{
"pages": [
- "pages/config/config",
-
"pages/welcome/index",
+ "pages/config/config",
"pages/company/index",
"pages/company/search/search",
"pages/shortVideo/index",
@@ -45,42 +44,14 @@
"pages/home/projectSuccess/projectSuccess",
"pages/home/activeSuccess/activeSuccess"
],
- "tabBar": {
- "list": [{
- "pagePath": "pages/shortVideo/index",
- "text": "视频",
- "iconPath": "/static/tabbar/tabbar_icon_00.png",
- "selectedIconPath": "/static/tabbar/tabbar_icon_show_00.png"
- },
- {
- "pagePath": "pages/mall/index",
- "text": "商城",
- "iconPath": "/static/tabbar/tabbar_icon_01.png",
- "selectedIconPath": "/static/tabbar/tabbar_icon_show_01.png"
- },
- {
- "pagePath": "pages/ticket/index",
- "text": "优惠",
- "iconPath": "/static/tabbar/tabbar_icon_02.png",
- "selectedIconPath": "/static/tabbar/tabbar_icon_show_02.png"
- },
- {
- "pagePath": "pages/user/index",
- "text": "我的",
- "iconPath": "/static/tabbar/tabbar_icon_03.png",
- "selectedIconPath": "/static/tabbar/tabbar_icon_show_03.png"
- }
- ],
- "selectedColor": "#0b0041",
- "color": "#4e4f51",
- "borderStyle": "white",
- "custom": true
- },
"window": {
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "",
"navigationBarTextStyle": "black"
},
+ "usingComponents": {
+ "storeTabBar": "/components/storeTabBar/storeTabBar"
+ },
"plugins": {
"live-player-plugin": {
"version": "1.2.5",
diff --git a/components/mallIndex_list/mallIndex_list.wxml b/components/mallIndex_list/mallIndex_list.wxml
index 800d169..f675b92 100644
--- a/components/mallIndex_list/mallIndex_list.wxml
+++ b/components/mallIndex_list/mallIndex_list.wxml
@@ -7,7 +7,7 @@
-
+
diff --git a/components/mallIndex_list/mallIndex_list.wxss b/components/mallIndex_list/mallIndex_list.wxss
index 3a1f669..3282c70 100644
--- a/components/mallIndex_list/mallIndex_list.wxss
+++ b/components/mallIndex_list/mallIndex_list.wxss
@@ -34,7 +34,7 @@
padding-top: 100%;
}
-.recommend-img image {
+.recommend-img-src {
position: absolute;
width: 100%;
height: 100%;
@@ -65,7 +65,6 @@
.recommend-cost {
font-size: 24rpx;
color: #999;
- /* text-decoration:line-through; */
margin: 2rpx 0 0 20rpx;
}
diff --git a/components/mallIndex_video/mallIndex_video.wxml b/components/mallIndex_video/mallIndex_video.wxml
index 31eb937..0d89044 100644
--- a/components/mallIndex_video/mallIndex_video.wxml
+++ b/components/mallIndex_video/mallIndex_video.wxml
@@ -4,7 +4,7 @@
商品直播间专区
- LIVE
+ LIVE
@@ -16,7 +16,7 @@
- 正在直播
+ 正在直播
diff --git a/components/mallIndex_video/mallIndex_video.wxss b/components/mallIndex_video/mallIndex_video.wxss
index 2a92c42..a426ae4 100644
--- a/components/mallIndex_video/mallIndex_video.wxss
+++ b/components/mallIndex_video/mallIndex_video.wxss
@@ -40,7 +40,7 @@
margin-top: 5rpx;
}
-.videoTitle-name-img image {
+.videoTitle-name-img-img {
width: 34rpx;
height: 34rpx;
margin: 1rpx 6rpx 0 10rpx;
@@ -73,7 +73,7 @@
padding-top: 80%;
}
-.videoList-img .videoList-cover {
+.videoList-cover {
position: absolute;
top: 0;
left: 0;
@@ -96,7 +96,7 @@
box-shadow: 0 0 10rpx rgba(0, 0, 0, .05);
}
-.videoList-tips image {
+.videoList-tips-image {
width: 30rpx;
height: 30rpx;
margin: 8rpx 10rpx 6rpx 0;
diff --git a/components/storeTabBar/storeTabBar.js b/components/storeTabBar/storeTabBar.js
new file mode 100644
index 0000000..e4bb99a
--- /dev/null
+++ b/components/storeTabBar/storeTabBar.js
@@ -0,0 +1,56 @@
+/**
+ * Web唐明明
+ * 匆匆数载恍如梦,岁月迢迢华发增。
+ * 碌碌无为枉半生,一朝惊醒万事空。
+ */
+
+import { tabBar } from "../../lib/storeConfig"
+
+Component({
+ /**
+ * 组件接收参数
+ */
+ properties: {
+ // 显示组件页面的路径
+ pagesUrl : {
+ type : String,
+ value : ""
+ }
+ },
+
+ /**
+ * 组件的初始数据
+ */
+ data: {
+ selected : 0,
+ color : "#4e4f51",
+ selectedColor : "#0b0041",
+ list : []
+ },
+
+ /**
+ * 生命周期函数
+ */
+ pageLifetimes: {
+ show(){
+ let selectedIndex = tabBar.findIndex(val=> val.pagePath == '/' + this.data.pagesUrl)
+ this.setData({
+ list : tabBar,
+ selected: selectedIndex
+ })
+ }
+ },
+
+ /**
+ * 组件的方法列表
+ */
+ methods: {
+ switchTab(e) {
+ const data = e.currentTarget.dataset
+ const url = data.path
+ wx.reLaunch({
+ url
+ })
+ }
+ }
+})
\ No newline at end of file
diff --git a/components/storeTabBar/storeTabBar.json b/components/storeTabBar/storeTabBar.json
new file mode 100644
index 0000000..7e37c03
--- /dev/null
+++ b/components/storeTabBar/storeTabBar.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/custom-tab-bar/index.wxml b/components/storeTabBar/storeTabBar.wxml
similarity index 50%
rename from custom-tab-bar/index.wxml
rename to components/storeTabBar/storeTabBar.wxml
index e54d25a..a8aa312 100644
--- a/custom-tab-bar/index.wxml
+++ b/components/storeTabBar/storeTabBar.wxml
@@ -1,9 +1,8 @@
-
-
- {{item.text}}
+
+ {{item.text}}
diff --git a/custom-tab-bar/index.wxss b/components/storeTabBar/storeTabBar.wxss
similarity index 90%
rename from custom-tab-bar/index.wxss
rename to components/storeTabBar/storeTabBar.wxss
index fe6d9b7..4ffc7f7 100644
--- a/custom-tab-bar/index.wxss
+++ b/components/storeTabBar/storeTabBar.wxss
@@ -5,7 +5,7 @@
* 碌碌无为枉半生,一朝惊醒万事空。
*/
-.tab-bar {
+ .tab-bar {
position: fixed;
bottom: 0;
left: 0;
@@ -34,11 +34,11 @@
flex-direction: column;
}
-.tab-bar-item cover-image {
+.tab-bar-item-icon{
width: 24px;
height: 24px;
}
-.tab-bar-item cover-view {
+.tab-bar-text{
font-size: 10px;
}
diff --git a/custom-tab-bar/index.js b/custom-tab-bar/index.js
deleted file mode 100644
index 49bf6f2..0000000
--- a/custom-tab-bar/index.js
+++ /dev/null
@@ -1,52 +0,0 @@
-
-/**
- * Web唐明明
- * 匆匆数载恍如梦,岁月迢迢华发增。
- * 碌碌无为枉半生,一朝惊醒万事空。
- */
-
-import { tabBar } from "../lib/storeConfig"
-
-Component({
- /**
- * 组件的初始数据
- */
- data: {
- selected : 0,
- color : "#4e4f51",
- selectedColor: "#0b0041",
- list : []
- },
-
- /**
- * 生命周期函数
- */
- attached(){
- if(this.data.list.length <= 0 && tabBar.length > 0){
- this.setData({
- list: tabBar
- })
- }else{
- wx.showToast({
- title: "获取店铺模块信息失败",
- icon : "none"
- })
- }
- },
-
- /**
- * 组件的方法列表
- */
- methods: {
- switchTab(e) {
- const data = e.currentTarget.dataset
- const url = data.path
- wx.switchTab({
- url
- })
- this.setData({
- selected: data.index
- })
- }
- }
-})
\ No newline at end of file
diff --git a/custom-tab-bar/index.json b/custom-tab-bar/index.json
deleted file mode 100644
index fba482a..0000000
--- a/custom-tab-bar/index.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "component": true
-}
\ No newline at end of file
diff --git a/pages/company/index.js b/pages/company/index.js
index cd18f54..8be121a 100644
--- a/pages/company/index.js
+++ b/pages/company/index.js
@@ -66,6 +66,9 @@ Page({
// 存储浏览记录
wx.setStorageSync('companyRecord', record)
+
+ // 存储点击的企业id
+ wx.setStorageSync('compayId', company.company_id)
// 存储店铺ID
wx.setStorage({
@@ -73,8 +76,8 @@ Page({
key : "storeId",
success : res=>{
if(res.errMsg == "setStorage:ok"){
- wx.navigateTo({
- url: "/pages/shortVideo/index",
+ wx.reLaunch({
+ url: "/pages/config/config",
})
}
}
diff --git a/pages/config/config.js b/pages/config/config.js
index a589427..2128690 100644
--- a/pages/config/config.js
+++ b/pages/config/config.js
@@ -18,30 +18,44 @@ Page({
})
return
}
+ wx.getStorage({
+ key : 'compayId',
+ success : res=>{
+
+ wx.$api.publics.storeConfig({
+ company_id: res.data
+ }).then(res => {
+ let tabBarVal = res.concat({})
+ tabBarVal.forEach(res => {
+ switch (res.slug) {
+ case "video":
+ tabBar.push(video)
+ break;
+ case "mall":
+ tabBar.push(mall)
+ break;
+ case "ticket":
+ tabBar.push(ticket)
+ break;
+ default :
+ tabBar.push(user)
+ break;
+ }
+ })
- wx.$api.publics.storeConfig({
- company_id: e.companyoid
- }).then(res => {
- let tabBarVal = res.concat({})
- tabBarVal.forEach(res => {
- switch (res.slug) {
- case "video":
- tabBar.push(video)
- break;
- case "mall":
- tabBar.push(mall)
- break;
- case "ticket":
- tabBar.push(ticket)
- break;
- default :
- tabBar.push(user)
- break;
- }
- })
- wx.switchTab({
- url: tabBar[0].pagePath
- })
+ if(tabBarVal.length == tabBar.length){
+ wx.reLaunch({
+ url: tabBar[0].pagePath,
+ })
+ }
+ })
+ }
})
+ },
+ /**
+ * 生命周期函数
+ */
+ onShow(){
+ wx.hideHomeButton()
}
})
\ No newline at end of file
diff --git a/pages/mall/index.js b/pages/mall/index.js
index 515a489..a81d184 100644
--- a/pages/mall/index.js
+++ b/pages/mall/index.js
@@ -28,6 +28,13 @@ Page({
this.pushInfo();
},
+ /**
+ * 生命周期函数
+ */
+ onShow(){
+ wx.hideHomeButton()
+ },
+
/**
* 商城首页数据
*/
diff --git a/pages/mall/index.wxml b/pages/mall/index.wxml
index 41b791b..c7d8a90 100644
--- a/pages/mall/index.wxml
+++ b/pages/mall/index.wxml
@@ -38,4 +38,6 @@
-
\ No newline at end of file
+
+
+
diff --git a/pages/shortVideo/index.js b/pages/shortVideo/index.js
index 663caa9..694dd31 100644
--- a/pages/shortVideo/index.js
+++ b/pages/shortVideo/index.js
@@ -10,10 +10,10 @@ Page({
* 页面的初始数据
*/
data: {
- videoList: [], //获取短视频列表
- videoIndex: 0, //当前播放视频的下标
- videoId: "", //当前播放的视频id
- playState: true, //视频播放状态
+ videoList : [], //获取短视频列表
+ videoIndex : 0, //当前播放视频的下标
+ videoId : "", //当前播放的视频id
+ playState : true, //视频播放状态
},
/**
diff --git a/pages/shortVideo/index.wxml b/pages/shortVideo/index.wxml
index 4964435..dded866 100644
--- a/pages/shortVideo/index.wxml
+++ b/pages/shortVideo/index.wxml
@@ -1,15 +1,13 @@
-短视频
-短视频
-短视频
-短视频
-短视频
-短视频
-短视频
-短视频
+
进入直播间
-
+
+
+ 改变全局id
+
+
+
-
\ No newline at end of file
+
+
+
diff --git a/pages/user/index.wxml b/pages/user/index.wxml
index 110d4d5..246021c 100644
--- a/pages/user/index.wxml
+++ b/pages/user/index.wxml
@@ -110,4 +110,6 @@
设置
-
\ No newline at end of file
+
+
+
diff --git a/pages/welcome/index.js b/pages/welcome/index.js
index 311733d..4e64271 100644
--- a/pages/welcome/index.js
+++ b/pages/welcome/index.js
@@ -25,7 +25,7 @@ Page({
key : "storeId",
success : ()=>{
wx.reLaunch({
- url: "/pages/shortVideo/index",
+ url: "/pages/config/config",
})
},
fail : ()=>{
diff --git a/project.config.json b/project.config.json
index 803f59b..d54c140 100644
--- a/project.config.json
+++ b/project.config.json
@@ -86,9 +86,9 @@
"scene": null
},
{
- "name": "读取企业配置",
+ "name": "分享进入",
"pathName": "pages/config/config",
- "query": "companyoid=17",
+ "query": "",
"scene": null
}
]
From 3e59b16c27089fad5d2722e1c95aee794ad3e04a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=94=90=E6=98=8E=E6=98=8E?= <970899069@qq.com>
Date: Wed, 30 Dec 2020 10:17:56 +0800
Subject: [PATCH 2/5] =?UTF-8?q?[=E6=96=B0=E5=A2=9E]wxmlToCanvas?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
miniprogram_npm/eventemitter3/index.js | 348 +++++
miniprogram_npm/eventemitter3/index.js.map | 1 +
miniprogram_npm/widget-ui/index.js | 12 +
miniprogram_npm/widget-ui/index.js.map | 1 +
miniprogram_npm/wxml-to-canvas/index.js | 779 +++++++++++
miniprogram_npm/wxml-to-canvas/index.json | 4 +
miniprogram_npm/wxml-to-canvas/index.wxml | 2 +
miniprogram_npm/wxml-to-canvas/index.wxss | 0
miniprogram_npm/wxml-to-canvas/utils.js | 57 +
node_modules/eventemitter3/LICENSE | 21 +
node_modules/eventemitter3/README.md | 94 ++
node_modules/eventemitter3/index.d.ts | 134 ++
node_modules/eventemitter3/index.js | 336 +++++
node_modules/eventemitter3/package.json | 84 ++
.../eventemitter3/umd/eventemitter3.js | 340 +++++
.../eventemitter3/umd/eventemitter3.min.js | 1 +
.../umd/eventemitter3.min.js.map | 1 +
node_modules/widget-ui/babel.config.js | 9 +
node_modules/widget-ui/dist/element.d.ts | 40 +
node_modules/widget-ui/dist/event.d.ts | 5 +
node_modules/widget-ui/dist/index.js | 1 +
node_modules/widget-ui/dist/style.d.ts | 36 +
node_modules/widget-ui/jest.config.js | 6 +
node_modules/widget-ui/package.json | 52 +
node_modules/widget-ui/src/css-layout.js | 1186 +++++++++++++++++
node_modules/widget-ui/src/element.ts | 172 +++
node_modules/widget-ui/src/event.ts | 15 +
node_modules/widget-ui/src/style.ts | 87 ++
.../widget-ui/test/css-layout.test.ts | 183 +++
node_modules/widget-ui/tsconfig.json | 47 +
node_modules/widget-ui/tslint.json | 206 +++
node_modules/widget-ui/webpack.config.js | 25 +
node_modules/wxml-to-canvas/.babelrc | 10 +
node_modules/wxml-to-canvas/.eslintrc.js | 99 ++
node_modules/wxml-to-canvas/LICENSE | 21 +
node_modules/wxml-to-canvas/README.md | 187 +++
node_modules/wxml-to-canvas/gulpfile.js | 26 +
.../wxml-to-canvas/miniprogram_dist/index.js | 779 +++++++++++
.../miniprogram_dist/index.json | 4 +
.../miniprogram_dist/index.wxml | 2 +
.../miniprogram_dist/index.wxss | 0
.../wxml-to-canvas/miniprogram_dist/utils.js | 57 +
node_modules/wxml-to-canvas/package.json | 91 ++
node_modules/wxml-to-canvas/src/draw.js | 225 ++++
node_modules/wxml-to-canvas/src/index.js | 117 ++
node_modules/wxml-to-canvas/src/index.json | 4 +
node_modules/wxml-to-canvas/src/index.wxml | 2 +
node_modules/wxml-to-canvas/src/index.wxss | 0
node_modules/wxml-to-canvas/src/utils.js | 57 +
node_modules/wxml-to-canvas/src/widget.js | 81 ++
node_modules/wxml-to-canvas/src/xml-parser.js | 164 +++
package-lock.json | 21 +
package.json | 3 +-
53 files changed, 6234 insertions(+), 1 deletion(-)
create mode 100644 miniprogram_npm/eventemitter3/index.js
create mode 100644 miniprogram_npm/eventemitter3/index.js.map
create mode 100644 miniprogram_npm/widget-ui/index.js
create mode 100644 miniprogram_npm/widget-ui/index.js.map
create mode 100644 miniprogram_npm/wxml-to-canvas/index.js
create mode 100644 miniprogram_npm/wxml-to-canvas/index.json
create mode 100644 miniprogram_npm/wxml-to-canvas/index.wxml
create mode 100644 miniprogram_npm/wxml-to-canvas/index.wxss
create mode 100644 miniprogram_npm/wxml-to-canvas/utils.js
create mode 100644 node_modules/eventemitter3/LICENSE
create mode 100644 node_modules/eventemitter3/README.md
create mode 100644 node_modules/eventemitter3/index.d.ts
create mode 100644 node_modules/eventemitter3/index.js
create mode 100644 node_modules/eventemitter3/package.json
create mode 100644 node_modules/eventemitter3/umd/eventemitter3.js
create mode 100644 node_modules/eventemitter3/umd/eventemitter3.min.js
create mode 100644 node_modules/eventemitter3/umd/eventemitter3.min.js.map
create mode 100644 node_modules/widget-ui/babel.config.js
create mode 100644 node_modules/widget-ui/dist/element.d.ts
create mode 100644 node_modules/widget-ui/dist/event.d.ts
create mode 100644 node_modules/widget-ui/dist/index.js
create mode 100644 node_modules/widget-ui/dist/style.d.ts
create mode 100644 node_modules/widget-ui/jest.config.js
create mode 100644 node_modules/widget-ui/package.json
create mode 100644 node_modules/widget-ui/src/css-layout.js
create mode 100644 node_modules/widget-ui/src/element.ts
create mode 100644 node_modules/widget-ui/src/event.ts
create mode 100644 node_modules/widget-ui/src/style.ts
create mode 100644 node_modules/widget-ui/test/css-layout.test.ts
create mode 100644 node_modules/widget-ui/tsconfig.json
create mode 100644 node_modules/widget-ui/tslint.json
create mode 100644 node_modules/widget-ui/webpack.config.js
create mode 100644 node_modules/wxml-to-canvas/.babelrc
create mode 100644 node_modules/wxml-to-canvas/.eslintrc.js
create mode 100644 node_modules/wxml-to-canvas/LICENSE
create mode 100644 node_modules/wxml-to-canvas/README.md
create mode 100644 node_modules/wxml-to-canvas/gulpfile.js
create mode 100644 node_modules/wxml-to-canvas/miniprogram_dist/index.js
create mode 100644 node_modules/wxml-to-canvas/miniprogram_dist/index.json
create mode 100644 node_modules/wxml-to-canvas/miniprogram_dist/index.wxml
create mode 100644 node_modules/wxml-to-canvas/miniprogram_dist/index.wxss
create mode 100644 node_modules/wxml-to-canvas/miniprogram_dist/utils.js
create mode 100644 node_modules/wxml-to-canvas/package.json
create mode 100644 node_modules/wxml-to-canvas/src/draw.js
create mode 100644 node_modules/wxml-to-canvas/src/index.js
create mode 100644 node_modules/wxml-to-canvas/src/index.json
create mode 100644 node_modules/wxml-to-canvas/src/index.wxml
create mode 100644 node_modules/wxml-to-canvas/src/index.wxss
create mode 100644 node_modules/wxml-to-canvas/src/utils.js
create mode 100644 node_modules/wxml-to-canvas/src/widget.js
create mode 100644 node_modules/wxml-to-canvas/src/xml-parser.js
diff --git a/miniprogram_npm/eventemitter3/index.js b/miniprogram_npm/eventemitter3/index.js
new file mode 100644
index 0000000..81fe254
--- /dev/null
+++ b/miniprogram_npm/eventemitter3/index.js
@@ -0,0 +1,348 @@
+module.exports = (function() {
+var __MODS__ = {};
+var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; };
+var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; };
+var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } };
+var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; };
+__DEFINE__(1609290924689, function(require, module, exports) {
+
+
+var has = Object.prototype.hasOwnProperty
+ , prefix = '~';
+
+/**
+ * Constructor to create a storage for our `EE` objects.
+ * An `Events` instance is a plain object whose properties are event names.
+ *
+ * @constructor
+ * @private
+ */
+function Events() {}
+
+//
+// We try to not inherit from `Object.prototype`. In some engines creating an
+// instance in this way is faster than calling `Object.create(null)` directly.
+// If `Object.create(null)` is not supported we prefix the event names with a
+// character to make sure that the built-in object properties are not
+// overridden or used as an attack vector.
+//
+if (Object.create) {
+ Events.prototype = Object.create(null);
+
+ //
+ // This hack is needed because the `__proto__` property is still inherited in
+ // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
+ //
+ if (!new Events().__proto__) prefix = false;
+}
+
+/**
+ * Representation of a single event listener.
+ *
+ * @param {Function} fn The listener function.
+ * @param {*} context The context to invoke the listener with.
+ * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
+ * @constructor
+ * @private
+ */
+function EE(fn, context, once) {
+ this.fn = fn;
+ this.context = context;
+ this.once = once || false;
+}
+
+/**
+ * Add a listener for a given event.
+ *
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
+ * @param {(String|Symbol)} event The event name.
+ * @param {Function} fn The listener function.
+ * @param {*} context The context to invoke the listener with.
+ * @param {Boolean} once Specify if the listener is a one-time listener.
+ * @returns {EventEmitter}
+ * @private
+ */
+function addListener(emitter, event, fn, context, once) {
+ if (typeof fn !== 'function') {
+ throw new TypeError('The listener must be a function');
+ }
+
+ var listener = new EE(fn, context || emitter, once)
+ , evt = prefix ? prefix + event : event;
+
+ if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
+ else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
+ else emitter._events[evt] = [emitter._events[evt], listener];
+
+ return emitter;
+}
+
+/**
+ * Clear event by name.
+ *
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
+ * @param {(String|Symbol)} evt The Event name.
+ * @private
+ */
+function clearEvent(emitter, evt) {
+ if (--emitter._eventsCount === 0) emitter._events = new Events();
+ else delete emitter._events[evt];
+}
+
+/**
+ * Minimal `EventEmitter` interface that is molded against the Node.js
+ * `EventEmitter` interface.
+ *
+ * @constructor
+ * @public
+ */
+function EventEmitter() {
+ this._events = new Events();
+ this._eventsCount = 0;
+}
+
+/**
+ * Return an array listing the events for which the emitter has registered
+ * listeners.
+ *
+ * @returns {Array}
+ * @public
+ */
+EventEmitter.prototype.eventNames = function eventNames() {
+ var names = []
+ , events
+ , name;
+
+ if (this._eventsCount === 0) return names;
+
+ for (name in (events = this._events)) {
+ if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
+ }
+
+ if (Object.getOwnPropertySymbols) {
+ return names.concat(Object.getOwnPropertySymbols(events));
+ }
+
+ return names;
+};
+
+/**
+ * Return the listeners registered for a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @returns {Array} The registered listeners.
+ * @public
+ */
+EventEmitter.prototype.listeners = function listeners(event) {
+ var evt = prefix ? prefix + event : event
+ , handlers = this._events[evt];
+
+ if (!handlers) return [];
+ if (handlers.fn) return [handlers.fn];
+
+ for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
+ ee[i] = handlers[i].fn;
+ }
+
+ return ee;
+};
+
+/**
+ * Return the number of listeners listening to a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @returns {Number} The number of listeners.
+ * @public
+ */
+EventEmitter.prototype.listenerCount = function listenerCount(event) {
+ var evt = prefix ? prefix + event : event
+ , listeners = this._events[evt];
+
+ if (!listeners) return 0;
+ if (listeners.fn) return 1;
+ return listeners.length;
+};
+
+/**
+ * Calls each of the listeners registered for a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @returns {Boolean} `true` if the event had listeners, else `false`.
+ * @public
+ */
+EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
+ var evt = prefix ? prefix + event : event;
+
+ if (!this._events[evt]) return false;
+
+ var listeners = this._events[evt]
+ , len = arguments.length
+ , args
+ , i;
+
+ if (listeners.fn) {
+ if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
+
+ switch (len) {
+ case 1: return listeners.fn.call(listeners.context), true;
+ case 2: return listeners.fn.call(listeners.context, a1), true;
+ case 3: return listeners.fn.call(listeners.context, a1, a2), true;
+ case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
+ case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
+ case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
+ }
+
+ for (i = 1, args = new Array(len -1); i < len; i++) {
+ args[i - 1] = arguments[i];
+ }
+
+ listeners.fn.apply(listeners.context, args);
+ } else {
+ var length = listeners.length
+ , j;
+
+ for (i = 0; i < length; i++) {
+ if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
+
+ switch (len) {
+ case 1: listeners[i].fn.call(listeners[i].context); break;
+ case 2: listeners[i].fn.call(listeners[i].context, a1); break;
+ case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
+ case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
+ default:
+ if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
+ args[j - 1] = arguments[j];
+ }
+
+ listeners[i].fn.apply(listeners[i].context, args);
+ }
+ }
+ }
+
+ return true;
+};
+
+/**
+ * Add a listener for a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @param {Function} fn The listener function.
+ * @param {*} [context=this] The context to invoke the listener with.
+ * @returns {EventEmitter} `this`.
+ * @public
+ */
+EventEmitter.prototype.on = function on(event, fn, context) {
+ return addListener(this, event, fn, context, false);
+};
+
+/**
+ * Add a one-time listener for a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @param {Function} fn The listener function.
+ * @param {*} [context=this] The context to invoke the listener with.
+ * @returns {EventEmitter} `this`.
+ * @public
+ */
+EventEmitter.prototype.once = function once(event, fn, context) {
+ return addListener(this, event, fn, context, true);
+};
+
+/**
+ * Remove the listeners of a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @param {Function} fn Only remove the listeners that match this function.
+ * @param {*} context Only remove the listeners that have this context.
+ * @param {Boolean} once Only remove one-time listeners.
+ * @returns {EventEmitter} `this`.
+ * @public
+ */
+EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
+ var evt = prefix ? prefix + event : event;
+
+ if (!this._events[evt]) return this;
+ if (!fn) {
+ clearEvent(this, evt);
+ return this;
+ }
+
+ var listeners = this._events[evt];
+
+ if (listeners.fn) {
+ if (
+ listeners.fn === fn &&
+ (!once || listeners.once) &&
+ (!context || listeners.context === context)
+ ) {
+ clearEvent(this, evt);
+ }
+ } else {
+ for (var i = 0, events = [], length = listeners.length; i < length; i++) {
+ if (
+ listeners[i].fn !== fn ||
+ (once && !listeners[i].once) ||
+ (context && listeners[i].context !== context)
+ ) {
+ events.push(listeners[i]);
+ }
+ }
+
+ //
+ // Reset the array, or remove it completely if we have no more listeners.
+ //
+ if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
+ else clearEvent(this, evt);
+ }
+
+ return this;
+};
+
+/**
+ * Remove all listeners, or those of the specified event.
+ *
+ * @param {(String|Symbol)} [event] The event name.
+ * @returns {EventEmitter} `this`.
+ * @public
+ */
+EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
+ var evt;
+
+ if (event) {
+ evt = prefix ? prefix + event : event;
+ if (this._events[evt]) clearEvent(this, evt);
+ } else {
+ this._events = new Events();
+ this._eventsCount = 0;
+ }
+
+ return this;
+};
+
+//
+// Alias methods names because people roll like that.
+//
+EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
+EventEmitter.prototype.addListener = EventEmitter.prototype.on;
+
+//
+// Expose the prefix.
+//
+EventEmitter.prefixed = prefix;
+
+//
+// Allow `EventEmitter` to be imported as module namespace.
+//
+EventEmitter.EventEmitter = EventEmitter;
+
+//
+// Expose the module.
+//
+if ('undefined' !== typeof module) {
+ module.exports = EventEmitter;
+}
+
+}, function(modId) {var map = {}; return __REQUIRE__(map[modId], modId); })
+return __REQUIRE__(1609290924689);
+})()
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/miniprogram_npm/eventemitter3/index.js.map b/miniprogram_npm/eventemitter3/index.js.map
new file mode 100644
index 0000000..4f2cb7b
--- /dev/null
+++ b/miniprogram_npm/eventemitter3/index.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["index.js"],"names":[],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"index.js","sourcesContent":["\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n"]}
\ No newline at end of file
diff --git a/miniprogram_npm/widget-ui/index.js b/miniprogram_npm/widget-ui/index.js
new file mode 100644
index 0000000..39dd169
--- /dev/null
+++ b/miniprogram_npm/widget-ui/index.js
@@ -0,0 +1,12 @@
+module.exports = (function() {
+var __MODS__ = {};
+var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; };
+var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; };
+var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } };
+var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; };
+__DEFINE__(1609290924690, function(require, module, exports) {
+!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var o=e();for(var r in o)("object"==typeof exports?exports:t)[r]=o[r]}}(this,(function(){return function(t){var e={};function o(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,o),i.l=!0,i.exports}return o.m=t,o.c=e,o.d=function(t,e,r){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)o.d(r,i,function(e){return t[e]}.bind(null,i));return r},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=0)}([function(t,e,o){var r=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(e,"__esModule",{value:!0});var i=r(o(1)),l=o(2),n=0,a=function(){function t(e){var o=this;void 0===e&&(e={}),this.parent=null,this.id=t.uuid(),this.style={},this.computedStyle={},this.lastComputedStyle={},this.children={},this.layoutBox={left:0,top:0,width:0,height:0},e=Object.assign(l.getDefaultStyle(),e),this.computedStyle=Object.assign(l.getDefaultStyle(),e),this.lastComputedStyle=Object.assign(l.getDefaultStyle(),e),Object.keys(e).forEach((function(t){Object.defineProperty(o.style,t,{configurable:!0,enumerable:!0,get:function(){return e[t]},set:function(r){r!==e[t]&&void 0!==r&&(o.lastComputedStyle=o.computedStyle[t],e[t]=r,o.computedStyle[t]=r,l.scalableStyles.includes(t)&&o.style.scale&&(o.computedStyle[t]=r*o.style.scale),"scale"===t&&l.scalableStyles.forEach((function(t){e[t]&&(o.computedStyle[t]=e[t]*r)})),"hidden"===t&&(r?l.layoutAffectedStyles.forEach((function(t){o.computedStyle[t]=0})):l.layoutAffectedStyles.forEach((function(t){o.computedStyle[t]=o.lastComputedStyle[t]}))))}})})),this.style.scale&&l.scalableStyles.forEach((function(t){if(o.style[t]){var e=o.style[t]*o.style.scale;o.computedStyle[t]=e}})),e.hidden&&l.layoutAffectedStyles.forEach((function(t){o.computedStyle[t]=0}))}return t.uuid=function(){return n++},t.prototype.getAbsolutePosition=function(t){if(!t)return this.getAbsolutePosition(this);if(!t.parent)return{left:0,top:0};var e=this.getAbsolutePosition(t.parent),o=e.left,r=e.top;return{left:o+t.layoutBox.left,top:r+t.layoutBox.top}},t.prototype.add=function(t){t.parent=this,this.children[t.id]=t},t.prototype.remove=function(t){var e=this;t?this.children[t.id]&&(t.remove(),delete this.children[t.id]):Object.keys(this.children).forEach((function(t){e.children[t].remove(),delete e.children[t]}))},t.prototype.getNodeTree=function(){var t=this;return{id:this.id,style:this.computedStyle,children:Object.keys(this.children).map((function(e){return t.children[e].getNodeTree()}))}},t.prototype.applyLayout=function(t){var e=this;["left","top","width","height"].forEach((function(o){t.layout&&"number"==typeof t.layout[o]&&(e.layoutBox[o]=t.layout[o],!e.parent||"left"!==o&&"top"!==o||(e.layoutBox[o]+=e.parent.layoutBox[o]))})),t.children.forEach((function(t){e.children[t.id].applyLayout(t)}))},t.prototype.layout=function(){var t=this.getNodeTree();i.default(t),this.applyLayout(t)},t}();e.default=a},function(t,e,o){o.r(e);var r=function(){var t,e="inherit",o="ltr",r="rtl",i="row",l="row-reverse",n="column",a="column-reverse",u="flex-start",d="center",s="flex-end",y="space-between",c="space-around",f="flex-start",h="center",p="flex-end",g="stretch",v="relative",m="absolute",b={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},x={row:"right","row-reverse":"left",column:"bottom","column-reverse":"top"},w={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},S={row:"width","row-reverse":"width",column:"height","column-reverse":"height"};function W(t){return void 0===t}function L(t){return t===i||t===l}function k(t,e){if(void 0!==t.style.marginStart&&L(e))return t.style.marginStart;var o=null;switch(e){case"row":o=t.style.marginLeft;break;case"row-reverse":o=t.style.marginRight;break;case"column":o=t.style.marginTop;break;case"column-reverse":o=t.style.marginBottom}return void 0!==o?o:void 0!==t.style.margin?t.style.margin:0}function j(t,e){if(void 0!==t.style.marginEnd&&L(e))return t.style.marginEnd;var o=null;switch(e){case"row":o=t.style.marginRight;break;case"row-reverse":o=t.style.marginLeft;break;case"column":o=t.style.marginBottom;break;case"column-reverse":o=t.style.marginTop}return null!=o?o:void 0!==t.style.margin?t.style.margin:0}function B(t,e){if(void 0!==t.style.borderStartWidth&&t.style.borderStartWidth>=0&&L(e))return t.style.borderStartWidth;var o=null;switch(e){case"row":o=t.style.borderLeftWidth;break;case"row-reverse":o=t.style.borderRightWidth;break;case"column":o=t.style.borderTopWidth;break;case"column-reverse":o=t.style.borderBottomWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function E(t,e){if(void 0!==t.style.borderEndWidth&&t.style.borderEndWidth>=0&&L(e))return t.style.borderEndWidth;var o=null;switch(e){case"row":o=t.style.borderRightWidth;break;case"row-reverse":o=t.style.borderLeftWidth;break;case"column":o=t.style.borderBottomWidth;break;case"column-reverse":o=t.style.borderTopWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function C(t,e){return function(t,e){if(void 0!==t.style.paddingStart&&t.style.paddingStart>=0&&L(e))return t.style.paddingStart;var o=null;switch(e){case"row":o=t.style.paddingLeft;break;case"row-reverse":o=t.style.paddingRight;break;case"column":o=t.style.paddingTop;break;case"column-reverse":o=t.style.paddingBottom}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+B(t,e)}function T(t,e){return function(t,e){if(void 0!==t.style.paddingEnd&&t.style.paddingEnd>=0&&L(e))return t.style.paddingEnd;var o=null;switch(e){case"row":o=t.style.paddingRight;break;case"row-reverse":o=t.style.paddingLeft;break;case"column":o=t.style.paddingBottom;break;case"column-reverse":o=t.style.paddingTop}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+E(t,e)}function O(t,e){return B(t,e)+E(t,e)}function _(t,e){return k(t,e)+j(t,e)}function R(t,e){return C(t,e)+T(t,e)}function A(t,e){return e.style.alignSelf?e.style.alignSelf:t.style.alignItems?t.style.alignItems:"stretch"}function P(t,e){if(e===r){if(t===i)return l;if(t===l)return i}return t}function D(t,e){return function(t){return t===n||t===a}(t)?P(i,e):n}function H(t){return t.style.position?t.style.position:"relative"}function M(t){return H(t)===v&&t.style.flex>0}function I(t,e){return t.layout[S[e]]+_(t,e)}function N(t,e){return void 0!==t.style[S[e]]&&t.style[S[e]]>=0}function F(t,e){return void 0!==t.style[e]}function q(t,e){return void 0!==t.style[e]?t.style[e]:0}function z(t,e,o){var r={row:t.style.minWidth,"row-reverse":t.style.minWidth,column:t.style.minHeight,"column-reverse":t.style.minHeight}[e],i={row:t.style.maxWidth,"row-reverse":t.style.maxWidth,column:t.style.maxHeight,"column-reverse":t.style.maxHeight}[e],l=o;return void 0!==i&&i>=0&&l>i&&(l=i),void 0!==r&&r>=0&&le?t:e}function G(t,e){void 0===t.layout[S[e]]&&N(t,e)&&(t.layout[S[e]]=U(z(t,e,t.style[S[e]]),R(t,e)))}function J(t,e,o){e.layout[x[o]]=t.layout[S[o]]-e.layout[S[o]]-e.layout[w[o]]}function K(t,e){return void 0!==t.style[b[e]]?q(t,b[e]):-q(t,x[e])}function Q(r,E,Q){var X=function(t,r){var i;return(i=t.style.direction?t.style.direction:e)===e&&(i=void 0===r?o:r),i}(r,Q),Y=P(function(t){return t.style.flexDirection?t.style.flexDirection:n}(r),X),Z=D(Y,X),$=P(i,X);G(r,Y),G(r,Z),r.layout.direction=X,r.layout[b[Y]]+=k(r,Y)+K(r,Y),r.layout[x[Y]]+=j(r,Y)+K(r,Y),r.layout[b[Z]]+=k(r,Z)+K(r,Z),r.layout[x[Z]]+=j(r,Z)+K(r,Z);var tt=r.children.length,et=R(r,$);if(function(t){return void 0!==t.style.measure}(r)){var ot=!W(r.layout[S[$]]),rt=t;rt=N(r,$)?r.style.width:ot?r.layout[S[$]]:E-_(r,$),rt-=et;var it=!N(r,$)&&!ot,lt=!N(r,n)&&W(r.layout[S[n]]);if(it||lt){var nt=r.style.measure(rt);it&&(r.layout.width=nt.width+et),lt&&(r.layout.height=nt.height+R(r,n))}if(0===tt)return}var at,ut,dt,st,yt=function(t){return"wrap"===t.style.flexWrap}(r),ct=function(t){return t.style.justifyContent?t.style.justifyContent:"flex-start"}(r),ft=C(r,Y),ht=C(r,Z),pt=R(r,Y),gt=R(r,Z),vt=!W(r.layout[S[Y]]),mt=!W(r.layout[S[Z]]),bt=L(Y),xt=null,wt=null,St=t;vt&&(St=r.layout[S[Y]]-pt);for(var Wt=0,Lt=0,kt=0,jt=0,Bt=0,Et=0;LtSt&&at!==Wt){Rt--,kt=1;break}At&&(H(dt)!==v||M(dt))&&(At=!1,Pt=at),Dt&&(H(dt)!==v||Xt!==g&&Xt!==f||W(dt.layout[S[Z]]))&&(Dt=!1,Ht=at),At&&(dt.layout[w[Y]]+=Nt,vt&&J(r,dt,Y),Nt+=I(dt,Y),Ft=U(Ft,z(dt,Z,I(dt,Z)))),Dt&&(dt.layout[w[Z]]+=jt+ht,mt&&J(r,dt,Z)),kt=0,Tt+=qt,Lt=at+1}var zt=0,Ut=0,Gt=0;if(Gt=vt?St-Tt:U(Tt,0)-Tt,0!==Ot){var Jt,Kt,Qt=Gt/_t;for(It=Mt;null!==It;)(Jt=Qt*It.style.flex+R(It,Y))!==(Kt=z(It,Y,Jt))&&(Gt-=Kt,_t-=It.style.flex),It=It.nextFlexChild;for((Qt=Gt/_t)<0&&(Qt=0),It=Mt;null!==It;)It.layout[S[Y]]=z(It,Y,Qt*It.style.flex+R(It,Y)),Ct=t,N(r,$)?Ct=r.layout[S[$]]-et:bt||(Ct=E-_(r,$)-et),V(It,Ct,X),dt=It,It=It.nextFlexChild,dt.nextFlexChild=null}else ct!==u&&(ct===d?zt=Gt/2:ct===s?zt=Gt:ct===y?(Gt=U(Gt,0),Ut=Ot+Rt-1!=0?Gt/(Ot+Rt-1):0):ct===c&&(zt=(Ut=Gt/(Ot+Rt))/2));for(Nt+=zt,at=Pt;at1&&mt){var $t=r.layout[S[Z]]-gt,te=$t-jt,ee=0,oe=ht,re=function(t){return t.style.alignContent?t.style.alignContent:"flex-start"}(r);re===p?oe+=te:re===h?oe+=te/2:re===g&&$t>jt&&(ee=te/Et);var ie=0;for(at=0;at=0&&L(e))return t.style.borderStartWidth;var o=null;switch(e){case\"row\":o=t.style.borderLeftWidth;break;case\"row-reverse\":o=t.style.borderRightWidth;break;case\"column\":o=t.style.borderTopWidth;break;case\"column-reverse\":o=t.style.borderBottomWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function E(t,e){if(void 0!==t.style.borderEndWidth&&t.style.borderEndWidth>=0&&L(e))return t.style.borderEndWidth;var o=null;switch(e){case\"row\":o=t.style.borderRightWidth;break;case\"row-reverse\":o=t.style.borderLeftWidth;break;case\"column\":o=t.style.borderBottomWidth;break;case\"column-reverse\":o=t.style.borderTopWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function C(t,e){return function(t,e){if(void 0!==t.style.paddingStart&&t.style.paddingStart>=0&&L(e))return t.style.paddingStart;var o=null;switch(e){case\"row\":o=t.style.paddingLeft;break;case\"row-reverse\":o=t.style.paddingRight;break;case\"column\":o=t.style.paddingTop;break;case\"column-reverse\":o=t.style.paddingBottom}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+B(t,e)}function T(t,e){return function(t,e){if(void 0!==t.style.paddingEnd&&t.style.paddingEnd>=0&&L(e))return t.style.paddingEnd;var o=null;switch(e){case\"row\":o=t.style.paddingRight;break;case\"row-reverse\":o=t.style.paddingLeft;break;case\"column\":o=t.style.paddingBottom;break;case\"column-reverse\":o=t.style.paddingTop}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+E(t,e)}function O(t,e){return B(t,e)+E(t,e)}function _(t,e){return k(t,e)+j(t,e)}function R(t,e){return C(t,e)+T(t,e)}function A(t,e){return e.style.alignSelf?e.style.alignSelf:t.style.alignItems?t.style.alignItems:\"stretch\"}function P(t,e){if(e===r){if(t===i)return l;if(t===l)return i}return t}function D(t,e){return function(t){return t===n||t===a}(t)?P(i,e):n}function H(t){return t.style.position?t.style.position:\"relative\"}function M(t){return H(t)===v&&t.style.flex>0}function I(t,e){return t.layout[S[e]]+_(t,e)}function N(t,e){return void 0!==t.style[S[e]]&&t.style[S[e]]>=0}function F(t,e){return void 0!==t.style[e]}function q(t,e){return void 0!==t.style[e]?t.style[e]:0}function z(t,e,o){var r={row:t.style.minWidth,\"row-reverse\":t.style.minWidth,column:t.style.minHeight,\"column-reverse\":t.style.minHeight}[e],i={row:t.style.maxWidth,\"row-reverse\":t.style.maxWidth,column:t.style.maxHeight,\"column-reverse\":t.style.maxHeight}[e],l=o;return void 0!==i&&i>=0&&l>i&&(l=i),void 0!==r&&r>=0&&le?t:e}function G(t,e){void 0===t.layout[S[e]]&&N(t,e)&&(t.layout[S[e]]=U(z(t,e,t.style[S[e]]),R(t,e)))}function J(t,e,o){e.layout[x[o]]=t.layout[S[o]]-e.layout[S[o]]-e.layout[w[o]]}function K(t,e){return void 0!==t.style[b[e]]?q(t,b[e]):-q(t,x[e])}function Q(r,E,Q){var X=function(t,r){var i;return(i=t.style.direction?t.style.direction:e)===e&&(i=void 0===r?o:r),i}(r,Q),Y=P(function(t){return t.style.flexDirection?t.style.flexDirection:n}(r),X),Z=D(Y,X),$=P(i,X);G(r,Y),G(r,Z),r.layout.direction=X,r.layout[b[Y]]+=k(r,Y)+K(r,Y),r.layout[x[Y]]+=j(r,Y)+K(r,Y),r.layout[b[Z]]+=k(r,Z)+K(r,Z),r.layout[x[Z]]+=j(r,Z)+K(r,Z);var tt=r.children.length,et=R(r,$);if(function(t){return void 0!==t.style.measure}(r)){var ot=!W(r.layout[S[$]]),rt=t;rt=N(r,$)?r.style.width:ot?r.layout[S[$]]:E-_(r,$),rt-=et;var it=!N(r,$)&&!ot,lt=!N(r,n)&&W(r.layout[S[n]]);if(it||lt){var nt=r.style.measure(rt);it&&(r.layout.width=nt.width+et),lt&&(r.layout.height=nt.height+R(r,n))}if(0===tt)return}var at,ut,dt,st,yt=function(t){return\"wrap\"===t.style.flexWrap}(r),ct=function(t){return t.style.justifyContent?t.style.justifyContent:\"flex-start\"}(r),ft=C(r,Y),ht=C(r,Z),pt=R(r,Y),gt=R(r,Z),vt=!W(r.layout[S[Y]]),mt=!W(r.layout[S[Z]]),bt=L(Y),xt=null,wt=null,St=t;vt&&(St=r.layout[S[Y]]-pt);for(var Wt=0,Lt=0,kt=0,jt=0,Bt=0,Et=0;LtSt&&at!==Wt){Rt--,kt=1;break}At&&(H(dt)!==v||M(dt))&&(At=!1,Pt=at),Dt&&(H(dt)!==v||Xt!==g&&Xt!==f||W(dt.layout[S[Z]]))&&(Dt=!1,Ht=at),At&&(dt.layout[w[Y]]+=Nt,vt&&J(r,dt,Y),Nt+=I(dt,Y),Ft=U(Ft,z(dt,Z,I(dt,Z)))),Dt&&(dt.layout[w[Z]]+=jt+ht,mt&&J(r,dt,Z)),kt=0,Tt+=qt,Lt=at+1}var zt=0,Ut=0,Gt=0;if(Gt=vt?St-Tt:U(Tt,0)-Tt,0!==Ot){var Jt,Kt,Qt=Gt/_t;for(It=Mt;null!==It;)(Jt=Qt*It.style.flex+R(It,Y))!==(Kt=z(It,Y,Jt))&&(Gt-=Kt,_t-=It.style.flex),It=It.nextFlexChild;for((Qt=Gt/_t)<0&&(Qt=0),It=Mt;null!==It;)It.layout[S[Y]]=z(It,Y,Qt*It.style.flex+R(It,Y)),Ct=t,N(r,$)?Ct=r.layout[S[$]]-et:bt||(Ct=E-_(r,$)-et),V(It,Ct,X),dt=It,It=It.nextFlexChild,dt.nextFlexChild=null}else ct!==u&&(ct===d?zt=Gt/2:ct===s?zt=Gt:ct===y?(Gt=U(Gt,0),Ut=Ot+Rt-1!=0?Gt/(Ot+Rt-1):0):ct===c&&(zt=(Ut=Gt/(Ot+Rt))/2));for(Nt+=zt,at=Pt;at1&&mt){var $t=r.layout[S[Z]]-gt,te=$t-jt,ee=0,oe=ht,re=function(t){return t.style.alignContent?t.style.alignContent:\"flex-start\"}(r);re===p?oe+=te:re===h?oe+=te/2:re===g&&$t>jt&&(ee=te/Et);var ie=0;for(at=0;at {
+ let result = null
+
+ if (/^#/.test(color) && (color.length === 7 || color.length === 9)) {
+ return color
+ // eslint-disable-next-line no-cond-assign
+ } else if ((result = /^(rgb|rgba)\((.+)\)/.exec(color)) !== null) {
+ return '#' + result[2].split(',').map((part, index) => {
+ part = part.trim()
+ part = index === 3 ? Math.floor(parseFloat(part) * 255) : parseInt(part, 10)
+ part = part.toString(16)
+ if (part.length === 1) {
+ part = '0' + part
+ }
+ return part
+ }).join('')
+ } else {
+ return '#00000000'
+ }
+}
+
+const splitLineToCamelCase = (str) => str.split('-').map((part, index) => {
+ if (index === 0) {
+ return part
+ }
+ return part[0].toUpperCase() + part.slice(1)
+}).join('')
+
+const compareVersion = (v1, v2) => {
+ v1 = v1.split('.')
+ v2 = v2.split('.')
+ const len = Math.max(v1.length, v2.length)
+ while (v1.length < len) {
+ v1.push('0')
+ }
+ while (v2.length < len) {
+ v2.push('0')
+ }
+ for (let i = 0; i < len; i++) {
+ const num1 = parseInt(v1[i], 10)
+ const num2 = parseInt(v2[i], 10)
+
+ if (num1 > num2) {
+ return 1
+ } else if (num1 < num2) {
+ return -1
+ }
+ }
+
+ return 0
+}
+
+module.exports = {
+ hex,
+ splitLineToCamelCase,
+ compareVersion
+}
+
+
+/***/ }),
+/* 1 */
+/***/ (function(module, exports, __webpack_require__) {
+
+
+const xmlParse = __webpack_require__(2)
+const {Widget} = __webpack_require__(3)
+const {Draw} = __webpack_require__(5)
+const {compareVersion} = __webpack_require__(0)
+
+const canvasId = 'weui-canvas'
+
+Component({
+ properties: {
+ width: {
+ type: Number,
+ value: 400
+ },
+ height: {
+ type: Number,
+ value: 300
+ }
+ },
+ data: {
+ use2dCanvas: false, // 2.9.2 后可用canvas 2d 接口
+ },
+ lifetimes: {
+ attached() {
+ const {SDKVersion, pixelRatio: dpr} = wx.getSystemInfoSync()
+ const use2dCanvas = compareVersion(SDKVersion, '2.9.2') >= 0
+ this.dpr = dpr
+ this.setData({use2dCanvas}, () => {
+ if (use2dCanvas) {
+ const query = this.createSelectorQuery()
+ query.select(`#${canvasId}`)
+ .fields({node: true, size: true})
+ .exec(res => {
+ const canvas = res[0].node
+ const ctx = canvas.getContext('2d')
+ canvas.width = res[0].width * dpr
+ canvas.height = res[0].height * dpr
+ ctx.scale(dpr, dpr)
+ this.ctx = ctx
+ this.canvas = canvas
+ })
+ } else {
+ this.ctx = wx.createCanvasContext(canvasId, this)
+ }
+ })
+ }
+ },
+ methods: {
+ async renderToCanvas(args) {
+ const {wxml, style} = args
+ const ctx = this.ctx
+ const canvas = this.canvas
+ const use2dCanvas = this.data.use2dCanvas
+
+ if (use2dCanvas && !canvas) {
+ return Promise.reject(new Error('renderToCanvas: fail canvas has not been created'))
+ }
+
+ ctx.clearRect(0, 0, this.data.width, this.data.height)
+ const {root: xom} = xmlParse(wxml)
+
+ const widget = new Widget(xom, style)
+ const container = widget.init()
+ this.boundary = {
+ top: container.layoutBox.top,
+ left: container.layoutBox.left,
+ width: container.computedStyle.width,
+ height: container.computedStyle.height,
+ }
+ const draw = new Draw(ctx, canvas, use2dCanvas)
+ await draw.drawNode(container)
+
+ if (!use2dCanvas) {
+ await this.canvasDraw(ctx)
+ }
+ return Promise.resolve(container)
+ },
+
+ canvasDraw(ctx, reserve) {
+ return new Promise(resolve => {
+ ctx.draw(reserve, () => {
+ resolve()
+ })
+ })
+ },
+
+ canvasToTempFilePath(args = {}) {
+ const use2dCanvas = this.data.use2dCanvas
+
+ return new Promise((resolve, reject) => {
+ const {
+ top, left, width, height
+ } = this.boundary
+
+ const copyArgs = {
+ x: left,
+ y: top,
+ width,
+ height,
+ destWidth: width * this.dpr,
+ destHeight: height * this.dpr,
+ canvasId,
+ fileType: args.fileType || 'png',
+ quality: args.quality || 1,
+ success: resolve,
+ fail: reject
+ }
+
+ if (use2dCanvas) {
+ delete copyArgs.canvasId
+ copyArgs.canvas = this.canvas
+ }
+ wx.canvasToTempFilePath(copyArgs, this)
+ })
+ }
+ }
+})
+
+
+/***/ }),
+/* 2 */
+/***/ (function(module, exports) {
+
+
+/**
+ * Module dependencies.
+ */
+
+
+/**
+ * Expose `parse`.
+ */
+
+
+/**
+ * Parse the given string of `xml`.
+ *
+ * @param {String} xml
+ * @return {Object}
+ * @api public
+ */
+
+function parse(xml) {
+ xml = xml.trim()
+
+ // strip comments
+ xml = xml.replace(//g, '')
+
+ return document()
+
+ /**
+ * XML document.
+ */
+
+ function document() {
+ return {
+ declaration: declaration(),
+ root: tag()
+ }
+ }
+
+ /**
+ * Declaration.
+ */
+
+ function declaration() {
+ const m = match(/^<\?xml\s*/)
+ if (!m) return
+
+ // tag
+ const node = {
+ attributes: {}
+ }
+
+ // attributes
+ while (!(eos() || is('?>'))) {
+ const attr = attribute()
+ if (!attr) return node
+ node.attributes[attr.name] = attr.value
+ }
+
+ match(/\?>\s*/)
+
+ return node
+ }
+
+ /**
+ * Tag.
+ */
+
+ function tag() {
+ const m = match(/^<([\w-:.]+)\s*/)
+ if (!m) return
+
+ // name
+ const node = {
+ name: m[1],
+ attributes: {},
+ children: []
+ }
+
+ // attributes
+ while (!(eos() || is('>') || is('?>') || is('/>'))) {
+ const attr = attribute()
+ if (!attr) return node
+ node.attributes[attr.name] = attr.value
+ }
+
+ // self closing tag
+ if (match(/^\s*\/>\s*/)) {
+ return node
+ }
+
+ match(/\??>\s*/)
+
+ // content
+ node.content = content()
+
+ // children
+ let child
+ while (child = tag()) {
+ node.children.push(child)
+ }
+
+ // closing
+ match(/^<\/[\w-:.]+>\s*/)
+
+ return node
+ }
+
+ /**
+ * Text content.
+ */
+
+ function content() {
+ const m = match(/^([^<]*)/)
+ if (m) return m[1]
+ return ''
+ }
+
+ /**
+ * Attribute.
+ */
+
+ function attribute() {
+ const m = match(/([\w:-]+)\s*=\s*("[^"]*"|'[^']*'|\w+)\s*/)
+ if (!m) return
+ return {name: m[1], value: strip(m[2])}
+ }
+
+ /**
+ * Strip quotes from `val`.
+ */
+
+ function strip(val) {
+ return val.replace(/^['"]|['"]$/g, '')
+ }
+
+ /**
+ * Match `re` and advance the string.
+ */
+
+ function match(re) {
+ const m = xml.match(re)
+ if (!m) return
+ xml = xml.slice(m[0].length)
+ return m
+ }
+
+ /**
+ * End-of-source.
+ */
+
+ function eos() {
+ return xml.length == 0
+ }
+
+ /**
+ * Check for `prefix`.
+ */
+
+ function is(prefix) {
+ return xml.indexOf(prefix) == 0
+ }
+}
+
+module.exports = parse
+
+
+/***/ }),
+/* 3 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Block = __webpack_require__(4)
+const {splitLineToCamelCase} = __webpack_require__(0)
+
+class Element extends Block {
+ constructor(prop) {
+ super(prop.style)
+ this.name = prop.name
+ this.attributes = prop.attributes
+ }
+}
+
+
+class Widget {
+ constructor(xom, style) {
+ this.xom = xom
+ this.style = style
+
+ this.inheritProps = ['fontSize', 'lineHeight', 'textAlign', 'verticalAlign', 'color']
+ }
+
+ init() {
+ this.container = this.create(this.xom)
+ this.container.layout()
+
+ this.inheritStyle(this.container)
+ return this.container
+ }
+
+ // 继承父节点的样式
+ inheritStyle(node) {
+ const parent = node.parent || null
+ const children = node.children || {}
+ const computedStyle = node.computedStyle
+
+ if (parent) {
+ this.inheritProps.forEach(prop => {
+ computedStyle[prop] = computedStyle[prop] || parent.computedStyle[prop]
+ })
+ }
+
+ Object.values(children).forEach(child => {
+ this.inheritStyle(child)
+ })
+ }
+
+ create(node) {
+ let classNames = (node.attributes.class || '').split(' ')
+ classNames = classNames.map(item => splitLineToCamelCase(item.trim()))
+ const style = {}
+ classNames.forEach(item => {
+ Object.assign(style, this.style[item] || {})
+ })
+
+ const args = {name: node.name, style}
+
+ const attrs = Object.keys(node.attributes)
+ const attributes = {}
+ for (const attr of attrs) {
+ const value = node.attributes[attr]
+ const CamelAttr = splitLineToCamelCase(attr)
+
+ if (value === '' || value === 'true') {
+ attributes[CamelAttr] = true
+ } else if (value === 'false') {
+ attributes[CamelAttr] = false
+ } else {
+ attributes[CamelAttr] = value
+ }
+ }
+ attributes.text = node.content
+ args.attributes = attributes
+ const element = new Element(args)
+ node.children.forEach(childNode => {
+ const childElement = this.create(childNode)
+ element.add(childElement)
+ })
+ return element
+ }
+}
+
+module.exports = {Widget}
+
+
+/***/ }),
+/* 4 */
+/***/ (function(module, exports) {
+
+module.exports = require("widget-ui");
+
+/***/ }),
+/* 5 */
+/***/ (function(module, exports) {
+
+class Draw {
+ constructor(context, canvas, use2dCanvas = false) {
+ this.ctx = context
+ this.canvas = canvas || null
+ this.use2dCanvas = use2dCanvas
+ }
+
+ roundRect(x, y, w, h, r, fill = true, stroke = false) {
+ if (r < 0) return
+ const ctx = this.ctx
+
+ ctx.beginPath()
+ ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 3 / 2)
+ ctx.arc(x + w - r, y + r, r, Math.PI * 3 / 2, 0)
+ ctx.arc(x + w - r, y + h - r, r, 0, Math.PI / 2)
+ ctx.arc(x + r, y + h - r, r, Math.PI / 2, Math.PI)
+ ctx.lineTo(x, y + r)
+ if (stroke) ctx.stroke()
+ if (fill) ctx.fill()
+ }
+
+ drawView(box, style) {
+ const ctx = this.ctx
+ const {
+ left: x, top: y, width: w, height: h
+ } = box
+ const {
+ borderRadius = 0,
+ borderWidth = 0,
+ borderColor,
+ color = '#000',
+ backgroundColor = 'transparent',
+ } = style
+ ctx.save()
+ // 外环
+ if (borderWidth > 0) {
+ ctx.fillStyle = borderColor || color
+ this.roundRect(x, y, w, h, borderRadius)
+ }
+
+ // 内环
+ ctx.fillStyle = backgroundColor
+ const innerWidth = w - 2 * borderWidth
+ const innerHeight = h - 2 * borderWidth
+ const innerRadius = borderRadius - borderWidth >= 0 ? borderRadius - borderWidth : 0
+ this.roundRect(x + borderWidth, y + borderWidth, innerWidth, innerHeight, innerRadius)
+ ctx.restore()
+ }
+
+ async drawImage(img, box, style) {
+ await new Promise((resolve, reject) => {
+ const ctx = this.ctx
+ const canvas = this.canvas
+
+ const {
+ borderRadius = 0
+ } = style
+ const {
+ left: x, top: y, width: w, height: h
+ } = box
+ ctx.save()
+ this.roundRect(x, y, w, h, borderRadius, false, false)
+ ctx.clip()
+
+ const _drawImage = (img) => {
+ if (this.use2dCanvas) {
+ const Image = canvas.createImage()
+ Image.onload = () => {
+ ctx.drawImage(Image, x, y, w, h)
+ ctx.restore()
+ resolve()
+ }
+ Image.onerror = () => { reject(new Error(`createImage fail: ${img}`)) }
+ Image.src = img
+ } else {
+ ctx.drawImage(img, x, y, w, h)
+ ctx.restore()
+ resolve()
+ }
+ }
+
+ const isTempFile = /^wxfile:\/\//.test(img)
+ const isNetworkFile = /^https?:\/\//.test(img)
+
+ if (isTempFile) {
+ _drawImage(img)
+ } else if (isNetworkFile) {
+ wx.downloadFile({
+ url: img,
+ success(res) {
+ if (res.statusCode === 200) {
+ _drawImage(res.tempFilePath)
+ } else {
+ reject(new Error(`downloadFile:fail ${img}`))
+ }
+ },
+ fail() {
+ reject(new Error(`downloadFile:fail ${img}`))
+ }
+ })
+ } else {
+ reject(new Error(`image format error: ${img}`))
+ }
+ })
+ }
+
+ // eslint-disable-next-line complexity
+ drawText(text, box, style) {
+ const ctx = this.ctx
+ let {
+ left: x, top: y, width: w, height: h
+ } = box
+ let {
+ color = '#000',
+ lineHeight = '1.4em',
+ fontSize = 14,
+ textAlign = 'left',
+ verticalAlign = 'top',
+ backgroundColor = 'transparent'
+ } = style
+
+ if (typeof lineHeight === 'string') { // 2em
+ lineHeight = Math.ceil(parseFloat(lineHeight.replace('em')) * fontSize)
+ }
+ if (!text || (lineHeight > h)) return
+
+ ctx.save()
+ ctx.textBaseline = 'top'
+ ctx.font = `${fontSize}px sans-serif`
+ ctx.textAlign = textAlign
+
+ // 背景色
+ ctx.fillStyle = backgroundColor
+ this.roundRect(x, y, w, h, 0)
+
+ // 文字颜色
+ ctx.fillStyle = color
+
+ // 水平布局
+ switch (textAlign) {
+ case 'left':
+ break
+ case 'center':
+ x += 0.5 * w
+ break
+ case 'right':
+ x += w
+ break
+ default: break
+ }
+
+ const textWidth = ctx.measureText(text).width
+ const actualHeight = Math.ceil(textWidth / w) * lineHeight
+ let paddingTop = Math.ceil((h - actualHeight) / 2)
+ if (paddingTop < 0) paddingTop = 0
+
+ // 垂直布局
+ switch (verticalAlign) {
+ case 'top':
+ break
+ case 'middle':
+ y += paddingTop
+ break
+ case 'bottom':
+ y += 2 * paddingTop
+ break
+ default: break
+ }
+
+ const inlinePaddingTop = Math.ceil((lineHeight - fontSize) / 2)
+
+ // 不超过一行
+ if (textWidth <= w) {
+ ctx.fillText(text, x, y + inlinePaddingTop)
+ return
+ }
+
+ // 多行文本
+ const chars = text.split('')
+ const _y = y
+
+ // 逐行绘制
+ let line = ''
+ for (const ch of chars) {
+ const testLine = line + ch
+ const testWidth = ctx.measureText(testLine).width
+
+ if (testWidth > w) {
+ ctx.fillText(line, x, y + inlinePaddingTop)
+ y += lineHeight
+ line = ch
+ if ((y + lineHeight) > (_y + h)) break
+ } else {
+ line = testLine
+ }
+ }
+
+ // 避免溢出
+ if ((y + lineHeight) <= (_y + h)) {
+ ctx.fillText(line, x, y + inlinePaddingTop)
+ }
+ ctx.restore()
+ }
+
+ async drawNode(element) {
+ const {layoutBox, computedStyle, name} = element
+ const {src, text} = element.attributes
+ if (name === 'view') {
+ this.drawView(layoutBox, computedStyle)
+ } else if (name === 'image') {
+ await this.drawImage(src, layoutBox, computedStyle)
+ } else if (name === 'text') {
+ this.drawText(text, layoutBox, computedStyle)
+ }
+ const childs = Object.values(element.children)
+ for (const child of childs) {
+ await this.drawNode(child)
+ }
+ }
+}
+
+
+module.exports = {
+ Draw
+}
+
+
+/***/ })
+/******/ ]);
+});
\ No newline at end of file
diff --git a/miniprogram_npm/wxml-to-canvas/index.json b/miniprogram_npm/wxml-to-canvas/index.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/miniprogram_npm/wxml-to-canvas/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/miniprogram_npm/wxml-to-canvas/index.wxml b/miniprogram_npm/wxml-to-canvas/index.wxml
new file mode 100644
index 0000000..a0010ad
--- /dev/null
+++ b/miniprogram_npm/wxml-to-canvas/index.wxml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/miniprogram_npm/wxml-to-canvas/index.wxss b/miniprogram_npm/wxml-to-canvas/index.wxss
new file mode 100644
index 0000000..e69de29
diff --git a/miniprogram_npm/wxml-to-canvas/utils.js b/miniprogram_npm/wxml-to-canvas/utils.js
new file mode 100644
index 0000000..c3cf7d7
--- /dev/null
+++ b/miniprogram_npm/wxml-to-canvas/utils.js
@@ -0,0 +1,57 @@
+const hex = (color) => {
+ let result = null
+
+ if (/^#/.test(color) && (color.length === 7 || color.length === 9)) {
+ return color
+ // eslint-disable-next-line no-cond-assign
+ } else if ((result = /^(rgb|rgba)\((.+)\)/.exec(color)) !== null) {
+ return '#' + result[2].split(',').map((part, index) => {
+ part = part.trim()
+ part = index === 3 ? Math.floor(parseFloat(part) * 255) : parseInt(part, 10)
+ part = part.toString(16)
+ if (part.length === 1) {
+ part = '0' + part
+ }
+ return part
+ }).join('')
+ } else {
+ return '#00000000'
+ }
+}
+
+const splitLineToCamelCase = (str) => str.split('-').map((part, index) => {
+ if (index === 0) {
+ return part
+ }
+ return part[0].toUpperCase() + part.slice(1)
+}).join('')
+
+const compareVersion = (v1, v2) => {
+ v1 = v1.split('.')
+ v2 = v2.split('.')
+ const len = Math.max(v1.length, v2.length)
+ while (v1.length < len) {
+ v1.push('0')
+ }
+ while (v2.length < len) {
+ v2.push('0')
+ }
+ for (let i = 0; i < len; i++) {
+ const num1 = parseInt(v1[i], 10)
+ const num2 = parseInt(v2[i], 10)
+
+ if (num1 > num2) {
+ return 1
+ } else if (num1 < num2) {
+ return -1
+ }
+ }
+
+ return 0
+}
+
+module.exports = {
+ hex,
+ splitLineToCamelCase,
+ compareVersion
+}
diff --git a/node_modules/eventemitter3/LICENSE b/node_modules/eventemitter3/LICENSE
new file mode 100644
index 0000000..abcbd54
--- /dev/null
+++ b/node_modules/eventemitter3/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Arnout Kazemier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/node_modules/eventemitter3/README.md b/node_modules/eventemitter3/README.md
new file mode 100644
index 0000000..aba7e18
--- /dev/null
+++ b/node_modules/eventemitter3/README.md
@@ -0,0 +1,94 @@
+# EventEmitter3
+
+[](https://www.npmjs.com/package/eventemitter3)[](https://travis-ci.org/primus/eventemitter3)[](https://david-dm.org/primus/eventemitter3)[](https://coveralls.io/r/primus/eventemitter3?branch=master)[](https://webchat.freenode.net/?channels=primus)
+
+[](https://saucelabs.com/u/eventemitter3)
+
+EventEmitter3 is a high performance EventEmitter. It has been micro-optimized
+for various of code paths making this, one of, if not the fastest EventEmitter
+available for Node.js and browsers. The module is API compatible with the
+EventEmitter that ships by default with Node.js but there are some slight
+differences:
+
+- Domain support has been removed.
+- We do not `throw` an error when you emit an `error` event and nobody is
+ listening.
+- The `newListener` and `removeListener` events have been removed as they
+ are useful only in some uncommon use-cases.
+- The `setMaxListeners`, `getMaxListeners`, `prependListener` and
+ `prependOnceListener` methods are not available.
+- Support for custom context for events so there is no need to use `fn.bind`.
+- The `removeListener` method removes all matching listeners, not only the
+ first.
+
+It's a drop in replacement for existing EventEmitters, but just faster. Free
+performance, who wouldn't want that? The EventEmitter is written in EcmaScript 3
+so it will work in the oldest browsers and node versions that you need to
+support.
+
+## Installation
+
+```bash
+$ npm install --save eventemitter3
+```
+
+## CDN
+
+Recommended CDN:
+
+```text
+https://unpkg.com/eventemitter3@latest/umd/eventemitter3.min.js
+```
+
+## Usage
+
+After installation the only thing you need to do is require the module:
+
+```js
+var EventEmitter = require('eventemitter3');
+```
+
+And you're ready to create your own EventEmitter instances. For the API
+documentation, please follow the official Node.js documentation:
+
+http://nodejs.org/api/events.html
+
+### Contextual emits
+
+We've upgraded the API of the `EventEmitter.on`, `EventEmitter.once` and
+`EventEmitter.removeListener` to accept an extra argument which is the `context`
+or `this` value that should be set for the emitted events. This means you no
+longer have the overhead of an event that required `fn.bind` in order to get a
+custom `this` value.
+
+```js
+var EE = new EventEmitter()
+ , context = { foo: 'bar' };
+
+function emitted() {
+ console.log(this === context); // true
+}
+
+EE.once('event-name', emitted, context);
+EE.on('another-event', emitted, context);
+EE.removeListener('another-event', emitted, context);
+```
+
+### Tests and benchmarks
+
+This module is well tested. You can run:
+
+- `npm test` to run the tests under Node.js.
+- `npm run test-browser` to run the tests in real browsers via Sauce Labs.
+
+We also have a set of benchmarks to compare EventEmitter3 with some available
+alternatives. To run the benchmarks run `npm run benchmark`.
+
+Tests and benchmarks are not included in the npm package. If you want to play
+with them you have to clone the GitHub repository.
+Note that you will have to run an additional `npm i` in the benchmarks folder
+before `npm run benchmark`.
+
+## License
+
+[MIT](LICENSE)
diff --git a/node_modules/eventemitter3/index.d.ts b/node_modules/eventemitter3/index.d.ts
new file mode 100644
index 0000000..118f68b
--- /dev/null
+++ b/node_modules/eventemitter3/index.d.ts
@@ -0,0 +1,134 @@
+/**
+ * Minimal `EventEmitter` interface that is molded against the Node.js
+ * `EventEmitter` interface.
+ */
+declare class EventEmitter<
+ EventTypes extends EventEmitter.ValidEventTypes = string | symbol,
+ Context extends any = any
+> {
+ static prefixed: string | boolean;
+
+ /**
+ * Return an array listing the events for which the emitter has registered
+ * listeners.
+ */
+ eventNames(): Array>;
+
+ /**
+ * Return the listeners registered for a given event.
+ */
+ listeners>(
+ event: T
+ ): Array>;
+
+ /**
+ * Return the number of listeners listening to a given event.
+ */
+ listenerCount(event: EventEmitter.EventNames): number;
+
+ /**
+ * Calls each of the listeners registered for a given event.
+ */
+ emit>(
+ event: T,
+ ...args: EventEmitter.EventArgs
+ ): boolean;
+
+ /**
+ * Add a listener for a given event.
+ */
+ on>(
+ event: T,
+ fn: EventEmitter.EventListener,
+ context?: Context
+ ): this;
+ addListener>(
+ event: T,
+ fn: EventEmitter.EventListener,
+ context?: Context
+ ): this;
+
+ /**
+ * Add a one-time listener for a given event.
+ */
+ once>(
+ event: T,
+ fn: EventEmitter.EventListener,
+ context?: Context
+ ): this;
+
+ /**
+ * Remove the listeners of a given event.
+ */
+ removeListener>(
+ event: T,
+ fn?: EventEmitter.EventListener,
+ context?: Context,
+ once?: boolean
+ ): this;
+ off>(
+ event: T,
+ fn?: EventEmitter.EventListener,
+ context?: Context,
+ once?: boolean
+ ): this;
+
+ /**
+ * Remove all listeners, or those of the specified event.
+ */
+ removeAllListeners(event?: EventEmitter.EventNames): this;
+}
+
+declare namespace EventEmitter {
+ export interface ListenerFn {
+ (...args: Args): void;
+ }
+
+ export interface EventEmitterStatic {
+ new <
+ EventTypes extends ValidEventTypes = string | symbol,
+ Context = any
+ >(): EventEmitter;
+ }
+
+ /**
+ * `object` should be in either of the following forms:
+ * ```
+ * interface EventTypes {
+ * 'event-with-parameters': any[]
+ * 'event-with-example-handler': (...args: any[]) => void
+ * }
+ * ```
+ */
+ export type ValidEventTypes = string | symbol | object;
+
+ export type EventNames = T extends string | symbol
+ ? T
+ : keyof T;
+
+ export type ArgumentMap = {
+ [K in keyof T]: T[K] extends (...args: any[]) => void
+ ? Parameters
+ : T[K] extends any[]
+ ? T[K]
+ : any[];
+ };
+
+ export type EventListener<
+ T extends ValidEventTypes,
+ K extends EventNames
+ > = T extends string | symbol
+ ? (...args: any[]) => void
+ : (
+ ...args: ArgumentMap>[Extract]
+ ) => void;
+
+ export type EventArgs<
+ T extends ValidEventTypes,
+ K extends EventNames
+ > = Parameters>;
+
+ export const EventEmitter: EventEmitterStatic;
+}
+
+export = EventEmitter;
diff --git a/node_modules/eventemitter3/index.js b/node_modules/eventemitter3/index.js
new file mode 100644
index 0000000..6ea485c
--- /dev/null
+++ b/node_modules/eventemitter3/index.js
@@ -0,0 +1,336 @@
+'use strict';
+
+var has = Object.prototype.hasOwnProperty
+ , prefix = '~';
+
+/**
+ * Constructor to create a storage for our `EE` objects.
+ * An `Events` instance is a plain object whose properties are event names.
+ *
+ * @constructor
+ * @private
+ */
+function Events() {}
+
+//
+// We try to not inherit from `Object.prototype`. In some engines creating an
+// instance in this way is faster than calling `Object.create(null)` directly.
+// If `Object.create(null)` is not supported we prefix the event names with a
+// character to make sure that the built-in object properties are not
+// overridden or used as an attack vector.
+//
+if (Object.create) {
+ Events.prototype = Object.create(null);
+
+ //
+ // This hack is needed because the `__proto__` property is still inherited in
+ // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
+ //
+ if (!new Events().__proto__) prefix = false;
+}
+
+/**
+ * Representation of a single event listener.
+ *
+ * @param {Function} fn The listener function.
+ * @param {*} context The context to invoke the listener with.
+ * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
+ * @constructor
+ * @private
+ */
+function EE(fn, context, once) {
+ this.fn = fn;
+ this.context = context;
+ this.once = once || false;
+}
+
+/**
+ * Add a listener for a given event.
+ *
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
+ * @param {(String|Symbol)} event The event name.
+ * @param {Function} fn The listener function.
+ * @param {*} context The context to invoke the listener with.
+ * @param {Boolean} once Specify if the listener is a one-time listener.
+ * @returns {EventEmitter}
+ * @private
+ */
+function addListener(emitter, event, fn, context, once) {
+ if (typeof fn !== 'function') {
+ throw new TypeError('The listener must be a function');
+ }
+
+ var listener = new EE(fn, context || emitter, once)
+ , evt = prefix ? prefix + event : event;
+
+ if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
+ else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
+ else emitter._events[evt] = [emitter._events[evt], listener];
+
+ return emitter;
+}
+
+/**
+ * Clear event by name.
+ *
+ * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
+ * @param {(String|Symbol)} evt The Event name.
+ * @private
+ */
+function clearEvent(emitter, evt) {
+ if (--emitter._eventsCount === 0) emitter._events = new Events();
+ else delete emitter._events[evt];
+}
+
+/**
+ * Minimal `EventEmitter` interface that is molded against the Node.js
+ * `EventEmitter` interface.
+ *
+ * @constructor
+ * @public
+ */
+function EventEmitter() {
+ this._events = new Events();
+ this._eventsCount = 0;
+}
+
+/**
+ * Return an array listing the events for which the emitter has registered
+ * listeners.
+ *
+ * @returns {Array}
+ * @public
+ */
+EventEmitter.prototype.eventNames = function eventNames() {
+ var names = []
+ , events
+ , name;
+
+ if (this._eventsCount === 0) return names;
+
+ for (name in (events = this._events)) {
+ if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
+ }
+
+ if (Object.getOwnPropertySymbols) {
+ return names.concat(Object.getOwnPropertySymbols(events));
+ }
+
+ return names;
+};
+
+/**
+ * Return the listeners registered for a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @returns {Array} The registered listeners.
+ * @public
+ */
+EventEmitter.prototype.listeners = function listeners(event) {
+ var evt = prefix ? prefix + event : event
+ , handlers = this._events[evt];
+
+ if (!handlers) return [];
+ if (handlers.fn) return [handlers.fn];
+
+ for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
+ ee[i] = handlers[i].fn;
+ }
+
+ return ee;
+};
+
+/**
+ * Return the number of listeners listening to a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @returns {Number} The number of listeners.
+ * @public
+ */
+EventEmitter.prototype.listenerCount = function listenerCount(event) {
+ var evt = prefix ? prefix + event : event
+ , listeners = this._events[evt];
+
+ if (!listeners) return 0;
+ if (listeners.fn) return 1;
+ return listeners.length;
+};
+
+/**
+ * Calls each of the listeners registered for a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @returns {Boolean} `true` if the event had listeners, else `false`.
+ * @public
+ */
+EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
+ var evt = prefix ? prefix + event : event;
+
+ if (!this._events[evt]) return false;
+
+ var listeners = this._events[evt]
+ , len = arguments.length
+ , args
+ , i;
+
+ if (listeners.fn) {
+ if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
+
+ switch (len) {
+ case 1: return listeners.fn.call(listeners.context), true;
+ case 2: return listeners.fn.call(listeners.context, a1), true;
+ case 3: return listeners.fn.call(listeners.context, a1, a2), true;
+ case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
+ case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
+ case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
+ }
+
+ for (i = 1, args = new Array(len -1); i < len; i++) {
+ args[i - 1] = arguments[i];
+ }
+
+ listeners.fn.apply(listeners.context, args);
+ } else {
+ var length = listeners.length
+ , j;
+
+ for (i = 0; i < length; i++) {
+ if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
+
+ switch (len) {
+ case 1: listeners[i].fn.call(listeners[i].context); break;
+ case 2: listeners[i].fn.call(listeners[i].context, a1); break;
+ case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
+ case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
+ default:
+ if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
+ args[j - 1] = arguments[j];
+ }
+
+ listeners[i].fn.apply(listeners[i].context, args);
+ }
+ }
+ }
+
+ return true;
+};
+
+/**
+ * Add a listener for a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @param {Function} fn The listener function.
+ * @param {*} [context=this] The context to invoke the listener with.
+ * @returns {EventEmitter} `this`.
+ * @public
+ */
+EventEmitter.prototype.on = function on(event, fn, context) {
+ return addListener(this, event, fn, context, false);
+};
+
+/**
+ * Add a one-time listener for a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @param {Function} fn The listener function.
+ * @param {*} [context=this] The context to invoke the listener with.
+ * @returns {EventEmitter} `this`.
+ * @public
+ */
+EventEmitter.prototype.once = function once(event, fn, context) {
+ return addListener(this, event, fn, context, true);
+};
+
+/**
+ * Remove the listeners of a given event.
+ *
+ * @param {(String|Symbol)} event The event name.
+ * @param {Function} fn Only remove the listeners that match this function.
+ * @param {*} context Only remove the listeners that have this context.
+ * @param {Boolean} once Only remove one-time listeners.
+ * @returns {EventEmitter} `this`.
+ * @public
+ */
+EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
+ var evt = prefix ? prefix + event : event;
+
+ if (!this._events[evt]) return this;
+ if (!fn) {
+ clearEvent(this, evt);
+ return this;
+ }
+
+ var listeners = this._events[evt];
+
+ if (listeners.fn) {
+ if (
+ listeners.fn === fn &&
+ (!once || listeners.once) &&
+ (!context || listeners.context === context)
+ ) {
+ clearEvent(this, evt);
+ }
+ } else {
+ for (var i = 0, events = [], length = listeners.length; i < length; i++) {
+ if (
+ listeners[i].fn !== fn ||
+ (once && !listeners[i].once) ||
+ (context && listeners[i].context !== context)
+ ) {
+ events.push(listeners[i]);
+ }
+ }
+
+ //
+ // Reset the array, or remove it completely if we have no more listeners.
+ //
+ if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
+ else clearEvent(this, evt);
+ }
+
+ return this;
+};
+
+/**
+ * Remove all listeners, or those of the specified event.
+ *
+ * @param {(String|Symbol)} [event] The event name.
+ * @returns {EventEmitter} `this`.
+ * @public
+ */
+EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
+ var evt;
+
+ if (event) {
+ evt = prefix ? prefix + event : event;
+ if (this._events[evt]) clearEvent(this, evt);
+ } else {
+ this._events = new Events();
+ this._eventsCount = 0;
+ }
+
+ return this;
+};
+
+//
+// Alias methods names because people roll like that.
+//
+EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
+EventEmitter.prototype.addListener = EventEmitter.prototype.on;
+
+//
+// Expose the prefix.
+//
+EventEmitter.prefixed = prefix;
+
+//
+// Allow `EventEmitter` to be imported as module namespace.
+//
+EventEmitter.EventEmitter = EventEmitter;
+
+//
+// Expose the module.
+//
+if ('undefined' !== typeof module) {
+ module.exports = EventEmitter;
+}
diff --git a/node_modules/eventemitter3/package.json b/node_modules/eventemitter3/package.json
new file mode 100644
index 0000000..6f6e2fd
--- /dev/null
+++ b/node_modules/eventemitter3/package.json
@@ -0,0 +1,84 @@
+{
+ "_from": "eventemitter3@^4.0.0",
+ "_id": "eventemitter3@4.0.7",
+ "_inBundle": false,
+ "_integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "_location": "/eventemitter3",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "eventemitter3@^4.0.0",
+ "name": "eventemitter3",
+ "escapedName": "eventemitter3",
+ "rawSpec": "^4.0.0",
+ "saveSpec": null,
+ "fetchSpec": "^4.0.0"
+ },
+ "_requiredBy": [
+ "/widget-ui"
+ ],
+ "_resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "_shasum": "2de9b68f6528d5644ef5c59526a1b4a07306169f",
+ "_spec": "eventemitter3@^4.0.0",
+ "_where": "/Users/WebTmm/Desktop/AGuestSaas/node_modules/widget-ui",
+ "author": {
+ "name": "Arnout Kazemier"
+ },
+ "bugs": {
+ "url": "https://github.com/primus/eventemitter3/issues"
+ },
+ "bundleDependencies": false,
+ "deprecated": false,
+ "description": "EventEmitter3 focuses on performance while maintaining a Node.js AND browser compatible interface.",
+ "devDependencies": {
+ "assume": "^2.2.0",
+ "browserify": "^16.5.0",
+ "mocha": "^8.0.1",
+ "nyc": "^15.1.0",
+ "pre-commit": "^1.2.0",
+ "sauce-browsers": "^2.0.0",
+ "sauce-test": "^1.3.3",
+ "uglify-js": "^3.9.0"
+ },
+ "files": [
+ "index.js",
+ "index.d.ts",
+ "umd"
+ ],
+ "homepage": "https://github.com/primus/eventemitter3#readme",
+ "keywords": [
+ "EventEmitter",
+ "EventEmitter2",
+ "EventEmitter3",
+ "Events",
+ "addEventListener",
+ "addListener",
+ "emit",
+ "emits",
+ "emitter",
+ "event",
+ "once",
+ "pub/sub",
+ "publish",
+ "reactor",
+ "subscribe"
+ ],
+ "license": "MIT",
+ "main": "index.js",
+ "name": "eventemitter3",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/primus/eventemitter3.git"
+ },
+ "scripts": {
+ "benchmark": "find benchmarks/run -name '*.js' -exec benchmarks/start.sh {} \\;",
+ "browserify": "rm -rf umd && mkdir umd && browserify index.js -s EventEmitter3 -o umd/eventemitter3.js",
+ "minify": "uglifyjs umd/eventemitter3.js --source-map -cm -o umd/eventemitter3.min.js",
+ "prepublishOnly": "npm run browserify && npm run minify",
+ "test": "nyc --reporter=html --reporter=text mocha test/test.js",
+ "test-browser": "node test/browser.js"
+ },
+ "typings": "index.d.ts",
+ "version": "4.0.7"
+}
diff --git a/node_modules/eventemitter3/umd/eventemitter3.js b/node_modules/eventemitter3/umd/eventemitter3.js
new file mode 100644
index 0000000..888fcb8
--- /dev/null
+++ b/node_modules/eventemitter3/umd/eventemitter3.js
@@ -0,0 +1,340 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.EventEmitter3 = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i=0&&L(e))return t.style.borderStartWidth;var o=null;switch(e){case"row":o=t.style.borderLeftWidth;break;case"row-reverse":o=t.style.borderRightWidth;break;case"column":o=t.style.borderTopWidth;break;case"column-reverse":o=t.style.borderBottomWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function E(t,e){if(void 0!==t.style.borderEndWidth&&t.style.borderEndWidth>=0&&L(e))return t.style.borderEndWidth;var o=null;switch(e){case"row":o=t.style.borderRightWidth;break;case"row-reverse":o=t.style.borderLeftWidth;break;case"column":o=t.style.borderBottomWidth;break;case"column-reverse":o=t.style.borderTopWidth}return null!=o&&o>=0?o:void 0!==t.style.borderWidth&&t.style.borderWidth>=0?t.style.borderWidth:0}function C(t,e){return function(t,e){if(void 0!==t.style.paddingStart&&t.style.paddingStart>=0&&L(e))return t.style.paddingStart;var o=null;switch(e){case"row":o=t.style.paddingLeft;break;case"row-reverse":o=t.style.paddingRight;break;case"column":o=t.style.paddingTop;break;case"column-reverse":o=t.style.paddingBottom}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+B(t,e)}function T(t,e){return function(t,e){if(void 0!==t.style.paddingEnd&&t.style.paddingEnd>=0&&L(e))return t.style.paddingEnd;var o=null;switch(e){case"row":o=t.style.paddingRight;break;case"row-reverse":o=t.style.paddingLeft;break;case"column":o=t.style.paddingBottom;break;case"column-reverse":o=t.style.paddingTop}return null!=o&&o>=0?o:void 0!==t.style.padding&&t.style.padding>=0?t.style.padding:0}(t,e)+E(t,e)}function O(t,e){return B(t,e)+E(t,e)}function _(t,e){return k(t,e)+j(t,e)}function R(t,e){return C(t,e)+T(t,e)}function A(t,e){return e.style.alignSelf?e.style.alignSelf:t.style.alignItems?t.style.alignItems:"stretch"}function P(t,e){if(e===r){if(t===i)return l;if(t===l)return i}return t}function D(t,e){return function(t){return t===n||t===a}(t)?P(i,e):n}function H(t){return t.style.position?t.style.position:"relative"}function M(t){return H(t)===v&&t.style.flex>0}function I(t,e){return t.layout[S[e]]+_(t,e)}function N(t,e){return void 0!==t.style[S[e]]&&t.style[S[e]]>=0}function F(t,e){return void 0!==t.style[e]}function q(t,e){return void 0!==t.style[e]?t.style[e]:0}function z(t,e,o){var r={row:t.style.minWidth,"row-reverse":t.style.minWidth,column:t.style.minHeight,"column-reverse":t.style.minHeight}[e],i={row:t.style.maxWidth,"row-reverse":t.style.maxWidth,column:t.style.maxHeight,"column-reverse":t.style.maxHeight}[e],l=o;return void 0!==i&&i>=0&&l>i&&(l=i),void 0!==r&&r>=0&&le?t:e}function G(t,e){void 0===t.layout[S[e]]&&N(t,e)&&(t.layout[S[e]]=U(z(t,e,t.style[S[e]]),R(t,e)))}function J(t,e,o){e.layout[x[o]]=t.layout[S[o]]-e.layout[S[o]]-e.layout[w[o]]}function K(t,e){return void 0!==t.style[b[e]]?q(t,b[e]):-q(t,x[e])}function Q(r,E,Q){var X=function(t,r){var i;return(i=t.style.direction?t.style.direction:e)===e&&(i=void 0===r?o:r),i}(r,Q),Y=P(function(t){return t.style.flexDirection?t.style.flexDirection:n}(r),X),Z=D(Y,X),$=P(i,X);G(r,Y),G(r,Z),r.layout.direction=X,r.layout[b[Y]]+=k(r,Y)+K(r,Y),r.layout[x[Y]]+=j(r,Y)+K(r,Y),r.layout[b[Z]]+=k(r,Z)+K(r,Z),r.layout[x[Z]]+=j(r,Z)+K(r,Z);var tt=r.children.length,et=R(r,$);if(function(t){return void 0!==t.style.measure}(r)){var ot=!W(r.layout[S[$]]),rt=t;rt=N(r,$)?r.style.width:ot?r.layout[S[$]]:E-_(r,$),rt-=et;var it=!N(r,$)&&!ot,lt=!N(r,n)&&W(r.layout[S[n]]);if(it||lt){var nt=r.style.measure(rt);it&&(r.layout.width=nt.width+et),lt&&(r.layout.height=nt.height+R(r,n))}if(0===tt)return}var at,ut,dt,st,yt=function(t){return"wrap"===t.style.flexWrap}(r),ct=function(t){return t.style.justifyContent?t.style.justifyContent:"flex-start"}(r),ft=C(r,Y),ht=C(r,Z),pt=R(r,Y),gt=R(r,Z),vt=!W(r.layout[S[Y]]),mt=!W(r.layout[S[Z]]),bt=L(Y),xt=null,wt=null,St=t;vt&&(St=r.layout[S[Y]]-pt);for(var Wt=0,Lt=0,kt=0,jt=0,Bt=0,Et=0;LtSt&&at!==Wt){Rt--,kt=1;break}At&&(H(dt)!==v||M(dt))&&(At=!1,Pt=at),Dt&&(H(dt)!==v||Xt!==g&&Xt!==f||W(dt.layout[S[Z]]))&&(Dt=!1,Ht=at),At&&(dt.layout[w[Y]]+=Nt,vt&&J(r,dt,Y),Nt+=I(dt,Y),Ft=U(Ft,z(dt,Z,I(dt,Z)))),Dt&&(dt.layout[w[Z]]+=jt+ht,mt&&J(r,dt,Z)),kt=0,Tt+=qt,Lt=at+1}var zt=0,Ut=0,Gt=0;if(Gt=vt?St-Tt:U(Tt,0)-Tt,0!==Ot){var Jt,Kt,Qt=Gt/_t;for(It=Mt;null!==It;)(Jt=Qt*It.style.flex+R(It,Y))!==(Kt=z(It,Y,Jt))&&(Gt-=Kt,_t-=It.style.flex),It=It.nextFlexChild;for((Qt=Gt/_t)<0&&(Qt=0),It=Mt;null!==It;)It.layout[S[Y]]=z(It,Y,Qt*It.style.flex+R(It,Y)),Ct=t,N(r,$)?Ct=r.layout[S[$]]-et:bt||(Ct=E-_(r,$)-et),V(It,Ct,X),dt=It,It=It.nextFlexChild,dt.nextFlexChild=null}else ct!==u&&(ct===d?zt=Gt/2:ct===s?zt=Gt:ct===y?(Gt=U(Gt,0),Ut=Ot+Rt-1!=0?Gt/(Ot+Rt-1):0):ct===c&&(zt=(Ut=Gt/(Ot+Rt))/2));for(Nt+=zt,at=Pt;at1&&mt){var $t=r.layout[S[Z]]-gt,te=$t-jt,ee=0,oe=ht,re=function(t){return t.style.alignContent?t.style.alignContent:"flex-start"}(r);re===p?oe+=te:re===h?oe+=te/2:re===g&&$t>jt&&(ee=te/Et);var ie=0;for(at=0;at {
+ left: undefined;
+ top: undefined;
+ right: undefined;
+ bottom: undefined;
+ width: undefined;
+ height: undefined;
+ maxWidth: undefined;
+ maxHeight: undefined;
+ minWidth: undefined;
+ minHeight: undefined;
+ margin: undefined;
+ marginLeft: undefined;
+ marginRight: undefined;
+ marginTop: undefined;
+ marginBottom: undefined;
+ padding: undefined;
+ paddingLeft: undefined;
+ paddingRight: undefined;
+ paddingTop: undefined;
+ paddingBottom: undefined;
+ borderWidth: undefined;
+ flexDirection: undefined;
+ justifyContent: undefined;
+ alignItems: undefined;
+ alignSelf: undefined;
+ flex: undefined;
+ flexWrap: undefined;
+ position: undefined;
+ hidden: boolean;
+ scale: number;
+};
+export { getDefaultStyle, scalableStyles, textStyles, layoutAffectedStyles };
diff --git a/node_modules/widget-ui/jest.config.js b/node_modules/widget-ui/jest.config.js
new file mode 100644
index 0000000..837466b
--- /dev/null
+++ b/node_modules/widget-ui/jest.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ transform: {
+ "^.+\\.js$": "babel-jest",
+ "^.+\\.ts$": "ts-jest"
+ }
+};
\ No newline at end of file
diff --git a/node_modules/widget-ui/package.json b/node_modules/widget-ui/package.json
new file mode 100644
index 0000000..c336a07
--- /dev/null
+++ b/node_modules/widget-ui/package.json
@@ -0,0 +1,52 @@
+{
+ "_from": "widget-ui@^1.0.2",
+ "_id": "widget-ui@1.0.2",
+ "_inBundle": false,
+ "_integrity": "sha512-gDXosr5mflJdMA1weU1A47aTsTFfMJhfA4EKgO5XFebY3eVklf80KD4GODfrjo8J2WQ+9YjL1Rd9UUmKIzhShw==",
+ "_location": "/widget-ui",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "widget-ui@^1.0.2",
+ "name": "widget-ui",
+ "escapedName": "widget-ui",
+ "rawSpec": "^1.0.2",
+ "saveSpec": null,
+ "fetchSpec": "^1.0.2"
+ },
+ "_requiredBy": [
+ "/wxml-to-canvas"
+ ],
+ "_resolved": "https://registry.npmjs.org/widget-ui/-/widget-ui-1.0.2.tgz",
+ "_shasum": "d65a560b91739fbd0ea7c2f5f2d28fe4c0132470",
+ "_spec": "widget-ui@^1.0.2",
+ "_where": "/Users/WebTmm/Desktop/AGuestSaas/node_modules/wxml-to-canvas",
+ "author": "",
+ "bundleDependencies": false,
+ "dependencies": {
+ "eventemitter3": "^4.0.0"
+ },
+ "deprecated": false,
+ "description": "",
+ "devDependencies": {
+ "@babel/preset-env": "^7.6.3",
+ "@babel/preset-typescript": "^7.6.0",
+ "@types/jest": "^24.0.18",
+ "babel-jest": "^24.9.0",
+ "jest": "^24.9.0",
+ "ts-jest": "^24.1.0",
+ "ts-loader": "^6.2.0",
+ "typescript": "^3.6.4",
+ "webpack": "^4.41.1",
+ "webpack-cli": "^3.3.9"
+ },
+ "license": "ISC",
+ "main": "dist/index.js",
+ "name": "widget-ui",
+ "scripts": {
+ "build": "webpack",
+ "test": "jest"
+ },
+ "version": "1.0.2"
+}
diff --git a/node_modules/widget-ui/src/css-layout.js b/node_modules/widget-ui/src/css-layout.js
new file mode 100644
index 0000000..790c753
--- /dev/null
+++ b/node_modules/widget-ui/src/css-layout.js
@@ -0,0 +1,1186 @@
+/* eslint-disable */
+// https://www.npmjs.com/package/css-layout
+// change: module export strategy. Use ES6 Module
+
+/**
+ * Copyright (c) 2014, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+var computeLayout = (function() {
+
+ var CSS_UNDEFINED;
+
+ var CSS_DIRECTION_INHERIT = 'inherit';
+ var CSS_DIRECTION_LTR = 'ltr';
+ var CSS_DIRECTION_RTL = 'rtl';
+
+ var CSS_FLEX_DIRECTION_ROW = 'row';
+ var CSS_FLEX_DIRECTION_ROW_REVERSE = 'row-reverse';
+ var CSS_FLEX_DIRECTION_COLUMN = 'column';
+ var CSS_FLEX_DIRECTION_COLUMN_REVERSE = 'column-reverse';
+
+ var CSS_JUSTIFY_FLEX_START = 'flex-start';
+ var CSS_JUSTIFY_CENTER = 'center';
+ var CSS_JUSTIFY_FLEX_END = 'flex-end';
+ var CSS_JUSTIFY_SPACE_BETWEEN = 'space-between';
+ var CSS_JUSTIFY_SPACE_AROUND = 'space-around';
+
+ var CSS_ALIGN_FLEX_START = 'flex-start';
+ var CSS_ALIGN_CENTER = 'center';
+ var CSS_ALIGN_FLEX_END = 'flex-end';
+ var CSS_ALIGN_STRETCH = 'stretch';
+
+ var CSS_POSITION_RELATIVE = 'relative';
+ var CSS_POSITION_ABSOLUTE = 'absolute';
+
+ var leading = {
+ 'row': 'left',
+ 'row-reverse': 'right',
+ 'column': 'top',
+ 'column-reverse': 'bottom'
+ };
+ var trailing = {
+ 'row': 'right',
+ 'row-reverse': 'left',
+ 'column': 'bottom',
+ 'column-reverse': 'top'
+ };
+ var pos = {
+ 'row': 'left',
+ 'row-reverse': 'right',
+ 'column': 'top',
+ 'column-reverse': 'bottom'
+ };
+ var dim = {
+ 'row': 'width',
+ 'row-reverse': 'width',
+ 'column': 'height',
+ 'column-reverse': 'height'
+ };
+
+ // When transpiled to Java / C the node type has layout, children and style
+ // properties. For the JavaScript version this function adds these properties
+ // if they don't already exist.
+ function fillNodes(node) {
+ if (!node.layout || node.isDirty) {
+ node.layout = {
+ width: undefined,
+ height: undefined,
+ top: 0,
+ left: 0,
+ right: 0,
+ bottom: 0
+ };
+ }
+
+ if (!node.style) {
+ node.style = {};
+ }
+
+ if (!node.children) {
+ node.children = [];
+ }
+ node.children.forEach(fillNodes);
+ return node;
+ }
+
+ function isUndefined(value) {
+ return value === undefined;
+ }
+
+ function isRowDirection(flexDirection) {
+ return flexDirection === CSS_FLEX_DIRECTION_ROW ||
+ flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE;
+ }
+
+ function isColumnDirection(flexDirection) {
+ return flexDirection === CSS_FLEX_DIRECTION_COLUMN ||
+ flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE;
+ }
+
+ function getLeadingMargin(node, axis) {
+ if (node.style.marginStart !== undefined && isRowDirection(axis)) {
+ return node.style.marginStart;
+ }
+
+ var value = null;
+ switch (axis) {
+ case 'row': value = node.style.marginLeft; break;
+ case 'row-reverse': value = node.style.marginRight; break;
+ case 'column': value = node.style.marginTop; break;
+ case 'column-reverse': value = node.style.marginBottom; break;
+ }
+
+ if (value !== undefined) {
+ return value;
+ }
+
+ if (node.style.margin !== undefined) {
+ return node.style.margin;
+ }
+
+ return 0;
+ }
+
+ function getTrailingMargin(node, axis) {
+ if (node.style.marginEnd !== undefined && isRowDirection(axis)) {
+ return node.style.marginEnd;
+ }
+
+ var value = null;
+ switch (axis) {
+ case 'row': value = node.style.marginRight; break;
+ case 'row-reverse': value = node.style.marginLeft; break;
+ case 'column': value = node.style.marginBottom; break;
+ case 'column-reverse': value = node.style.marginTop; break;
+ }
+
+ if (value != null) {
+ return value;
+ }
+
+ if (node.style.margin !== undefined) {
+ return node.style.margin;
+ }
+
+ return 0;
+ }
+
+ function getLeadingPadding(node, axis) {
+ if (node.style.paddingStart !== undefined && node.style.paddingStart >= 0
+ && isRowDirection(axis)) {
+ return node.style.paddingStart;
+ }
+
+ var value = null;
+ switch (axis) {
+ case 'row': value = node.style.paddingLeft; break;
+ case 'row-reverse': value = node.style.paddingRight; break;
+ case 'column': value = node.style.paddingTop; break;
+ case 'column-reverse': value = node.style.paddingBottom; break;
+ }
+
+ if (value != null && value >= 0) {
+ return value;
+ }
+
+ if (node.style.padding !== undefined && node.style.padding >= 0) {
+ return node.style.padding;
+ }
+
+ return 0;
+ }
+
+ function getTrailingPadding(node, axis) {
+ if (node.style.paddingEnd !== undefined && node.style.paddingEnd >= 0
+ && isRowDirection(axis)) {
+ return node.style.paddingEnd;
+ }
+
+ var value = null;
+ switch (axis) {
+ case 'row': value = node.style.paddingRight; break;
+ case 'row-reverse': value = node.style.paddingLeft; break;
+ case 'column': value = node.style.paddingBottom; break;
+ case 'column-reverse': value = node.style.paddingTop; break;
+ }
+
+ if (value != null && value >= 0) {
+ return value;
+ }
+
+ if (node.style.padding !== undefined && node.style.padding >= 0) {
+ return node.style.padding;
+ }
+
+ return 0;
+ }
+
+ function getLeadingBorder(node, axis) {
+ if (node.style.borderStartWidth !== undefined && node.style.borderStartWidth >= 0
+ && isRowDirection(axis)) {
+ return node.style.borderStartWidth;
+ }
+
+ var value = null;
+ switch (axis) {
+ case 'row': value = node.style.borderLeftWidth; break;
+ case 'row-reverse': value = node.style.borderRightWidth; break;
+ case 'column': value = node.style.borderTopWidth; break;
+ case 'column-reverse': value = node.style.borderBottomWidth; break;
+ }
+
+ if (value != null && value >= 0) {
+ return value;
+ }
+
+ if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {
+ return node.style.borderWidth;
+ }
+
+ return 0;
+ }
+
+ function getTrailingBorder(node, axis) {
+ if (node.style.borderEndWidth !== undefined && node.style.borderEndWidth >= 0
+ && isRowDirection(axis)) {
+ return node.style.borderEndWidth;
+ }
+
+ var value = null;
+ switch (axis) {
+ case 'row': value = node.style.borderRightWidth; break;
+ case 'row-reverse': value = node.style.borderLeftWidth; break;
+ case 'column': value = node.style.borderBottomWidth; break;
+ case 'column-reverse': value = node.style.borderTopWidth; break;
+ }
+
+ if (value != null && value >= 0) {
+ return value;
+ }
+
+ if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {
+ return node.style.borderWidth;
+ }
+
+ return 0;
+ }
+
+ function getLeadingPaddingAndBorder(node, axis) {
+ return getLeadingPadding(node, axis) + getLeadingBorder(node, axis);
+ }
+
+ function getTrailingPaddingAndBorder(node, axis) {
+ return getTrailingPadding(node, axis) + getTrailingBorder(node, axis);
+ }
+
+ function getBorderAxis(node, axis) {
+ return getLeadingBorder(node, axis) + getTrailingBorder(node, axis);
+ }
+
+ function getMarginAxis(node, axis) {
+ return getLeadingMargin(node, axis) + getTrailingMargin(node, axis);
+ }
+
+ function getPaddingAndBorderAxis(node, axis) {
+ return getLeadingPaddingAndBorder(node, axis) +
+ getTrailingPaddingAndBorder(node, axis);
+ }
+
+ function getJustifyContent(node) {
+ if (node.style.justifyContent) {
+ return node.style.justifyContent;
+ }
+ return 'flex-start';
+ }
+
+ function getAlignContent(node) {
+ if (node.style.alignContent) {
+ return node.style.alignContent;
+ }
+ return 'flex-start';
+ }
+
+ function getAlignItem(node, child) {
+ if (child.style.alignSelf) {
+ return child.style.alignSelf;
+ }
+ if (node.style.alignItems) {
+ return node.style.alignItems;
+ }
+ return 'stretch';
+ }
+
+ function resolveAxis(axis, direction) {
+ if (direction === CSS_DIRECTION_RTL) {
+ if (axis === CSS_FLEX_DIRECTION_ROW) {
+ return CSS_FLEX_DIRECTION_ROW_REVERSE;
+ } else if (axis === CSS_FLEX_DIRECTION_ROW_REVERSE) {
+ return CSS_FLEX_DIRECTION_ROW;
+ }
+ }
+
+ return axis;
+ }
+
+ function resolveDirection(node, parentDirection) {
+ var direction;
+ if (node.style.direction) {
+ direction = node.style.direction;
+ } else {
+ direction = CSS_DIRECTION_INHERIT;
+ }
+
+ if (direction === CSS_DIRECTION_INHERIT) {
+ direction = (parentDirection === undefined ? CSS_DIRECTION_LTR : parentDirection);
+ }
+
+ return direction;
+ }
+
+ function getFlexDirection(node) {
+ if (node.style.flexDirection) {
+ return node.style.flexDirection;
+ }
+ return CSS_FLEX_DIRECTION_COLUMN;
+ }
+
+ function getCrossFlexDirection(flexDirection, direction) {
+ if (isColumnDirection(flexDirection)) {
+ return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction);
+ } else {
+ return CSS_FLEX_DIRECTION_COLUMN;
+ }
+ }
+
+ function getPositionType(node) {
+ if (node.style.position) {
+ return node.style.position;
+ }
+ return 'relative';
+ }
+
+ function isFlex(node) {
+ return (
+ getPositionType(node) === CSS_POSITION_RELATIVE &&
+ node.style.flex > 0
+ );
+ }
+
+ function isFlexWrap(node) {
+ return node.style.flexWrap === 'wrap';
+ }
+
+ function getDimWithMargin(node, axis) {
+ return node.layout[dim[axis]] + getMarginAxis(node, axis);
+ }
+
+ function isDimDefined(node, axis) {
+ return node.style[dim[axis]] !== undefined && node.style[dim[axis]] >= 0;
+ }
+
+ function isPosDefined(node, pos) {
+ return node.style[pos] !== undefined;
+ }
+
+ function isMeasureDefined(node) {
+ return node.style.measure !== undefined;
+ }
+
+ function getPosition(node, pos) {
+ if (node.style[pos] !== undefined) {
+ return node.style[pos];
+ }
+ return 0;
+ }
+
+ function boundAxis(node, axis, value) {
+ var min = {
+ 'row': node.style.minWidth,
+ 'row-reverse': node.style.minWidth,
+ 'column': node.style.minHeight,
+ 'column-reverse': node.style.minHeight
+ }[axis];
+
+ var max = {
+ 'row': node.style.maxWidth,
+ 'row-reverse': node.style.maxWidth,
+ 'column': node.style.maxHeight,
+ 'column-reverse': node.style.maxHeight
+ }[axis];
+
+ var boundValue = value;
+ if (max !== undefined && max >= 0 && boundValue > max) {
+ boundValue = max;
+ }
+ if (min !== undefined && min >= 0 && boundValue < min) {
+ boundValue = min;
+ }
+ return boundValue;
+ }
+
+ function fmaxf(a, b) {
+ if (a > b) {
+ return a;
+ }
+ return b;
+ }
+
+ // When the user specifically sets a value for width or height
+ function setDimensionFromStyle(node, axis) {
+ // The parent already computed us a width or height. We just skip it
+ if (node.layout[dim[axis]] !== undefined) {
+ return;
+ }
+ // We only run if there's a width or height defined
+ if (!isDimDefined(node, axis)) {
+ return;
+ }
+
+ // The dimensions can never be smaller than the padding and border
+ node.layout[dim[axis]] = fmaxf(
+ boundAxis(node, axis, node.style[dim[axis]]),
+ getPaddingAndBorderAxis(node, axis)
+ );
+ }
+
+ function setTrailingPosition(node, child, axis) {
+ child.layout[trailing[axis]] = node.layout[dim[axis]] -
+ child.layout[dim[axis]] - child.layout[pos[axis]];
+ }
+
+ // If both left and right are defined, then use left. Otherwise return
+ // +left or -right depending on which is defined.
+ function getRelativePosition(node, axis) {
+ if (node.style[leading[axis]] !== undefined) {
+ return getPosition(node, leading[axis]);
+ }
+ return -getPosition(node, trailing[axis]);
+ }
+
+ function layoutNodeImpl(node, parentMaxWidth, /*css_direction_t*/parentDirection) {
+ var/*css_direction_t*/ direction = resolveDirection(node, parentDirection);
+ var/*(c)!css_flex_direction_t*//*(java)!int*/ mainAxis = resolveAxis(getFlexDirection(node), direction);
+ var/*(c)!css_flex_direction_t*//*(java)!int*/ crossAxis = getCrossFlexDirection(mainAxis, direction);
+ var/*(c)!css_flex_direction_t*//*(java)!int*/ resolvedRowAxis = resolveAxis(CSS_FLEX_DIRECTION_ROW, direction);
+
+ // Handle width and height style attributes
+ setDimensionFromStyle(node, mainAxis);
+ setDimensionFromStyle(node, crossAxis);
+
+ // Set the resolved resolution in the node's layout
+ node.layout.direction = direction;
+
+ // The position is set by the parent, but we need to complete it with a
+ // delta composed of the margin and left/top/right/bottom
+ node.layout[leading[mainAxis]] += getLeadingMargin(node, mainAxis) +
+ getRelativePosition(node, mainAxis);
+ node.layout[trailing[mainAxis]] += getTrailingMargin(node, mainAxis) +
+ getRelativePosition(node, mainAxis);
+ node.layout[leading[crossAxis]] += getLeadingMargin(node, crossAxis) +
+ getRelativePosition(node, crossAxis);
+ node.layout[trailing[crossAxis]] += getTrailingMargin(node, crossAxis) +
+ getRelativePosition(node, crossAxis);
+
+ // Inline immutable values from the target node to avoid excessive method
+ // invocations during the layout calculation.
+ var/*int*/ childCount = node.children.length;
+ var/*float*/ paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis);
+
+ if (isMeasureDefined(node)) {
+ var/*bool*/ isResolvedRowDimDefined = !isUndefined(node.layout[dim[resolvedRowAxis]]);
+
+ var/*float*/ width = CSS_UNDEFINED;
+ if (isDimDefined(node, resolvedRowAxis)) {
+ width = node.style.width;
+ } else if (isResolvedRowDimDefined) {
+ width = node.layout[dim[resolvedRowAxis]];
+ } else {
+ width = parentMaxWidth -
+ getMarginAxis(node, resolvedRowAxis);
+ }
+ width -= paddingAndBorderAxisResolvedRow;
+
+ // We only need to give a dimension for the text if we haven't got any
+ // for it computed yet. It can either be from the style attribute or because
+ // the element is flexible.
+ var/*bool*/ isRowUndefined = !isDimDefined(node, resolvedRowAxis) && !isResolvedRowDimDefined;
+ var/*bool*/ isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) &&
+ isUndefined(node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]]);
+
+ // Let's not measure the text if we already know both dimensions
+ if (isRowUndefined || isColumnUndefined) {
+ var/*css_dim_t*/ measureDim = node.style.measure(
+ /*(c)!node->context,*/
+ /*(java)!layoutContext.measureOutput,*/
+ width
+ );
+ if (isRowUndefined) {
+ node.layout.width = measureDim.width +
+ paddingAndBorderAxisResolvedRow;
+ }
+ if (isColumnUndefined) {
+ node.layout.height = measureDim.height +
+ getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);
+ }
+ }
+ if (childCount === 0) {
+ return;
+ }
+ }
+
+ var/*bool*/ isNodeFlexWrap = isFlexWrap(node);
+
+ var/*css_justify_t*/ justifyContent = getJustifyContent(node);
+
+ var/*float*/ leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis);
+ var/*float*/ leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis);
+ var/*float*/ paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis);
+ var/*float*/ paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis);
+
+ var/*bool*/ isMainDimDefined = !isUndefined(node.layout[dim[mainAxis]]);
+ var/*bool*/ isCrossDimDefined = !isUndefined(node.layout[dim[crossAxis]]);
+ var/*bool*/ isMainRowDirection = isRowDirection(mainAxis);
+
+ var/*int*/ i;
+ var/*int*/ ii;
+ var/*css_node_t**/ child;
+ var/*(c)!css_flex_direction_t*//*(java)!int*/ axis;
+
+ var/*css_node_t**/ firstAbsoluteChild = null;
+ var/*css_node_t**/ currentAbsoluteChild = null;
+
+ var/*float*/ definedMainDim = CSS_UNDEFINED;
+ if (isMainDimDefined) {
+ definedMainDim = node.layout[dim[mainAxis]] - paddingAndBorderAxisMain;
+ }
+
+ // We want to execute the next two loops one per line with flex-wrap
+ var/*int*/ startLine = 0;
+ var/*int*/ endLine = 0;
+ // var/*int*/ nextOffset = 0;
+ var/*int*/ alreadyComputedNextLayout = 0;
+ // We aggregate the total dimensions of the container in those two variables
+ var/*float*/ linesCrossDim = 0;
+ var/*float*/ linesMainDim = 0;
+ var/*int*/ linesCount = 0;
+ while (endLine < childCount) {
+ // Layout non flexible children and count children by type
+
+ // mainContentDim is accumulation of the dimensions and margin of all the
+ // non flexible children. This will be used in order to either set the
+ // dimensions of the node if none already exist, or to compute the
+ // remaining space left for the flexible children.
+ var/*float*/ mainContentDim = 0;
+
+ // There are three kind of children, non flexible, flexible and absolute.
+ // We need to know how many there are in order to distribute the space.
+ var/*int*/ flexibleChildrenCount = 0;
+ var/*float*/ totalFlexible = 0;
+ var/*int*/ nonFlexibleChildrenCount = 0;
+
+ // Use the line loop to position children in the main axis for as long
+ // as they are using a simple stacking behaviour. Children that are
+ // immediately stacked in the initial loop will not be touched again
+ // in .
+ var/*bool*/ isSimpleStackMain =
+ (isMainDimDefined && justifyContent === CSS_JUSTIFY_FLEX_START) ||
+ (!isMainDimDefined && justifyContent !== CSS_JUSTIFY_CENTER);
+ var/*int*/ firstComplexMain = (isSimpleStackMain ? childCount : startLine);
+
+ // Use the initial line loop to position children in the cross axis for
+ // as long as they are relatively positioned with alignment STRETCH or
+ // FLEX_START. Children that are immediately stacked in the initial loop
+ // will not be touched again in .
+ var/*bool*/ isSimpleStackCross = true;
+ var/*int*/ firstComplexCross = childCount;
+
+ var/*css_node_t**/ firstFlexChild = null;
+ var/*css_node_t**/ currentFlexChild = null;
+
+ var/*float*/ mainDim = leadingPaddingAndBorderMain;
+ var/*float*/ crossDim = 0;
+
+ var/*float*/ maxWidth;
+ for (i = startLine; i < childCount; ++i) {
+ child = node.children[i];
+ child.lineIndex = linesCount;
+
+ child.nextAbsoluteChild = null;
+ child.nextFlexChild = null;
+
+ var/*css_align_t*/ alignItem = getAlignItem(node, child);
+
+ // Pre-fill cross axis dimensions when the child is using stretch before
+ // we call the recursive layout pass
+ if (alignItem === CSS_ALIGN_STRETCH &&
+ getPositionType(child) === CSS_POSITION_RELATIVE &&
+ isCrossDimDefined &&
+ !isDimDefined(child, crossAxis)) {
+ child.layout[dim[crossAxis]] = fmaxf(
+ boundAxis(child, crossAxis, node.layout[dim[crossAxis]] -
+ paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)),
+ // You never want to go smaller than padding
+ getPaddingAndBorderAxis(child, crossAxis)
+ );
+ } else if (getPositionType(child) === CSS_POSITION_ABSOLUTE) {
+ // Store a private linked list of absolutely positioned children
+ // so that we can efficiently traverse them later.
+ if (firstAbsoluteChild === null) {
+ firstAbsoluteChild = child;
+ }
+ if (currentAbsoluteChild !== null) {
+ currentAbsoluteChild.nextAbsoluteChild = child;
+ }
+ currentAbsoluteChild = child;
+
+ // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both
+ // left and right or top and bottom).
+ for (ii = 0; ii < 2; ii++) {
+ axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
+ if (!isUndefined(node.layout[dim[axis]]) &&
+ !isDimDefined(child, axis) &&
+ isPosDefined(child, leading[axis]) &&
+ isPosDefined(child, trailing[axis])) {
+ child.layout[dim[axis]] = fmaxf(
+ boundAxis(child, axis, node.layout[dim[axis]] -
+ getPaddingAndBorderAxis(node, axis) -
+ getMarginAxis(child, axis) -
+ getPosition(child, leading[axis]) -
+ getPosition(child, trailing[axis])),
+ // You never want to go smaller than padding
+ getPaddingAndBorderAxis(child, axis)
+ );
+ }
+ }
+ }
+
+ var/*float*/ nextContentDim = 0;
+
+ // It only makes sense to consider a child flexible if we have a computed
+ // dimension for the node.
+ if (isMainDimDefined && isFlex(child)) {
+ flexibleChildrenCount++;
+ totalFlexible += child.style.flex;
+
+ // Store a private linked list of flexible children so that we can
+ // efficiently traverse them later.
+ if (firstFlexChild === null) {
+ firstFlexChild = child;
+ }
+ if (currentFlexChild !== null) {
+ currentFlexChild.nextFlexChild = child;
+ }
+ currentFlexChild = child;
+
+ // Even if we don't know its exact size yet, we already know the padding,
+ // border and margin. We'll use this partial information, which represents
+ // the smallest possible size for the child, to compute the remaining
+ // available space.
+ nextContentDim = getPaddingAndBorderAxis(child, mainAxis) +
+ getMarginAxis(child, mainAxis);
+
+ } else {
+ maxWidth = CSS_UNDEFINED;
+ if (!isMainRowDirection) {
+ if (isDimDefined(node, resolvedRowAxis)) {
+ maxWidth = node.layout[dim[resolvedRowAxis]] -
+ paddingAndBorderAxisResolvedRow;
+ } else {
+ maxWidth = parentMaxWidth -
+ getMarginAxis(node, resolvedRowAxis) -
+ paddingAndBorderAxisResolvedRow;
+ }
+ }
+
+ // This is the main recursive call. We layout non flexible children.
+ if (alreadyComputedNextLayout === 0) {
+ layoutNode(/*(java)!layoutContext, */child, maxWidth, direction);
+ }
+
+ // Absolute positioned elements do not take part of the layout, so we
+ // don't use them to compute mainContentDim
+ if (getPositionType(child) === CSS_POSITION_RELATIVE) {
+ nonFlexibleChildrenCount++;
+ // At this point we know the final size and margin of the element.
+ nextContentDim = getDimWithMargin(child, mainAxis);
+ }
+ }
+
+ // The element we are about to add would make us go to the next line
+ if (isNodeFlexWrap &&
+ isMainDimDefined &&
+ mainContentDim + nextContentDim > definedMainDim &&
+ // If there's only one element, then it's bigger than the content
+ // and needs its own line
+ i !== startLine) {
+ nonFlexibleChildrenCount--;
+ alreadyComputedNextLayout = 1;
+ break;
+ }
+
+ // Disable simple stacking in the main axis for the current line as
+ // we found a non-trivial child. The remaining children will be laid out
+ // in .
+ if (isSimpleStackMain &&
+ (getPositionType(child) !== CSS_POSITION_RELATIVE || isFlex(child))) {
+ isSimpleStackMain = false;
+ firstComplexMain = i;
+ }
+
+ // Disable simple stacking in the cross axis for the current line as
+ // we found a non-trivial child. The remaining children will be laid out
+ // in .
+ if (isSimpleStackCross &&
+ (getPositionType(child) !== CSS_POSITION_RELATIVE ||
+ (alignItem !== CSS_ALIGN_STRETCH && alignItem !== CSS_ALIGN_FLEX_START) ||
+ isUndefined(child.layout[dim[crossAxis]]))) {
+ isSimpleStackCross = false;
+ firstComplexCross = i;
+ }
+
+ if (isSimpleStackMain) {
+ child.layout[pos[mainAxis]] += mainDim;
+ if (isMainDimDefined) {
+ setTrailingPosition(node, child, mainAxis);
+ }
+
+ mainDim += getDimWithMargin(child, mainAxis);
+ crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis)));
+ }
+
+ if (isSimpleStackCross) {
+ child.layout[pos[crossAxis]] += linesCrossDim + leadingPaddingAndBorderCross;
+ if (isCrossDimDefined) {
+ setTrailingPosition(node, child, crossAxis);
+ }
+ }
+
+ alreadyComputedNextLayout = 0;
+ mainContentDim += nextContentDim;
+ endLine = i + 1;
+ }
+
+ // Layout flexible children and allocate empty space
+
+ // In order to position the elements in the main axis, we have two
+ // controls. The space between the beginning and the first element
+ // and the space between each two elements.
+ var/*float*/ leadingMainDim = 0;
+ var/*float*/ betweenMainDim = 0;
+
+ // The remaining available space that needs to be allocated
+ var/*float*/ remainingMainDim = 0;
+ if (isMainDimDefined) {
+ remainingMainDim = definedMainDim - mainContentDim;
+ } else {
+ remainingMainDim = fmaxf(mainContentDim, 0) - mainContentDim;
+ }
+
+ // If there are flexible children in the mix, they are going to fill the
+ // remaining space
+ if (flexibleChildrenCount !== 0) {
+ var/*float*/ flexibleMainDim = remainingMainDim / totalFlexible;
+ var/*float*/ baseMainDim;
+ var/*float*/ boundMainDim;
+
+ // If the flex share of remaining space doesn't meet min/max bounds,
+ // remove this child from flex calculations.
+ currentFlexChild = firstFlexChild;
+ while (currentFlexChild !== null) {
+ baseMainDim = flexibleMainDim * currentFlexChild.style.flex +
+ getPaddingAndBorderAxis(currentFlexChild, mainAxis);
+ boundMainDim = boundAxis(currentFlexChild, mainAxis, baseMainDim);
+
+ if (baseMainDim !== boundMainDim) {
+ remainingMainDim -= boundMainDim;
+ totalFlexible -= currentFlexChild.style.flex;
+ }
+
+ currentFlexChild = currentFlexChild.nextFlexChild;
+ }
+ flexibleMainDim = remainingMainDim / totalFlexible;
+
+ // The non flexible children can overflow the container, in this case
+ // we should just assume that there is no space available.
+ if (flexibleMainDim < 0) {
+ flexibleMainDim = 0;
+ }
+
+ currentFlexChild = firstFlexChild;
+ while (currentFlexChild !== null) {
+ // At this point we know the final size of the element in the main
+ // dimension
+ currentFlexChild.layout[dim[mainAxis]] = boundAxis(currentFlexChild, mainAxis,
+ flexibleMainDim * currentFlexChild.style.flex +
+ getPaddingAndBorderAxis(currentFlexChild, mainAxis)
+ );
+
+ maxWidth = CSS_UNDEFINED;
+ if (isDimDefined(node, resolvedRowAxis)) {
+ maxWidth = node.layout[dim[resolvedRowAxis]] -
+ paddingAndBorderAxisResolvedRow;
+ } else if (!isMainRowDirection) {
+ maxWidth = parentMaxWidth -
+ getMarginAxis(node, resolvedRowAxis) -
+ paddingAndBorderAxisResolvedRow;
+ }
+
+ // And we recursively call the layout algorithm for this child
+ layoutNode(/*(java)!layoutContext, */currentFlexChild, maxWidth, direction);
+
+ child = currentFlexChild;
+ currentFlexChild = currentFlexChild.nextFlexChild;
+ child.nextFlexChild = null;
+ }
+
+ // We use justifyContent to figure out how to allocate the remaining
+ // space available
+ } else if (justifyContent !== CSS_JUSTIFY_FLEX_START) {
+ if (justifyContent === CSS_JUSTIFY_CENTER) {
+ leadingMainDim = remainingMainDim / 2;
+ } else if (justifyContent === CSS_JUSTIFY_FLEX_END) {
+ leadingMainDim = remainingMainDim;
+ } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) {
+ remainingMainDim = fmaxf(remainingMainDim, 0);
+ if (flexibleChildrenCount + nonFlexibleChildrenCount - 1 !== 0) {
+ betweenMainDim = remainingMainDim /
+ (flexibleChildrenCount + nonFlexibleChildrenCount - 1);
+ } else {
+ betweenMainDim = 0;
+ }
+ } else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) {
+ // Space on the edges is half of the space between elements
+ betweenMainDim = remainingMainDim /
+ (flexibleChildrenCount + nonFlexibleChildrenCount);
+ leadingMainDim = betweenMainDim / 2;
+ }
+ }
+
+ // Position elements in the main axis and compute dimensions
+
+ // At this point, all the children have their dimensions set. We need to
+ // find their position. In order to do that, we accumulate data in
+ // variables that are also useful to compute the total dimensions of the
+ // container!
+ mainDim += leadingMainDim;
+
+ for (i = firstComplexMain; i < endLine; ++i) {
+ child = node.children[i];
+
+ if (getPositionType(child) === CSS_POSITION_ABSOLUTE &&
+ isPosDefined(child, leading[mainAxis])) {
+ // In case the child is position absolute and has left/top being
+ // defined, we override the position to whatever the user said
+ // (and margin/border).
+ child.layout[pos[mainAxis]] = getPosition(child, leading[mainAxis]) +
+ getLeadingBorder(node, mainAxis) +
+ getLeadingMargin(child, mainAxis);
+ } else {
+ // If the child is position absolute (without top/left) or relative,
+ // we put it at the current accumulated offset.
+ child.layout[pos[mainAxis]] += mainDim;
+
+ // Define the trailing position accordingly.
+ if (isMainDimDefined) {
+ setTrailingPosition(node, child, mainAxis);
+ }
+
+ // Now that we placed the element, we need to update the variables
+ // We only need to do that for relative elements. Absolute elements
+ // do not take part in that phase.
+ if (getPositionType(child) === CSS_POSITION_RELATIVE) {
+ // The main dimension is the sum of all the elements dimension plus
+ // the spacing.
+ mainDim += betweenMainDim + getDimWithMargin(child, mainAxis);
+ // The cross dimension is the max of the elements dimension since there
+ // can only be one element in that cross dimension.
+ crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis)));
+ }
+ }
+ }
+
+ var/*float*/ containerCrossAxis = node.layout[dim[crossAxis]];
+ if (!isCrossDimDefined) {
+ containerCrossAxis = fmaxf(
+ // For the cross dim, we add both sides at the end because the value
+ // is aggregate via a max function. Intermediate negative values
+ // can mess this computation otherwise
+ boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross),
+ paddingAndBorderAxisCross
+ );
+ }
+
+ // Position elements in the cross axis
+ for (i = firstComplexCross; i < endLine; ++i) {
+ child = node.children[i];
+
+ if (getPositionType(child) === CSS_POSITION_ABSOLUTE &&
+ isPosDefined(child, leading[crossAxis])) {
+ // In case the child is absolutely positionned and has a
+ // top/left/bottom/right being set, we override all the previously
+ // computed positions to set it correctly.
+ child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) +
+ getLeadingBorder(node, crossAxis) +
+ getLeadingMargin(child, crossAxis);
+
+ } else {
+ var/*float*/ leadingCrossDim = leadingPaddingAndBorderCross;
+
+ // For a relative children, we're either using alignItems (parent) or
+ // alignSelf (child) in order to determine the position in the cross axis
+ if (getPositionType(child) === CSS_POSITION_RELATIVE) {
+ // This variable is intentionally re-defined as the code is transpiled to a block scope language
+ var/*css_align_t*/ alignItem = getAlignItem(node, child);
+ if (alignItem === CSS_ALIGN_STRETCH) {
+ // You can only stretch if the dimension has not already been set
+ // previously.
+ if (isUndefined(child.layout[dim[crossAxis]])) {
+ child.layout[dim[crossAxis]] = fmaxf(
+ boundAxis(child, crossAxis, containerCrossAxis -
+ paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)),
+ // You never want to go smaller than padding
+ getPaddingAndBorderAxis(child, crossAxis)
+ );
+ }
+ } else if (alignItem !== CSS_ALIGN_FLEX_START) {
+ // The remaining space between the parent dimensions+padding and child
+ // dimensions+margin.
+ var/*float*/ remainingCrossDim = containerCrossAxis -
+ paddingAndBorderAxisCross - getDimWithMargin(child, crossAxis);
+
+ if (alignItem === CSS_ALIGN_CENTER) {
+ leadingCrossDim += remainingCrossDim / 2;
+ } else { // CSS_ALIGN_FLEX_END
+ leadingCrossDim += remainingCrossDim;
+ }
+ }
+ }
+
+ // And we apply the position
+ child.layout[pos[crossAxis]] += linesCrossDim + leadingCrossDim;
+
+ // Define the trailing position accordingly.
+ if (isCrossDimDefined) {
+ setTrailingPosition(node, child, crossAxis);
+ }
+ }
+ }
+
+ linesCrossDim += crossDim;
+ linesMainDim = fmaxf(linesMainDim, mainDim);
+ linesCount += 1;
+ startLine = endLine;
+ }
+
+ //
+ //
+ // Note(prenaux): More than one line, we need to layout the crossAxis
+ // according to alignContent.
+ //
+ // Note that we could probably remove and handle the one line case
+ // here too, but for the moment this is safer since it won't interfere with
+ // previously working code.
+ //
+ // See specs:
+ // http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm
+ // section 9.4
+ //
+ if (linesCount > 1 && isCrossDimDefined) {
+ var/*float*/ nodeCrossAxisInnerSize = node.layout[dim[crossAxis]] -
+ paddingAndBorderAxisCross;
+ var/*float*/ remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim;
+
+ var/*float*/ crossDimLead = 0;
+ var/*float*/ currentLead = leadingPaddingAndBorderCross;
+
+ var/*css_align_t*/ alignContent = getAlignContent(node);
+ if (alignContent === CSS_ALIGN_FLEX_END) {
+ currentLead += remainingAlignContentDim;
+ } else if (alignContent === CSS_ALIGN_CENTER) {
+ currentLead += remainingAlignContentDim / 2;
+ } else if (alignContent === CSS_ALIGN_STRETCH) {
+ if (nodeCrossAxisInnerSize > linesCrossDim) {
+ crossDimLead = (remainingAlignContentDim / linesCount);
+ }
+ }
+
+ var/*int*/ endIndex = 0;
+ for (i = 0; i < linesCount; ++i) {
+ var/*int*/ startIndex = endIndex;
+
+ // compute the line's height and find the endIndex
+ var/*float*/ lineHeight = 0;
+ for (ii = startIndex; ii < childCount; ++ii) {
+ child = node.children[ii];
+ if (getPositionType(child) !== CSS_POSITION_RELATIVE) {
+ continue;
+ }
+ if (child.lineIndex !== i) {
+ break;
+ }
+ if (!isUndefined(child.layout[dim[crossAxis]])) {
+ lineHeight = fmaxf(
+ lineHeight,
+ child.layout[dim[crossAxis]] + getMarginAxis(child, crossAxis)
+ );
+ }
+ }
+ endIndex = ii;
+ lineHeight += crossDimLead;
+
+ for (ii = startIndex; ii < endIndex; ++ii) {
+ child = node.children[ii];
+ if (getPositionType(child) !== CSS_POSITION_RELATIVE) {
+ continue;
+ }
+
+ var/*css_align_t*/ alignContentAlignItem = getAlignItem(node, child);
+ if (alignContentAlignItem === CSS_ALIGN_FLEX_START) {
+ child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);
+ } else if (alignContentAlignItem === CSS_ALIGN_FLEX_END) {
+ child.layout[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child.layout[dim[crossAxis]];
+ } else if (alignContentAlignItem === CSS_ALIGN_CENTER) {
+ var/*float*/ childHeight = child.layout[dim[crossAxis]];
+ child.layout[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2;
+ } else if (alignContentAlignItem === CSS_ALIGN_STRETCH) {
+ child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);
+ // TODO(prenaux): Correctly set the height of items with undefined
+ // (auto) crossAxis dimension.
+ }
+ }
+
+ currentLead += lineHeight;
+ }
+ }
+
+ var/*bool*/ needsMainTrailingPos = false;
+ var/*bool*/ needsCrossTrailingPos = false;
+
+ // If the user didn't specify a width or height, and it has not been set
+ // by the container, then we set it via the children.
+ if (!isMainDimDefined) {
+ node.layout[dim[mainAxis]] = fmaxf(
+ // We're missing the last padding at this point to get the final
+ // dimension
+ boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)),
+ // We can never assign a width smaller than the padding and borders
+ paddingAndBorderAxisMain
+ );
+
+ if (mainAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||
+ mainAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {
+ needsMainTrailingPos = true;
+ }
+ }
+
+ if (!isCrossDimDefined) {
+ node.layout[dim[crossAxis]] = fmaxf(
+ // For the cross dim, we add both sides at the end because the value
+ // is aggregate via a max function. Intermediate negative values
+ // can mess this computation otherwise
+ boundAxis(node, crossAxis, linesCrossDim + paddingAndBorderAxisCross),
+ paddingAndBorderAxisCross
+ );
+
+ if (crossAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||
+ crossAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {
+ needsCrossTrailingPos = true;
+ }
+ }
+
+ // Set trailing position if necessary
+ if (needsMainTrailingPos || needsCrossTrailingPos) {
+ for (i = 0; i < childCount; ++i) {
+ child = node.children[i];
+
+ if (needsMainTrailingPos) {
+ setTrailingPosition(node, child, mainAxis);
+ }
+
+ if (needsCrossTrailingPos) {
+ setTrailingPosition(node, child, crossAxis);
+ }
+ }
+ }
+
+ // Calculate dimensions for absolutely positioned elements
+ currentAbsoluteChild = firstAbsoluteChild;
+ while (currentAbsoluteChild !== null) {
+ // Pre-fill dimensions when using absolute position and both offsets for
+ // the axis are defined (either both left and right or top and bottom).
+ for (ii = 0; ii < 2; ii++) {
+ axis = (ii !== 0) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
+
+ if (!isUndefined(node.layout[dim[axis]]) &&
+ !isDimDefined(currentAbsoluteChild, axis) &&
+ isPosDefined(currentAbsoluteChild, leading[axis]) &&
+ isPosDefined(currentAbsoluteChild, trailing[axis])) {
+ currentAbsoluteChild.layout[dim[axis]] = fmaxf(
+ boundAxis(currentAbsoluteChild, axis, node.layout[dim[axis]] -
+ getBorderAxis(node, axis) -
+ getMarginAxis(currentAbsoluteChild, axis) -
+ getPosition(currentAbsoluteChild, leading[axis]) -
+ getPosition(currentAbsoluteChild, trailing[axis])
+ ),
+ // You never want to go smaller than padding
+ getPaddingAndBorderAxis(currentAbsoluteChild, axis)
+ );
+ }
+
+ if (isPosDefined(currentAbsoluteChild, trailing[axis]) &&
+ !isPosDefined(currentAbsoluteChild, leading[axis])) {
+ currentAbsoluteChild.layout[leading[axis]] =
+ node.layout[dim[axis]] -
+ currentAbsoluteChild.layout[dim[axis]] -
+ getPosition(currentAbsoluteChild, trailing[axis]);
+ }
+ }
+
+ child = currentAbsoluteChild;
+ currentAbsoluteChild = currentAbsoluteChild.nextAbsoluteChild;
+ child.nextAbsoluteChild = null;
+ }
+ }
+
+ function layoutNode(node, parentMaxWidth, parentDirection) {
+ node.shouldUpdate = true;
+
+ var direction = node.style.direction || CSS_DIRECTION_LTR;
+ var skipLayout =
+ !node.isDirty &&
+ node.lastLayout &&
+ node.lastLayout.requestedHeight === node.layout.height &&
+ node.lastLayout.requestedWidth === node.layout.width &&
+ node.lastLayout.parentMaxWidth === parentMaxWidth &&
+ node.lastLayout.direction === direction;
+
+ if (skipLayout) {
+ node.layout.width = node.lastLayout.width;
+ node.layout.height = node.lastLayout.height;
+ node.layout.top = node.lastLayout.top;
+ node.layout.left = node.lastLayout.left;
+ } else {
+ if (!node.lastLayout) {
+ node.lastLayout = {};
+ }
+
+ node.lastLayout.requestedWidth = node.layout.width;
+ node.lastLayout.requestedHeight = node.layout.height;
+ node.lastLayout.parentMaxWidth = parentMaxWidth;
+ node.lastLayout.direction = direction;
+
+ // Reset child layouts
+ node.children.forEach(function(child) {
+ child.layout.width = undefined;
+ child.layout.height = undefined;
+ child.layout.top = 0;
+ child.layout.left = 0;
+ });
+
+ layoutNodeImpl(node, parentMaxWidth, parentDirection);
+
+ node.lastLayout.width = node.layout.width;
+ node.lastLayout.height = node.layout.height;
+ node.lastLayout.top = node.layout.top;
+ node.lastLayout.left = node.layout.left;
+ }
+ }
+
+ return {
+ layoutNodeImpl: layoutNodeImpl,
+ computeLayout: layoutNode,
+ fillNodes: fillNodes
+ };
+})();
+
+export default function(node) {
+ // disabling ESLint because this code relies on the above include
+ computeLayout.fillNodes(node);
+ computeLayout.computeLayout(node);
+};
diff --git a/node_modules/widget-ui/src/element.ts b/node_modules/widget-ui/src/element.ts
new file mode 100644
index 0000000..4677bc0
--- /dev/null
+++ b/node_modules/widget-ui/src/element.ts
@@ -0,0 +1,172 @@
+
+import computeLayout from "./css-layout";
+import { getDefaultStyle, scalableStyles, layoutAffectedStyles } from "./style";
+
+type LayoutData = {
+ left: number,
+ top: number,
+ width: number,
+ height: number
+};
+
+type LayoutNode = {
+ id: number,
+ style: Object,
+ children: LayoutNode[],
+ layout?: LayoutData
+};
+
+let uuid = 0;
+
+class Element {
+ public static uuid(): number {
+ return uuid++;
+ }
+
+ public parent: Element | null = null;
+ public id: number = Element.uuid();
+ public style: { [key: string]: any } = {};
+ public computedStyle: { [key: string]: any } = {};
+ public lastComputedStyle: { [key: string]: any } = {};
+ public children: { [key: string]: Element } = {};
+ public layoutBox: LayoutData = { left: 0, top: 0, width: 0, height: 0 };
+
+ constructor(style: { [key: string]: any } = {}) {
+ // 拷贝一份,防止被外部逻辑修改
+ style = Object.assign(getDefaultStyle(), style);
+ this.computedStyle = Object.assign(getDefaultStyle(), style);
+ this.lastComputedStyle = Object.assign(getDefaultStyle(), style);
+
+ Object.keys(style).forEach(key => {
+ Object.defineProperty(this.style, key, {
+ configurable: true,
+ enumerable: true,
+ get: () => style[key],
+ set: (value: any) => {
+ if (value === style[key] || value === undefined) {
+ return;
+ }
+
+ this.lastComputedStyle = this.computedStyle[key]
+ style[key] = value
+ this.computedStyle[key] = value
+
+ // 如果设置的是一个可缩放的属性, 计算自己
+ if (scalableStyles.includes(key) && this.style.scale) {
+ this.computedStyle[key] = value * this.style.scale
+ }
+
+ // 如果设置的是 scale, 则把所有可缩放的属性计算
+ if (key === "scale") {
+ scalableStyles.forEach(prop => {
+ if (style[prop]) {
+ this.computedStyle[prop] = style[prop] * value
+ }
+ })
+ }
+
+ if (key === "hidden") {
+ if (value) {
+ layoutAffectedStyles.forEach((key: string) => {
+ this.computedStyle[key] = 0;
+ });
+ } else {
+ layoutAffectedStyles.forEach((key: string) => {
+ this.computedStyle[key] = this.lastComputedStyle[key];
+ });
+ }
+ }
+ }
+ })
+ })
+
+ if (this.style.scale) {
+ scalableStyles.forEach((key: string) => {
+ if (this.style[key]) {
+ const computedValue = this.style[key] * this.style.scale;
+ this.computedStyle[key] = computedValue;
+ }
+ });
+ }
+
+ if (style.hidden) {
+ layoutAffectedStyles.forEach((key: string) => {
+ this.computedStyle[key] = 0;
+ });
+ }
+ }
+
+ getAbsolutePosition(element: Element) {
+ if (!element) {
+ return this.getAbsolutePosition(this)
+ }
+
+ if (!element.parent) {
+ return {
+ left: 0,
+ top: 0
+ }
+ }
+
+ const {left, top} = this.getAbsolutePosition(element.parent)
+
+ return {
+ left: left + element.layoutBox.left,
+ top: top + element.layoutBox.top
+ }
+ }
+
+ public add(element: Element) {
+ element.parent = this;
+ this.children[element.id] = element;
+ }
+
+ public remove(element?: Element) {
+ // 删除自己
+ if (!element) {
+ Object.keys(this.children).forEach(id => {
+ const child = this.children[id]
+ child.remove()
+ delete this.children[id]
+ })
+ } else if (this.children[element.id]) {
+ // 是自己的子节点才删除
+ element.remove()
+ delete this.children[element.id];
+ }
+ }
+
+ public getNodeTree(): LayoutNode {
+ return {
+ id: this.id,
+ style: this.computedStyle,
+ children: Object.keys(this.children).map((id: string) => {
+ const child = this.children[id];
+ return child.getNodeTree();
+ })
+ }
+ }
+
+ public applyLayout(layoutNode: LayoutNode) {
+ ["left", "top", "width", "height"].forEach((key: string) => {
+ if (layoutNode.layout && typeof layoutNode.layout[key] === "number") {
+ this.layoutBox[key] = layoutNode.layout[key];
+ if (this.parent && (key === "left" || key === "top")) {
+ this.layoutBox[key] += this.parent.layoutBox[key];
+ }
+ }
+ });
+
+ layoutNode.children.forEach((child: LayoutNode) => {
+ this.children[child.id].applyLayout(child);
+ });
+ }
+
+ layout() {
+ const nodeTree = this.getNodeTree();
+ computeLayout(nodeTree);
+ this.applyLayout(nodeTree);
+ }
+}
+
+export default Element;
\ No newline at end of file
diff --git a/node_modules/widget-ui/src/event.ts b/node_modules/widget-ui/src/event.ts
new file mode 100644
index 0000000..fe41980
--- /dev/null
+++ b/node_modules/widget-ui/src/event.ts
@@ -0,0 +1,15 @@
+import _EventEmitter from "eventemitter3";
+const emitter = new _EventEmitter();
+export default class EventEmitter {
+ public emit(event: string, data?: any) {
+ emitter.emit(event, data);
+ }
+
+ public on(event: string, callback) {
+ emitter.on(event, callback);
+ }
+
+ public off(event: string, callback) {
+ emitter.off(event, callback);
+ }
+}
\ No newline at end of file
diff --git a/node_modules/widget-ui/src/style.ts b/node_modules/widget-ui/src/style.ts
new file mode 100644
index 0000000..7d595c2
--- /dev/null
+++ b/node_modules/widget-ui/src/style.ts
@@ -0,0 +1,87 @@
+const textStyles: string[] = ["color", "fontSize", "textAlign", "fontWeight", "lineHeight", "lineBreak"];
+
+const scalableStyles: string[] = ["left", "top", "right", "bottom", "width", "height",
+ "margin", "marginLeft", "marginRight", "marginTop", "marginBottom",
+ "padding", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom",
+ "borderWidth", "borderLeftWidth", "borderRightWidth", "borderTopWidth", "borderBottomWidth"];
+
+const layoutAffectedStyles: string[] = [
+ "margin", "marginTop", "marginBottom", "marginLeft", "marginRight",
+ "padding", "paddingTop", "paddingBottom", "paddingLeft", "paddingRight",
+ "width", "height"];
+
+type Style = {
+ left: number,
+ top: number,
+ right: number,
+ bottom: number,
+ width: number,
+ height: number,
+ maxWidth: number,
+ maxHeight: number,
+ minWidth: number,
+ minHeight: number,
+ margin: number,
+ marginLeft: number,
+ marginRight: number,
+ marginTop: number,
+ marginBottom: number,
+ padding: number,
+ paddingLeft: number,
+ paddingRight: number,
+ paddingTop: number,
+ paddingBottom: number,
+ borderWidth: number,
+ borderLeftWidth: number,
+ borderRightWidth: number,
+ borderTopWidth: number,
+ borderBottomWidth: number,
+ flexDirection: "column" | "row",
+ justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around",
+ alignItems: "flex-start" | "center" | "flex-end" | "stretch",
+ alignSelf: "flex-start" | "center" | "flex-end" | "stretch",
+ flex: number,
+ flexWrap: "wrap" | "nowrap",
+ position: "relative" | "absolute",
+
+ hidden: boolean,
+ scale: number
+}
+
+const getDefaultStyle = () => ({
+ left: undefined,
+ top: undefined,
+ right: undefined,
+ bottom: undefined,
+ width: undefined,
+ height: undefined,
+ maxWidth: undefined,
+ maxHeight: undefined,
+ minWidth: undefined,
+ minHeight: undefined,
+ margin: undefined,
+ marginLeft: undefined,
+ marginRight: undefined,
+ marginTop: undefined,
+ marginBottom: undefined,
+ padding: undefined,
+ paddingLeft: undefined,
+ paddingRight: undefined,
+ paddingTop: undefined,
+ paddingBottom: undefined,
+ borderWidth: undefined,
+ flexDirection: undefined,
+ justifyContent: undefined,
+ alignItems: undefined,
+ alignSelf: undefined,
+ flex: undefined,
+ flexWrap: undefined,
+ position: undefined,
+
+ hidden: false,
+ scale: 1
+})
+
+export {
+ getDefaultStyle, scalableStyles, textStyles, layoutAffectedStyles
+}
diff --git a/node_modules/widget-ui/test/css-layout.test.ts b/node_modules/widget-ui/test/css-layout.test.ts
new file mode 100644
index 0000000..9657d2c
--- /dev/null
+++ b/node_modules/widget-ui/test/css-layout.test.ts
@@ -0,0 +1,183 @@
+
+import Element from "../src/element";
+
+test("layout", () => {
+ const container = new Element({
+ width: 100,
+ height: 100,
+ padding: 10,
+ borderWidth: 2
+ })
+
+ const div1 = new Element({
+ left: 5,
+ top: 5,
+ width: 14,
+ height: 14
+ })
+
+ container.add(div1);
+ container.layout();
+ // css-layout 是 border-box
+ expect(container.layoutBox.left).toBe(0);
+ expect(container.layoutBox.top).toBe(0);
+ expect(container.layoutBox.width).toBe(100);
+ expect(container.layoutBox.height).toBe(100);
+
+ expect(div1.layoutBox.left).toBe(10 + 2 + 5);
+ expect(div1.layoutBox.top).toBe(10 + 2 + 5);
+ expect(div1.layoutBox.width).toBe(14);
+ expect(div1.layoutBox.height).toBe(14);
+});
+
+test("overflow", () => {
+ const container = new Element({
+ width: 100,
+ height: 100,
+ padding: 10,
+ borderWidth: 2
+ })
+
+ const div1 = new Element({
+ width: 114,
+ height: 114,
+ })
+
+ container.add(div1);
+ container.layout();
+
+ // 写死尺寸的情况下子元素不收缩父元素不撑开
+ expect(container.layoutBox.width).toBe(100);
+ expect(container.layoutBox.height).toBe(100);
+
+ expect(div1.layoutBox.left).toBe(10 + 2);
+ expect(div1.layoutBox.top).toBe(10 + 2);
+ expect(div1.layoutBox.width).toBe(114);
+ expect(div1.layoutBox.height).toBe(114);
+});
+
+test("right bottom", () => {
+ const container = new Element({
+ width: 100,
+ height: 100,
+ padding: 10,
+ borderWidth: 2
+ })
+
+ const div1 = new Element({
+ width: 14,
+ height: 14,
+ right: 13,
+ bottom: 9,
+ position: "absolute"
+ })
+
+ container.add(div1);
+ container.layout();
+
+ // right bottom 只有在 position 为 absolute 的情况下才有用
+ expect(container.layoutBox.width).toBe(100);
+ expect(container.layoutBox.height).toBe(100);
+
+ // 但这时就是以整个父元素为边界,而不是 border + padding 后的边界
+ expect(div1.layoutBox.left).toBe(100 - 13 - 14);
+ expect(div1.layoutBox.top).toBe(100 - 9 - 14);
+});
+
+test("flex center", () => {
+ const container = new Element({
+ width: 100,
+ height: 100,
+ padding: 10,
+ borderWidth: 2,
+ flexDirection: "row",
+ justifyContent: "center",
+ alignItems: "center"
+ })
+
+ const div1 = new Element({
+ width: 14,
+ height: 14
+ })
+
+ container.add(div1);
+ container.layout();
+ // 使用 flex 水平垂直居中
+ expect(div1.layoutBox.left).toBe((100 - 14)/2);
+ expect(div1.layoutBox.top).toBe((100 - 14)/2);
+})
+
+test("flex top bottom", () => {
+ const container = new Element({
+ width: 100,
+ height: 100,
+ padding: 10,
+ borderWidth: 2,
+ flexDirection: "column",
+ justifyContent: "space-between",
+ alignItems: "stretch"
+ })
+
+ // flex 实现一上一下两行水平填满
+ const div1 = new Element({
+ height: 10
+ })
+
+ const div2 = new Element({
+ height: 20
+ })
+
+ container.add(div1);
+ container.add(div2);
+ container.layout();
+
+ expect(div1.layoutBox.left).toBe(10 + 2);
+ expect(div1.layoutBox.top).toBe(10 + 2);
+ expect(div1.layoutBox.width).toBe(100 - 10*2 - 2*2);
+
+ expect(div2.layoutBox.left).toBe(10 + 2);
+ expect(div2.layoutBox.top).toBe(100 - 10 - 2 - 20);
+ expect(div2.layoutBox.width).toBe(100 - 10*2 - 2*2);
+})
+
+test("rewrite uuid", () => {
+ // 小程序为了保证 webview 和 service 侧的 coverview 不冲突,所以设置了不同的自增起点
+ // uuid 静态方法就是为了根据不同的需求去覆写
+ let uuid = 79648527;
+ Element.uuid = () => uuid++;
+ const container = new Element();
+ expect(container.id).toEqual(79648527);
+ const div = new Element();
+ expect(div.id).toEqual(79648528);
+});
+
+test("absolute left top", () => {
+ const container = new Element({
+ width: 300,
+ height: 200,
+ flexDirection: 'row',
+ justifyContent: 'center',
+ alignItems: 'center'
+ })
+
+
+ const div1 = new Element({
+ width: 80,
+ height: 60
+ })
+
+ const div2 = new Element({
+ width: 40,
+ height: 30
+ })
+
+ div1.add(div2)
+ container.add(div1)
+ container.layout()
+
+ expect(div1.layoutBox.left).toBe(110)
+ expect(div1.layoutBox.top).toBe(70)
+
+ expect(div2.layoutBox.left).toBe(110)
+ expect(div2.layoutBox.top).toBe(70)
+})
\ No newline at end of file
diff --git a/node_modules/widget-ui/tsconfig.json b/node_modules/widget-ui/tsconfig.json
new file mode 100644
index 0000000..5e628f9
--- /dev/null
+++ b/node_modules/widget-ui/tsconfig.json
@@ -0,0 +1,47 @@
+{
+ "compilerOptions": {
+ "baseUrl": "src",
+ "resolveJsonModule": true,
+ "downlevelIteration": false,
+ "target": "es5",
+ "module": "commonjs",
+ "lib": [
+ "es5",
+ "es2015.promise",
+ "es2016",
+ "dom"
+ ],
+ "outDir": "./dist",
+ "paths": {
+ "@/*": [
+ "*"
+ ],
+ "*": [
+ "*"
+ ]
+ },
+ "typeRoots": [
+ "./node_modules/@types"
+ ],
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "declaration": true,
+ "stripInternal": true,
+ "experimentalDecorators": true,
+ "noImplicitReturns": true,
+ "alwaysStrict": true,
+ "noFallthroughCasesInSwitch": true,
+ "removeComments": false,
+ "strictNullChecks": true,
+ "strictFunctionTypes": true,
+ "skipLibCheck": true,
+ "pretty": true,
+ "strictPropertyInitialization": true
+ },
+ "include": [
+ "src/**/*.ts"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
\ No newline at end of file
diff --git a/node_modules/widget-ui/tslint.json b/node_modules/widget-ui/tslint.json
new file mode 100644
index 0000000..f6dac04
--- /dev/null
+++ b/node_modules/widget-ui/tslint.json
@@ -0,0 +1,206 @@
+{
+ "defaultSeverity": "error",
+ "extends": [],
+ "rules": {
+ "adjacent-overload-signatures": true,
+ "align": {
+ "options": [
+ "parameters",
+ "statements"
+ ]
+ },
+ "arrow-return-shorthand": true,
+ "ban-types": {
+ "options": [
+ [
+ "Object",
+ "Avoid using the `Object` type. Did you mean `object`?"
+ ],
+ [
+ "Function",
+ "Avoid using the `Function` type. Prefer a specific function type, like `() => void`."
+ ],
+ [
+ "Boolean",
+ "Avoid using the `Boolean` type. Did you mean `boolean`?"
+ ],
+ [
+ "Number",
+ "Avoid using the `Number` type. Did you mean `number`?"
+ ],
+ [
+ "String",
+ "Avoid using the `String` type. Did you mean `string`?"
+ ],
+ [
+ "Symbol",
+ "Avoid using the `Symbol` type. Did you mean `symbol`?"
+ ]
+ ]
+ },
+ "comment-format": {
+ "options": [
+ "check-space"
+ ]
+ },
+ "curly": {
+ "options": [
+ "ignore-same-line"
+ ]
+ },
+ "cyclomatic-complexity": false,
+ "import-spacing": true,
+ "indent": {
+ "options": [
+ "spaces"
+ ]
+ },
+ "interface-over-type-literal": true,
+ "member-ordering": [
+ true,
+ {
+ "order": [
+ "public-static-field",
+ "public-instance-field",
+ "private-static-field",
+ "private-instance-field",
+ "public-constructor",
+ "private-constructor",
+ "public-instance-method",
+ "protected-instance-method",
+ "private-instance-method"
+ ],
+ "alphabetize": false
+ }
+ ],
+ "no-angle-bracket-type-assertion": true,
+ "no-arg": true,
+ "no-conditional-assignment": true,
+ "no-debugger": true,
+ "no-duplicate-super": true,
+ "no-eval": true,
+ "no-internal-module": true,
+ "no-misused-new": true,
+ "no-reference-import": true,
+ "no-string-literal": true,
+ "no-string-throw": true,
+ "no-unnecessary-initializer": true,
+ "no-unsafe-finally": true,
+ "no-unused-expression": true,
+ "no-use-before-declare": false,
+ "no-var-keyword": true,
+ "no-var-requires": true,
+ "one-line": {
+ "options": [
+ "check-catch",
+ "check-else",
+ "check-finally",
+ "check-open-brace",
+ "check-whitespace"
+ ]
+ },
+ "one-variable-per-declaration": {
+ "options": [
+ "ignore-for-loop"
+ ]
+ },
+ "ordered-imports": {
+ "options": {
+ "import-sources-order": "case-insensitive",
+ "module-source-path": "full",
+ "named-imports-order": "case-insensitive"
+ }
+ },
+ "prefer-const": true,
+ "prefer-for-of": false,
+ "quotemark": {
+ "options": [
+ "double",
+ "avoid-escape"
+ ]
+ },
+ "radix": true,
+ "semicolon": {
+ "options": [
+ "always"
+ ]
+ },
+ "space-before-function-paren": {
+ "options": {
+ "anonymous": "never",
+ "asyncArrow": "always",
+ "constructor": "never",
+ "method": "never",
+ "named": "never"
+ }
+ },
+ "trailing-comma": {
+ "options": {
+ "esSpecCompliant": true,
+ "multiline": {
+ "objects": "always",
+ "arrays": "always",
+ "functions": "always",
+ "typeLiterals": "always"
+ },
+ "singleline": "never"
+ }
+ },
+ "triple-equals": {
+ "options": [
+ "allow-null-check"
+ ]
+ },
+ "typedef": false,
+ "typedef-whitespace": {
+ "options": [
+ {
+ "call-signature": "nospace",
+ "index-signature": "nospace",
+ "parameter": "nospace",
+ "property-declaration": "nospace",
+ "variable-declaration": "nospace"
+ },
+ {
+ "call-signature": "onespace",
+ "index-signature": "onespace",
+ "parameter": "onespace",
+ "property-declaration": "onespace",
+ "variable-declaration": "onespace"
+ }
+ ]
+ },
+ "typeof-compare": false,
+ "unified-signatures": true,
+ "use-isnan": true,
+ "whitespace": {
+ "options": [
+ "check-branch",
+ "check-decl",
+ "check-operator",
+ "check-separator",
+ "check-type",
+ "check-typecast"
+ ]
+ }
+ },
+ "jsRules": {},
+ "rulesDirectory": [],
+ "no-var-requires": false,
+ "trailing-comma": [
+ true,
+ {
+ "multiline": {
+ "objects": "always",
+ "arrays": "always",
+ "functions": "always",
+ "typeLiterals": "ignore"
+ },
+ "esSpecCompliant": true
+ }
+ ],
+ "no-unused-expression": [
+ true,
+ "allow-fast-null-checks"
+ ]
+}
\ No newline at end of file
diff --git a/node_modules/widget-ui/webpack.config.js b/node_modules/widget-ui/webpack.config.js
new file mode 100644
index 0000000..2a3a7e2
--- /dev/null
+++ b/node_modules/widget-ui/webpack.config.js
@@ -0,0 +1,25 @@
+const path = require("path");
+
+module.exports = {
+ mode: "production",
+ entry: path.resolve(__dirname, "src/element.ts"),
+ module: {
+ rules: [
+ {
+ test: /\.ts$/,
+ use: "ts-loader",
+ exclude: /node_modules/
+ }
+ ]
+ },
+ resolve: {
+ extensions: [".js", ".ts"]
+ },
+ output: {
+ filename: "index.js",
+ path: path.resolve(__dirname, "dist"),
+ libraryTarget: "umd", // 采用通用模块定义
+ libraryExport: "default", // 兼容 ES6(ES2015) 的模块系统、CommonJS 和 AMD 模块规范
+ globalObject: "this" // 兼容node和浏览器运行,避免window is not undefined情况
+ }
+};
\ No newline at end of file
diff --git a/node_modules/wxml-to-canvas/.babelrc b/node_modules/wxml-to-canvas/.babelrc
new file mode 100644
index 0000000..c062b77
--- /dev/null
+++ b/node_modules/wxml-to-canvas/.babelrc
@@ -0,0 +1,10 @@
+{
+ "plugins": [
+ ["module-resolver", {
+ "root": ["./src"],
+ "alias": {}
+ }],
+ "@babel/transform-runtime"
+ ],
+ "presets": ["@babel/preset-env"]
+}
\ No newline at end of file
diff --git a/node_modules/wxml-to-canvas/.eslintrc.js b/node_modules/wxml-to-canvas/.eslintrc.js
new file mode 100644
index 0000000..6576a30
--- /dev/null
+++ b/node_modules/wxml-to-canvas/.eslintrc.js
@@ -0,0 +1,99 @@
+module.exports = {
+ 'extends': [
+ 'airbnb-base',
+ 'plugin:promise/recommended'
+ ],
+ 'parserOptions': {
+ 'ecmaVersion': 9,
+ 'ecmaFeatures': {
+ 'jsx': false
+ },
+ 'sourceType': 'module'
+ },
+ 'env': {
+ 'es6': true,
+ 'node': true,
+ 'jest': true
+ },
+ 'plugins': [
+ 'import',
+ 'node',
+ 'promise'
+ ],
+ 'rules': {
+ 'arrow-parens': 'off',
+ 'comma-dangle': [
+ 'error',
+ 'only-multiline'
+ ],
+ 'complexity': ['error', 10],
+ 'func-names': 'off',
+ 'global-require': 'off',
+ 'handle-callback-err': [
+ 'error',
+ '^(err|error)$'
+ ],
+ 'import/no-unresolved': [
+ 'error',
+ {
+ 'caseSensitive': true,
+ 'commonjs': true,
+ 'ignore': ['^[^.]']
+ }
+ ],
+ 'import/prefer-default-export': 'off',
+ 'linebreak-style': 'off',
+ 'no-catch-shadow': 'error',
+ 'no-continue': 'off',
+ 'no-div-regex': 'warn',
+ 'no-else-return': 'off',
+ 'no-param-reassign': 'off',
+ 'no-plusplus': 'off',
+ 'no-shadow': 'off',
+ 'no-multi-assign': 'off',
+ 'no-underscore-dangle': 'off',
+ 'node/no-deprecated-api': 'error',
+ 'node/process-exit-as-throw': 'error',
+ 'object-curly-spacing': [
+ 'error',
+ 'never'
+ ],
+ 'operator-linebreak': [
+ 'error',
+ 'after',
+ {
+ 'overrides': {
+ ':': 'before',
+ '?': 'before'
+ }
+ }
+ ],
+ 'prefer-arrow-callback': 'off',
+ 'prefer-destructuring': 'off',
+ 'prefer-template': 'off',
+ 'quote-props': [
+ 1,
+ 'as-needed',
+ {
+ 'unnecessary': true
+ }
+ ],
+ 'semi': [
+ 'error',
+ 'never'
+ ],
+ 'no-await-in-loop': 'off',
+ 'no-restricted-syntax': 'off',
+ 'promise/always-return': 'off',
+ },
+ 'globals': {
+ 'window': true,
+ 'document': true,
+ 'App': true,
+ 'Page': true,
+ 'Component': true,
+ 'Behavior': true,
+ 'wx': true,
+ 'getCurrentPages': true,
+ }
+}
diff --git a/node_modules/wxml-to-canvas/LICENSE b/node_modules/wxml-to-canvas/LICENSE
new file mode 100644
index 0000000..3617210
--- /dev/null
+++ b/node_modules/wxml-to-canvas/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 wechat-miniprogram
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/node_modules/wxml-to-canvas/README.md b/node_modules/wxml-to-canvas/README.md
new file mode 100644
index 0000000..8ee64df
--- /dev/null
+++ b/node_modules/wxml-to-canvas/README.md
@@ -0,0 +1,187 @@
+# wxml-to-canvas
+
+[](https://www.npmjs.com/package/wxml-to-canvas)
+[](https://github.com/wechat-miniprogram/wxml-to-canvas)
+
+小程序内通过静态模板和样式绘制 canvas ,导出图片,可用于生成分享图等场景。[代码片段](https://developers.weixin.qq.com/s/r6UBlEm17pc6)
+
+
+## 使用方法
+
+#### Step1. npm 安装,参考 [小程序 npm 支持](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html)
+
+```
+npm install --save wxml-to-canvas
+```
+
+#### Step2. JSON 组件声明
+
+```
+{
+ "usingComponents": {
+ "wxml-to-canvas": "wxml-to-canvas",
+ }
+}
+```
+
+#### Step3. wxml 引入组件
+
+```
+
+
+```
+
+##### 属性列表
+
+| 属性 | 类型 | 默认值 | 必填 | 说明 |
+| --------------- | ------- | ------- | ---- | ---------------------- |
+| width | Number | 400 | 否 | 画布宽度 |
+| height | Number | 300 | 否 | 画布高度 |
+
+
+#### Step4. js 获取实例
+
+```
+const {wxml, style} = require('./demo.js')
+Page({
+ data: {
+ src: ''
+ },
+ onLoad() {
+ this.widget = this.selectComponent('.widget')
+ },
+ renderToCanvas() {
+ const p1 = this.widget.renderToCanvas({ wxml, style })
+ p1.then((res) => {
+ this.container = res
+ this.extraImage()
+ })
+ },
+ extraImage() {
+ const p2 = this.widget.canvasToTempFilePath()
+ p2.then(res => {
+ this.setData({
+ src: res.tempFilePath,
+ width: this.container.layoutBox.width,
+ height: this.container.layoutBox.height
+ })
+ })
+ }
+})
+```
+
+## wxml 模板
+
+支持 `view`、`text`、`image` 三种标签,通过 class 匹配 style 对象中的样式。
+
+```
+
+
+
+
+ yeah!
+
+
+
+
+
+```
+
+## 样式
+
+对象属性值为对应 wxml 标签的 cass 驼峰形式。**需为每个元素指定 width 和 height 属性**,否则会导致布局错误。
+
+存在多个 className 时,位置靠后的优先级更高,子元素会继承父级元素的可继承属性。
+
+元素均为 flex 布局。left/top 等 仅在 absolute 定位下生效。
+
+```
+const style = {
+ container: {
+ width: 300,
+ height: 200,
+ flexDirection: 'row',
+ justifyContent: 'space-around',
+ backgroundColor: '#ccc',
+ alignItems: 'center',
+ },
+ itemBox: {
+ width: 80,
+ height: 60,
+ },
+ red: {
+ backgroundColor: '#ff0000'
+ },
+ green: {
+ backgroundColor: '#00ff00'
+ },
+ blue: {
+ backgroundColor: '#0000ff'
+ },
+ text: {
+ width: 80,
+ height: 60,
+ textAlign: 'center',
+ verticalAlign: 'middle',
+ }
+}
+```
+
+## 接口
+
+#### f1. `renderToCanvas({wxml, style}): Promise`
+
+渲染到 canvas,传入 wxml 模板 和 style 对象,返回的容器对象包含布局和样式信息。
+
+#### f2. `canvasToTempFilePath({fileType, quality}): Promise`
+
+提取画布中容器所在区域内容生成相同大小的图片,返回临时文件地址。
+
+`fileType` 支持 `jpg`、`png` 两种格式,quality 为图片的质量,目前仅对 jpg 有效。取值范围为 (0, 1],不在范围内时当作 1.0 处理。
+
+## 支持的 css 属性
+
+### 布局相关
+
+| 属性名 | 支持的值或类型 | 默认值 |
+| --------------------- | --------------------------------------------------------- | ---------- |
+| width | number | 0 |
+| height | number | 0 |
+| position | relative, absolute | relative |
+| left | number | 0 |
+| top | number | 0 |
+| right | number | 0 |
+| bottom | number | 0 |
+| margin | number | 0 |
+| padding | number | 0 |
+| borderWidth | number | 0 |
+| borderRadius | number | 0 |
+| flexDirection | column, row | row |
+| flexShrink | number | 1 |
+| flexGrow | number | |
+| flexWrap | wrap, nowrap | nowrap |
+| justifyContent | flex-start, center, flex-end, space-between, space-around | flex-start |
+| alignItems, alignSelf | flex-start, center, flex-end, stretch | flex-start |
+
+支持 marginLeft、paddingLeft 等
+
+### 文字
+
+| 属性名 | 支持的值或类型 | 默认值 |
+| --------------- | ------------------- | ----------- |
+| fontSize | number | 14 |
+| lineHeight | number / string | '1.4em' |
+| textAlign | left, center, right | left |
+| verticalAlign | top, middle, bottom | top |
+| color | string | #000000 |
+| backgroundColor | string | transparent |
+
+lineHeight 可取带 em 单位的字符串或数字类型。
+
+### 变形
+
+| 属性名 | 支持的值或类型 | 默认值 |
+| ------ | -------------- | ------ |
+| scale | number | 1 |
diff --git a/node_modules/wxml-to-canvas/gulpfile.js b/node_modules/wxml-to-canvas/gulpfile.js
new file mode 100644
index 0000000..fb292c2
--- /dev/null
+++ b/node_modules/wxml-to-canvas/gulpfile.js
@@ -0,0 +1,26 @@
+const gulp = require('gulp')
+const clean = require('gulp-clean')
+
+const config = require('./tools/config')
+const BuildTask = require('./tools/build')
+const id = require('./package.json').name || 'miniprogram-custom-component'
+
+// 构建任务实例
+// eslint-disable-next-line no-new
+new BuildTask(id, config.entry)
+
+// 清空生成目录和文件
+gulp.task('clean', gulp.series(() => gulp.src(config.distPath, {read: false, allowEmpty: true}).pipe(clean()), done => {
+ if (config.isDev) {
+ return gulp.src(config.demoDist, {read: false, allowEmpty: true})
+ .pipe(clean())
+ }
+
+ return done()
+}))
+// 监听文件变化并进行开发模式构建
+gulp.task('watch', gulp.series(`${id}-watch`))
+// 开发模式构建
+gulp.task('dev', gulp.series(`${id}-dev`))
+// 生产模式构建
+gulp.task('default', gulp.series(`${id}-default`))
diff --git a/node_modules/wxml-to-canvas/miniprogram_dist/index.js b/node_modules/wxml-to-canvas/miniprogram_dist/index.js
new file mode 100644
index 0000000..2a4f21e
--- /dev/null
+++ b/node_modules/wxml-to-canvas/miniprogram_dist/index.js
@@ -0,0 +1,779 @@
+(function webpackUniversalModuleDefinition(root, factory) {
+ if(typeof exports === 'object' && typeof module === 'object')
+ module.exports = factory();
+ else if(typeof define === 'function' && define.amd)
+ define([], factory);
+ else {
+ var a = factory();
+ for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
+ }
+})(window, function() {
+return /******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId]) {
+/******/ return installedModules[moduleId].exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ i: moduleId,
+/******/ l: false,
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ // Flag the module as loaded
+/******/ module.l = true;
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/******/
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = modules;
+/******/
+/******/ // expose the module cache
+/******/ __webpack_require__.c = installedModules;
+/******/
+/******/ // define getter function for harmony exports
+/******/ __webpack_require__.d = function(exports, name, getter) {
+/******/ if(!__webpack_require__.o(exports, name)) {
+/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ }
+/******/ };
+/******/
+/******/ // define __esModule on exports
+/******/ __webpack_require__.r = function(exports) {
+/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ }
+/******/ Object.defineProperty(exports, '__esModule', { value: true });
+/******/ };
+/******/
+/******/ // create a fake namespace object
+/******/ // mode & 1: value is a module id, require it
+/******/ // mode & 2: merge all properties of value into the ns
+/******/ // mode & 4: return value when already ns object
+/******/ // mode & 8|1: behave like require
+/******/ __webpack_require__.t = function(value, mode) {
+/******/ if(mode & 1) value = __webpack_require__(value);
+/******/ if(mode & 8) return value;
+/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ var ns = Object.create(null);
+/******/ __webpack_require__.r(ns);
+/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ return ns;
+/******/ };
+/******/
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function getDefault() { return module['default']; } :
+/******/ function getModuleExports() { return module; };
+/******/ __webpack_require__.d(getter, 'a', getter);
+/******/ return getter;
+/******/ };
+/******/
+/******/ // Object.prototype.hasOwnProperty.call
+/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ // __webpack_public_path__
+/******/ __webpack_require__.p = "";
+/******/
+/******/
+/******/ // Load entry module and return exports
+/******/ return __webpack_require__(__webpack_require__.s = 1);
+/******/ })
+/************************************************************************/
+/******/ ([
+/* 0 */
+/***/ (function(module, exports) {
+
+const hex = (color) => {
+ let result = null
+
+ if (/^#/.test(color) && (color.length === 7 || color.length === 9)) {
+ return color
+ // eslint-disable-next-line no-cond-assign
+ } else if ((result = /^(rgb|rgba)\((.+)\)/.exec(color)) !== null) {
+ return '#' + result[2].split(',').map((part, index) => {
+ part = part.trim()
+ part = index === 3 ? Math.floor(parseFloat(part) * 255) : parseInt(part, 10)
+ part = part.toString(16)
+ if (part.length === 1) {
+ part = '0' + part
+ }
+ return part
+ }).join('')
+ } else {
+ return '#00000000'
+ }
+}
+
+const splitLineToCamelCase = (str) => str.split('-').map((part, index) => {
+ if (index === 0) {
+ return part
+ }
+ return part[0].toUpperCase() + part.slice(1)
+}).join('')
+
+const compareVersion = (v1, v2) => {
+ v1 = v1.split('.')
+ v2 = v2.split('.')
+ const len = Math.max(v1.length, v2.length)
+ while (v1.length < len) {
+ v1.push('0')
+ }
+ while (v2.length < len) {
+ v2.push('0')
+ }
+ for (let i = 0; i < len; i++) {
+ const num1 = parseInt(v1[i], 10)
+ const num2 = parseInt(v2[i], 10)
+
+ if (num1 > num2) {
+ return 1
+ } else if (num1 < num2) {
+ return -1
+ }
+ }
+
+ return 0
+}
+
+module.exports = {
+ hex,
+ splitLineToCamelCase,
+ compareVersion
+}
+
+
+/***/ }),
+/* 1 */
+/***/ (function(module, exports, __webpack_require__) {
+
+
+const xmlParse = __webpack_require__(2)
+const {Widget} = __webpack_require__(3)
+const {Draw} = __webpack_require__(5)
+const {compareVersion} = __webpack_require__(0)
+
+const canvasId = 'weui-canvas'
+
+Component({
+ properties: {
+ width: {
+ type: Number,
+ value: 400
+ },
+ height: {
+ type: Number,
+ value: 300
+ }
+ },
+ data: {
+ use2dCanvas: false, // 2.9.2 后可用canvas 2d 接口
+ },
+ lifetimes: {
+ attached() {
+ const {SDKVersion, pixelRatio: dpr} = wx.getSystemInfoSync()
+ const use2dCanvas = compareVersion(SDKVersion, '2.9.2') >= 0
+ this.dpr = dpr
+ this.setData({use2dCanvas}, () => {
+ if (use2dCanvas) {
+ const query = this.createSelectorQuery()
+ query.select(`#${canvasId}`)
+ .fields({node: true, size: true})
+ .exec(res => {
+ const canvas = res[0].node
+ const ctx = canvas.getContext('2d')
+ canvas.width = res[0].width * dpr
+ canvas.height = res[0].height * dpr
+ ctx.scale(dpr, dpr)
+ this.ctx = ctx
+ this.canvas = canvas
+ })
+ } else {
+ this.ctx = wx.createCanvasContext(canvasId, this)
+ }
+ })
+ }
+ },
+ methods: {
+ async renderToCanvas(args) {
+ const {wxml, style} = args
+ const ctx = this.ctx
+ const canvas = this.canvas
+ const use2dCanvas = this.data.use2dCanvas
+
+ if (use2dCanvas && !canvas) {
+ return Promise.reject(new Error('renderToCanvas: fail canvas has not been created'))
+ }
+
+ ctx.clearRect(0, 0, this.data.width, this.data.height)
+ const {root: xom} = xmlParse(wxml)
+
+ const widget = new Widget(xom, style)
+ const container = widget.init()
+ this.boundary = {
+ top: container.layoutBox.top,
+ left: container.layoutBox.left,
+ width: container.computedStyle.width,
+ height: container.computedStyle.height,
+ }
+ const draw = new Draw(ctx, canvas, use2dCanvas)
+ await draw.drawNode(container)
+
+ if (!use2dCanvas) {
+ await this.canvasDraw(ctx)
+ }
+ return Promise.resolve(container)
+ },
+
+ canvasDraw(ctx, reserve) {
+ return new Promise(resolve => {
+ ctx.draw(reserve, () => {
+ resolve()
+ })
+ })
+ },
+
+ canvasToTempFilePath(args = {}) {
+ const use2dCanvas = this.data.use2dCanvas
+
+ return new Promise((resolve, reject) => {
+ const {
+ top, left, width, height
+ } = this.boundary
+
+ const copyArgs = {
+ x: left,
+ y: top,
+ width,
+ height,
+ destWidth: width * this.dpr,
+ destHeight: height * this.dpr,
+ canvasId,
+ fileType: args.fileType || 'png',
+ quality: args.quality || 1,
+ success: resolve,
+ fail: reject
+ }
+
+ if (use2dCanvas) {
+ delete copyArgs.canvasId
+ copyArgs.canvas = this.canvas
+ }
+ wx.canvasToTempFilePath(copyArgs, this)
+ })
+ }
+ }
+})
+
+
+/***/ }),
+/* 2 */
+/***/ (function(module, exports) {
+
+
+/**
+ * Module dependencies.
+ */
+
+
+/**
+ * Expose `parse`.
+ */
+
+
+/**
+ * Parse the given string of `xml`.
+ *
+ * @param {String} xml
+ * @return {Object}
+ * @api public
+ */
+
+function parse(xml) {
+ xml = xml.trim()
+
+ // strip comments
+ xml = xml.replace(//g, '')
+
+ return document()
+
+ /**
+ * XML document.
+ */
+
+ function document() {
+ return {
+ declaration: declaration(),
+ root: tag()
+ }
+ }
+
+ /**
+ * Declaration.
+ */
+
+ function declaration() {
+ const m = match(/^<\?xml\s*/)
+ if (!m) return
+
+ // tag
+ const node = {
+ attributes: {}
+ }
+
+ // attributes
+ while (!(eos() || is('?>'))) {
+ const attr = attribute()
+ if (!attr) return node
+ node.attributes[attr.name] = attr.value
+ }
+
+ match(/\?>\s*/)
+
+ return node
+ }
+
+ /**
+ * Tag.
+ */
+
+ function tag() {
+ const m = match(/^<([\w-:.]+)\s*/)
+ if (!m) return
+
+ // name
+ const node = {
+ name: m[1],
+ attributes: {},
+ children: []
+ }
+
+ // attributes
+ while (!(eos() || is('>') || is('?>') || is('/>'))) {
+ const attr = attribute()
+ if (!attr) return node
+ node.attributes[attr.name] = attr.value
+ }
+
+ // self closing tag
+ if (match(/^\s*\/>\s*/)) {
+ return node
+ }
+
+ match(/\??>\s*/)
+
+ // content
+ node.content = content()
+
+ // children
+ let child
+ while (child = tag()) {
+ node.children.push(child)
+ }
+
+ // closing
+ match(/^<\/[\w-:.]+>\s*/)
+
+ return node
+ }
+
+ /**
+ * Text content.
+ */
+
+ function content() {
+ const m = match(/^([^<]*)/)
+ if (m) return m[1]
+ return ''
+ }
+
+ /**
+ * Attribute.
+ */
+
+ function attribute() {
+ const m = match(/([\w:-]+)\s*=\s*("[^"]*"|'[^']*'|\w+)\s*/)
+ if (!m) return
+ return {name: m[1], value: strip(m[2])}
+ }
+
+ /**
+ * Strip quotes from `val`.
+ */
+
+ function strip(val) {
+ return val.replace(/^['"]|['"]$/g, '')
+ }
+
+ /**
+ * Match `re` and advance the string.
+ */
+
+ function match(re) {
+ const m = xml.match(re)
+ if (!m) return
+ xml = xml.slice(m[0].length)
+ return m
+ }
+
+ /**
+ * End-of-source.
+ */
+
+ function eos() {
+ return xml.length == 0
+ }
+
+ /**
+ * Check for `prefix`.
+ */
+
+ function is(prefix) {
+ return xml.indexOf(prefix) == 0
+ }
+}
+
+module.exports = parse
+
+
+/***/ }),
+/* 3 */
+/***/ (function(module, exports, __webpack_require__) {
+
+const Block = __webpack_require__(4)
+const {splitLineToCamelCase} = __webpack_require__(0)
+
+class Element extends Block {
+ constructor(prop) {
+ super(prop.style)
+ this.name = prop.name
+ this.attributes = prop.attributes
+ }
+}
+
+
+class Widget {
+ constructor(xom, style) {
+ this.xom = xom
+ this.style = style
+
+ this.inheritProps = ['fontSize', 'lineHeight', 'textAlign', 'verticalAlign', 'color']
+ }
+
+ init() {
+ this.container = this.create(this.xom)
+ this.container.layout()
+
+ this.inheritStyle(this.container)
+ return this.container
+ }
+
+ // 继承父节点的样式
+ inheritStyle(node) {
+ const parent = node.parent || null
+ const children = node.children || {}
+ const computedStyle = node.computedStyle
+
+ if (parent) {
+ this.inheritProps.forEach(prop => {
+ computedStyle[prop] = computedStyle[prop] || parent.computedStyle[prop]
+ })
+ }
+
+ Object.values(children).forEach(child => {
+ this.inheritStyle(child)
+ })
+ }
+
+ create(node) {
+ let classNames = (node.attributes.class || '').split(' ')
+ classNames = classNames.map(item => splitLineToCamelCase(item.trim()))
+ const style = {}
+ classNames.forEach(item => {
+ Object.assign(style, this.style[item] || {})
+ })
+
+ const args = {name: node.name, style}
+
+ const attrs = Object.keys(node.attributes)
+ const attributes = {}
+ for (const attr of attrs) {
+ const value = node.attributes[attr]
+ const CamelAttr = splitLineToCamelCase(attr)
+
+ if (value === '' || value === 'true') {
+ attributes[CamelAttr] = true
+ } else if (value === 'false') {
+ attributes[CamelAttr] = false
+ } else {
+ attributes[CamelAttr] = value
+ }
+ }
+ attributes.text = node.content
+ args.attributes = attributes
+ const element = new Element(args)
+ node.children.forEach(childNode => {
+ const childElement = this.create(childNode)
+ element.add(childElement)
+ })
+ return element
+ }
+}
+
+module.exports = {Widget}
+
+
+/***/ }),
+/* 4 */
+/***/ (function(module, exports) {
+
+module.exports = require("widget-ui");
+
+/***/ }),
+/* 5 */
+/***/ (function(module, exports) {
+
+class Draw {
+ constructor(context, canvas, use2dCanvas = false) {
+ this.ctx = context
+ this.canvas = canvas || null
+ this.use2dCanvas = use2dCanvas
+ }
+
+ roundRect(x, y, w, h, r, fill = true, stroke = false) {
+ if (r < 0) return
+ const ctx = this.ctx
+
+ ctx.beginPath()
+ ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 3 / 2)
+ ctx.arc(x + w - r, y + r, r, Math.PI * 3 / 2, 0)
+ ctx.arc(x + w - r, y + h - r, r, 0, Math.PI / 2)
+ ctx.arc(x + r, y + h - r, r, Math.PI / 2, Math.PI)
+ ctx.lineTo(x, y + r)
+ if (stroke) ctx.stroke()
+ if (fill) ctx.fill()
+ }
+
+ drawView(box, style) {
+ const ctx = this.ctx
+ const {
+ left: x, top: y, width: w, height: h
+ } = box
+ const {
+ borderRadius = 0,
+ borderWidth = 0,
+ borderColor,
+ color = '#000',
+ backgroundColor = 'transparent',
+ } = style
+ ctx.save()
+ // 外环
+ if (borderWidth > 0) {
+ ctx.fillStyle = borderColor || color
+ this.roundRect(x, y, w, h, borderRadius)
+ }
+
+ // 内环
+ ctx.fillStyle = backgroundColor
+ const innerWidth = w - 2 * borderWidth
+ const innerHeight = h - 2 * borderWidth
+ const innerRadius = borderRadius - borderWidth >= 0 ? borderRadius - borderWidth : 0
+ this.roundRect(x + borderWidth, y + borderWidth, innerWidth, innerHeight, innerRadius)
+ ctx.restore()
+ }
+
+ async drawImage(img, box, style) {
+ await new Promise((resolve, reject) => {
+ const ctx = this.ctx
+ const canvas = this.canvas
+
+ const {
+ borderRadius = 0
+ } = style
+ const {
+ left: x, top: y, width: w, height: h
+ } = box
+ ctx.save()
+ this.roundRect(x, y, w, h, borderRadius, false, false)
+ ctx.clip()
+
+ const _drawImage = (img) => {
+ if (this.use2dCanvas) {
+ const Image = canvas.createImage()
+ Image.onload = () => {
+ ctx.drawImage(Image, x, y, w, h)
+ ctx.restore()
+ resolve()
+ }
+ Image.onerror = () => { reject(new Error(`createImage fail: ${img}`)) }
+ Image.src = img
+ } else {
+ ctx.drawImage(img, x, y, w, h)
+ ctx.restore()
+ resolve()
+ }
+ }
+
+ const isTempFile = /^wxfile:\/\//.test(img)
+ const isNetworkFile = /^https?:\/\//.test(img)
+
+ if (isTempFile) {
+ _drawImage(img)
+ } else if (isNetworkFile) {
+ wx.downloadFile({
+ url: img,
+ success(res) {
+ if (res.statusCode === 200) {
+ _drawImage(res.tempFilePath)
+ } else {
+ reject(new Error(`downloadFile:fail ${img}`))
+ }
+ },
+ fail() {
+ reject(new Error(`downloadFile:fail ${img}`))
+ }
+ })
+ } else {
+ reject(new Error(`image format error: ${img}`))
+ }
+ })
+ }
+
+ // eslint-disable-next-line complexity
+ drawText(text, box, style) {
+ const ctx = this.ctx
+ let {
+ left: x, top: y, width: w, height: h
+ } = box
+ let {
+ color = '#000',
+ lineHeight = '1.4em',
+ fontSize = 14,
+ textAlign = 'left',
+ verticalAlign = 'top',
+ backgroundColor = 'transparent'
+ } = style
+
+ if (typeof lineHeight === 'string') { // 2em
+ lineHeight = Math.ceil(parseFloat(lineHeight.replace('em')) * fontSize)
+ }
+ if (!text || (lineHeight > h)) return
+
+ ctx.save()
+ ctx.textBaseline = 'top'
+ ctx.font = `${fontSize}px sans-serif`
+ ctx.textAlign = textAlign
+
+ // 背景色
+ ctx.fillStyle = backgroundColor
+ this.roundRect(x, y, w, h, 0)
+
+ // 文字颜色
+ ctx.fillStyle = color
+
+ // 水平布局
+ switch (textAlign) {
+ case 'left':
+ break
+ case 'center':
+ x += 0.5 * w
+ break
+ case 'right':
+ x += w
+ break
+ default: break
+ }
+
+ const textWidth = ctx.measureText(text).width
+ const actualHeight = Math.ceil(textWidth / w) * lineHeight
+ let paddingTop = Math.ceil((h - actualHeight) / 2)
+ if (paddingTop < 0) paddingTop = 0
+
+ // 垂直布局
+ switch (verticalAlign) {
+ case 'top':
+ break
+ case 'middle':
+ y += paddingTop
+ break
+ case 'bottom':
+ y += 2 * paddingTop
+ break
+ default: break
+ }
+
+ const inlinePaddingTop = Math.ceil((lineHeight - fontSize) / 2)
+
+ // 不超过一行
+ if (textWidth <= w) {
+ ctx.fillText(text, x, y + inlinePaddingTop)
+ return
+ }
+
+ // 多行文本
+ const chars = text.split('')
+ const _y = y
+
+ // 逐行绘制
+ let line = ''
+ for (const ch of chars) {
+ const testLine = line + ch
+ const testWidth = ctx.measureText(testLine).width
+
+ if (testWidth > w) {
+ ctx.fillText(line, x, y + inlinePaddingTop)
+ y += lineHeight
+ line = ch
+ if ((y + lineHeight) > (_y + h)) break
+ } else {
+ line = testLine
+ }
+ }
+
+ // 避免溢出
+ if ((y + lineHeight) <= (_y + h)) {
+ ctx.fillText(line, x, y + inlinePaddingTop)
+ }
+ ctx.restore()
+ }
+
+ async drawNode(element) {
+ const {layoutBox, computedStyle, name} = element
+ const {src, text} = element.attributes
+ if (name === 'view') {
+ this.drawView(layoutBox, computedStyle)
+ } else if (name === 'image') {
+ await this.drawImage(src, layoutBox, computedStyle)
+ } else if (name === 'text') {
+ this.drawText(text, layoutBox, computedStyle)
+ }
+ const childs = Object.values(element.children)
+ for (const child of childs) {
+ await this.drawNode(child)
+ }
+ }
+}
+
+
+module.exports = {
+ Draw
+}
+
+
+/***/ })
+/******/ ]);
+});
\ No newline at end of file
diff --git a/node_modules/wxml-to-canvas/miniprogram_dist/index.json b/node_modules/wxml-to-canvas/miniprogram_dist/index.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/node_modules/wxml-to-canvas/miniprogram_dist/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/node_modules/wxml-to-canvas/miniprogram_dist/index.wxml b/node_modules/wxml-to-canvas/miniprogram_dist/index.wxml
new file mode 100644
index 0000000..a0010ad
--- /dev/null
+++ b/node_modules/wxml-to-canvas/miniprogram_dist/index.wxml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/node_modules/wxml-to-canvas/miniprogram_dist/index.wxss b/node_modules/wxml-to-canvas/miniprogram_dist/index.wxss
new file mode 100644
index 0000000..e69de29
diff --git a/node_modules/wxml-to-canvas/miniprogram_dist/utils.js b/node_modules/wxml-to-canvas/miniprogram_dist/utils.js
new file mode 100644
index 0000000..c3cf7d7
--- /dev/null
+++ b/node_modules/wxml-to-canvas/miniprogram_dist/utils.js
@@ -0,0 +1,57 @@
+const hex = (color) => {
+ let result = null
+
+ if (/^#/.test(color) && (color.length === 7 || color.length === 9)) {
+ return color
+ // eslint-disable-next-line no-cond-assign
+ } else if ((result = /^(rgb|rgba)\((.+)\)/.exec(color)) !== null) {
+ return '#' + result[2].split(',').map((part, index) => {
+ part = part.trim()
+ part = index === 3 ? Math.floor(parseFloat(part) * 255) : parseInt(part, 10)
+ part = part.toString(16)
+ if (part.length === 1) {
+ part = '0' + part
+ }
+ return part
+ }).join('')
+ } else {
+ return '#00000000'
+ }
+}
+
+const splitLineToCamelCase = (str) => str.split('-').map((part, index) => {
+ if (index === 0) {
+ return part
+ }
+ return part[0].toUpperCase() + part.slice(1)
+}).join('')
+
+const compareVersion = (v1, v2) => {
+ v1 = v1.split('.')
+ v2 = v2.split('.')
+ const len = Math.max(v1.length, v2.length)
+ while (v1.length < len) {
+ v1.push('0')
+ }
+ while (v2.length < len) {
+ v2.push('0')
+ }
+ for (let i = 0; i < len; i++) {
+ const num1 = parseInt(v1[i], 10)
+ const num2 = parseInt(v2[i], 10)
+
+ if (num1 > num2) {
+ return 1
+ } else if (num1 < num2) {
+ return -1
+ }
+ }
+
+ return 0
+}
+
+module.exports = {
+ hex,
+ splitLineToCamelCase,
+ compareVersion
+}
diff --git a/node_modules/wxml-to-canvas/package.json b/node_modules/wxml-to-canvas/package.json
new file mode 100644
index 0000000..54fe015
--- /dev/null
+++ b/node_modules/wxml-to-canvas/package.json
@@ -0,0 +1,91 @@
+{
+ "_from": "wxml-to-canvas",
+ "_id": "wxml-to-canvas@1.1.1",
+ "_inBundle": false,
+ "_integrity": "sha512-3mDjHzujY/UgdCOXij/MnmwJYerVjwkyQHMBFBE8zh89DK7h7UTzoydWFqEBjIC0rfZM+AXl5kDh9hUcsNpSmg==",
+ "_location": "/wxml-to-canvas",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "tag",
+ "registry": true,
+ "raw": "wxml-to-canvas",
+ "name": "wxml-to-canvas",
+ "escapedName": "wxml-to-canvas",
+ "rawSpec": "",
+ "saveSpec": null,
+ "fetchSpec": "latest"
+ },
+ "_requiredBy": [
+ "#USER",
+ "/"
+ ],
+ "_resolved": "https://registry.npmjs.org/wxml-to-canvas/-/wxml-to-canvas-1.1.1.tgz",
+ "_shasum": "64771473fb1e251bdad94f8c6ffa7dd64290e7ca",
+ "_spec": "wxml-to-canvas",
+ "_where": "/Users/WebTmm/Desktop/AGuestSaas",
+ "author": {
+ "name": "sanfordsun"
+ },
+ "bundleDependencies": false,
+ "dependencies": {
+ "widget-ui": "^1.0.2"
+ },
+ "deprecated": false,
+ "description": "[](https://www.npmjs.com/package/wxml-to-canvas) [](https://github.com/wechat-miniprogram/wxml-to-canvas)",
+ "devDependencies": {
+ "colors": "^1.3.1",
+ "eslint": "^5.14.1",
+ "eslint-config-airbnb-base": "13.1.0",
+ "eslint-loader": "^2.1.2",
+ "eslint-plugin-import": "^2.16.0",
+ "eslint-plugin-node": "^7.0.1",
+ "eslint-plugin-promise": "^3.8.0",
+ "gulp": "^4.0.0",
+ "gulp-clean": "^0.4.0",
+ "gulp-if": "^2.0.2",
+ "gulp-install": "^1.1.0",
+ "gulp-less": "^4.0.1",
+ "gulp-rename": "^1.4.0",
+ "gulp-sourcemaps": "^2.6.5",
+ "jest": "^23.5.0",
+ "miniprogram-simulate": "^1.0.0",
+ "through2": "^2.0.3",
+ "vinyl": "^2.2.0",
+ "webpack": "^4.29.5",
+ "webpack-cli": "^3.3.10",
+ "webpack-node-externals": "^1.7.2"
+ },
+ "jest": {
+ "testEnvironment": "jsdom",
+ "testURL": "https://jest.test",
+ "collectCoverageFrom": [
+ "src/**/*.js"
+ ],
+ "moduleDirectories": [
+ "node_modules",
+ "src"
+ ]
+ },
+ "license": "MIT",
+ "main": "miniprogram_dist/index.js",
+ "miniprogram": "miniprogram_dist",
+ "name": "wxml-to-canvas",
+ "repository": {
+ "type": "git",
+ "url": ""
+ },
+ "scripts": {
+ "build": "gulp",
+ "clean": "gulp clean",
+ "clean-dev": "gulp clean --develop",
+ "coverage": "jest ./test/* --coverage --bail",
+ "dev": "gulp dev --develop",
+ "dist": "npm run build",
+ "lint": "eslint \"src/**/*.js\" --fix",
+ "lint-tools": "eslint \"tools/**/*.js\" --rule \"import/no-extraneous-dependencies: false\" --fix",
+ "test": "jest --bail",
+ "test-debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --bail",
+ "watch": "gulp watch --develop --watch"
+ },
+ "version": "1.1.1"
+}
diff --git a/node_modules/wxml-to-canvas/src/draw.js b/node_modules/wxml-to-canvas/src/draw.js
new file mode 100644
index 0000000..42e69c4
--- /dev/null
+++ b/node_modules/wxml-to-canvas/src/draw.js
@@ -0,0 +1,225 @@
+class Draw {
+ constructor(context, canvas, use2dCanvas = false) {
+ this.ctx = context
+ this.canvas = canvas || null
+ this.use2dCanvas = use2dCanvas
+ }
+
+ roundRect(x, y, w, h, r, fill = true, stroke = false) {
+ if (r < 0) return
+ const ctx = this.ctx
+
+ ctx.beginPath()
+ ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 3 / 2)
+ ctx.arc(x + w - r, y + r, r, Math.PI * 3 / 2, 0)
+ ctx.arc(x + w - r, y + h - r, r, 0, Math.PI / 2)
+ ctx.arc(x + r, y + h - r, r, Math.PI / 2, Math.PI)
+ ctx.lineTo(x, y + r)
+ if (stroke) ctx.stroke()
+ if (fill) ctx.fill()
+ }
+
+ drawView(box, style) {
+ const ctx = this.ctx
+ const {
+ left: x, top: y, width: w, height: h
+ } = box
+ const {
+ borderRadius = 0,
+ borderWidth = 0,
+ borderColor,
+ color = '#000',
+ backgroundColor = 'transparent',
+ } = style
+ ctx.save()
+ // 外环
+ if (borderWidth > 0) {
+ ctx.fillStyle = borderColor || color
+ this.roundRect(x, y, w, h, borderRadius)
+ }
+
+ // 内环
+ ctx.fillStyle = backgroundColor
+ const innerWidth = w - 2 * borderWidth
+ const innerHeight = h - 2 * borderWidth
+ const innerRadius = borderRadius - borderWidth >= 0 ? borderRadius - borderWidth : 0
+ this.roundRect(x + borderWidth, y + borderWidth, innerWidth, innerHeight, innerRadius)
+ ctx.restore()
+ }
+
+ async drawImage(img, box, style) {
+ await new Promise((resolve, reject) => {
+ const ctx = this.ctx
+ const canvas = this.canvas
+
+ const {
+ borderRadius = 0
+ } = style
+ const {
+ left: x, top: y, width: w, height: h
+ } = box
+ ctx.save()
+ this.roundRect(x, y, w, h, borderRadius, false, false)
+ ctx.clip()
+
+ const _drawImage = (img) => {
+ if (this.use2dCanvas) {
+ const Image = canvas.createImage()
+ Image.onload = () => {
+ ctx.drawImage(Image, x, y, w, h)
+ ctx.restore()
+ resolve()
+ }
+ Image.onerror = () => { reject(new Error(`createImage fail: ${img}`)) }
+ Image.src = img
+ } else {
+ ctx.drawImage(img, x, y, w, h)
+ ctx.restore()
+ resolve()
+ }
+ }
+
+ const isTempFile = /^wxfile:\/\//.test(img)
+ const isNetworkFile = /^https?:\/\//.test(img)
+
+ if (isTempFile) {
+ _drawImage(img)
+ } else if (isNetworkFile) {
+ wx.downloadFile({
+ url: img,
+ success(res) {
+ if (res.statusCode === 200) {
+ _drawImage(res.tempFilePath)
+ } else {
+ reject(new Error(`downloadFile:fail ${img}`))
+ }
+ },
+ fail() {
+ reject(new Error(`downloadFile:fail ${img}`))
+ }
+ })
+ } else {
+ reject(new Error(`image format error: ${img}`))
+ }
+ })
+ }
+
+ // eslint-disable-next-line complexity
+ drawText(text, box, style) {
+ const ctx = this.ctx
+ let {
+ left: x, top: y, width: w, height: h
+ } = box
+ let {
+ color = '#000',
+ lineHeight = '1.4em',
+ fontSize = 14,
+ textAlign = 'left',
+ verticalAlign = 'top',
+ backgroundColor = 'transparent'
+ } = style
+
+ if (typeof lineHeight === 'string') { // 2em
+ lineHeight = Math.ceil(parseFloat(lineHeight.replace('em')) * fontSize)
+ }
+ if (!text || (lineHeight > h)) return
+
+ ctx.save()
+ ctx.textBaseline = 'top'
+ ctx.font = `${fontSize}px sans-serif`
+ ctx.textAlign = textAlign
+
+ // 背景色
+ ctx.fillStyle = backgroundColor
+ this.roundRect(x, y, w, h, 0)
+
+ // 文字颜色
+ ctx.fillStyle = color
+
+ // 水平布局
+ switch (textAlign) {
+ case 'left':
+ break
+ case 'center':
+ x += 0.5 * w
+ break
+ case 'right':
+ x += w
+ break
+ default: break
+ }
+
+ const textWidth = ctx.measureText(text).width
+ const actualHeight = Math.ceil(textWidth / w) * lineHeight
+ let paddingTop = Math.ceil((h - actualHeight) / 2)
+ if (paddingTop < 0) paddingTop = 0
+
+ // 垂直布局
+ switch (verticalAlign) {
+ case 'top':
+ break
+ case 'middle':
+ y += paddingTop
+ break
+ case 'bottom':
+ y += 2 * paddingTop
+ break
+ default: break
+ }
+
+ const inlinePaddingTop = Math.ceil((lineHeight - fontSize) / 2)
+
+ // 不超过一行
+ if (textWidth <= w) {
+ ctx.fillText(text, x, y + inlinePaddingTop)
+ return
+ }
+
+ // 多行文本
+ const chars = text.split('')
+ const _y = y
+
+ // 逐行绘制
+ let line = ''
+ for (const ch of chars) {
+ const testLine = line + ch
+ const testWidth = ctx.measureText(testLine).width
+
+ if (testWidth > w) {
+ ctx.fillText(line, x, y + inlinePaddingTop)
+ y += lineHeight
+ line = ch
+ if ((y + lineHeight) > (_y + h)) break
+ } else {
+ line = testLine
+ }
+ }
+
+ // 避免溢出
+ if ((y + lineHeight) <= (_y + h)) {
+ ctx.fillText(line, x, y + inlinePaddingTop)
+ }
+ ctx.restore()
+ }
+
+ async drawNode(element) {
+ const {layoutBox, computedStyle, name} = element
+ const {src, text} = element.attributes
+ if (name === 'view') {
+ this.drawView(layoutBox, computedStyle)
+ } else if (name === 'image') {
+ await this.drawImage(src, layoutBox, computedStyle)
+ } else if (name === 'text') {
+ this.drawText(text, layoutBox, computedStyle)
+ }
+ const childs = Object.values(element.children)
+ for (const child of childs) {
+ await this.drawNode(child)
+ }
+ }
+}
+
+
+module.exports = {
+ Draw
+}
diff --git a/node_modules/wxml-to-canvas/src/index.js b/node_modules/wxml-to-canvas/src/index.js
new file mode 100644
index 0000000..ffa8834
--- /dev/null
+++ b/node_modules/wxml-to-canvas/src/index.js
@@ -0,0 +1,117 @@
+
+const xmlParse = require('./xml-parser')
+const {Widget} = require('./widget')
+const {Draw} = require('./draw')
+const {compareVersion} = require('./utils')
+
+const canvasId = 'weui-canvas'
+
+Component({
+ properties: {
+ width: {
+ type: Number,
+ value: 400
+ },
+ height: {
+ type: Number,
+ value: 300
+ }
+ },
+ data: {
+ use2dCanvas: false, // 2.9.2 后可用canvas 2d 接口
+ },
+ lifetimes: {
+ attached() {
+ const {SDKVersion, pixelRatio: dpr} = wx.getSystemInfoSync()
+ const use2dCanvas = compareVersion(SDKVersion, '2.9.2') >= 0
+ this.dpr = dpr
+ this.setData({use2dCanvas}, () => {
+ if (use2dCanvas) {
+ const query = this.createSelectorQuery()
+ query.select(`#${canvasId}`)
+ .fields({node: true, size: true})
+ .exec(res => {
+ const canvas = res[0].node
+ const ctx = canvas.getContext('2d')
+ canvas.width = res[0].width * dpr
+ canvas.height = res[0].height * dpr
+ ctx.scale(dpr, dpr)
+ this.ctx = ctx
+ this.canvas = canvas
+ })
+ } else {
+ this.ctx = wx.createCanvasContext(canvasId, this)
+ }
+ })
+ }
+ },
+ methods: {
+ async renderToCanvas(args) {
+ const {wxml, style} = args
+ const ctx = this.ctx
+ const canvas = this.canvas
+ const use2dCanvas = this.data.use2dCanvas
+
+ if (use2dCanvas && !canvas) {
+ return Promise.reject(new Error('renderToCanvas: fail canvas has not been created'))
+ }
+
+ ctx.clearRect(0, 0, this.data.width, this.data.height)
+ const {root: xom} = xmlParse(wxml)
+
+ const widget = new Widget(xom, style)
+ const container = widget.init()
+ this.boundary = {
+ top: container.layoutBox.top,
+ left: container.layoutBox.left,
+ width: container.computedStyle.width,
+ height: container.computedStyle.height,
+ }
+ const draw = new Draw(ctx, canvas, use2dCanvas)
+ await draw.drawNode(container)
+
+ if (!use2dCanvas) {
+ await this.canvasDraw(ctx)
+ }
+ return Promise.resolve(container)
+ },
+
+ canvasDraw(ctx, reserve) {
+ return new Promise(resolve => {
+ ctx.draw(reserve, () => {
+ resolve()
+ })
+ })
+ },
+
+ canvasToTempFilePath(args = {}) {
+ const use2dCanvas = this.data.use2dCanvas
+
+ return new Promise((resolve, reject) => {
+ const {
+ top, left, width, height
+ } = this.boundary
+
+ const copyArgs = {
+ x: left,
+ y: top,
+ width,
+ height,
+ destWidth: width * this.dpr,
+ destHeight: height * this.dpr,
+ canvasId,
+ fileType: args.fileType || 'png',
+ quality: args.quality || 1,
+ success: resolve,
+ fail: reject
+ }
+
+ if (use2dCanvas) {
+ delete copyArgs.canvasId
+ copyArgs.canvas = this.canvas
+ }
+ wx.canvasToTempFilePath(copyArgs, this)
+ })
+ }
+ }
+})
diff --git a/node_modules/wxml-to-canvas/src/index.json b/node_modules/wxml-to-canvas/src/index.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/node_modules/wxml-to-canvas/src/index.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/node_modules/wxml-to-canvas/src/index.wxml b/node_modules/wxml-to-canvas/src/index.wxml
new file mode 100644
index 0000000..a0010ad
--- /dev/null
+++ b/node_modules/wxml-to-canvas/src/index.wxml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/node_modules/wxml-to-canvas/src/index.wxss b/node_modules/wxml-to-canvas/src/index.wxss
new file mode 100644
index 0000000..e69de29
diff --git a/node_modules/wxml-to-canvas/src/utils.js b/node_modules/wxml-to-canvas/src/utils.js
new file mode 100644
index 0000000..c3cf7d7
--- /dev/null
+++ b/node_modules/wxml-to-canvas/src/utils.js
@@ -0,0 +1,57 @@
+const hex = (color) => {
+ let result = null
+
+ if (/^#/.test(color) && (color.length === 7 || color.length === 9)) {
+ return color
+ // eslint-disable-next-line no-cond-assign
+ } else if ((result = /^(rgb|rgba)\((.+)\)/.exec(color)) !== null) {
+ return '#' + result[2].split(',').map((part, index) => {
+ part = part.trim()
+ part = index === 3 ? Math.floor(parseFloat(part) * 255) : parseInt(part, 10)
+ part = part.toString(16)
+ if (part.length === 1) {
+ part = '0' + part
+ }
+ return part
+ }).join('')
+ } else {
+ return '#00000000'
+ }
+}
+
+const splitLineToCamelCase = (str) => str.split('-').map((part, index) => {
+ if (index === 0) {
+ return part
+ }
+ return part[0].toUpperCase() + part.slice(1)
+}).join('')
+
+const compareVersion = (v1, v2) => {
+ v1 = v1.split('.')
+ v2 = v2.split('.')
+ const len = Math.max(v1.length, v2.length)
+ while (v1.length < len) {
+ v1.push('0')
+ }
+ while (v2.length < len) {
+ v2.push('0')
+ }
+ for (let i = 0; i < len; i++) {
+ const num1 = parseInt(v1[i], 10)
+ const num2 = parseInt(v2[i], 10)
+
+ if (num1 > num2) {
+ return 1
+ } else if (num1 < num2) {
+ return -1
+ }
+ }
+
+ return 0
+}
+
+module.exports = {
+ hex,
+ splitLineToCamelCase,
+ compareVersion
+}
diff --git a/node_modules/wxml-to-canvas/src/widget.js b/node_modules/wxml-to-canvas/src/widget.js
new file mode 100644
index 0000000..af3ccc2
--- /dev/null
+++ b/node_modules/wxml-to-canvas/src/widget.js
@@ -0,0 +1,81 @@
+const Block = require('widget-ui')
+const {splitLineToCamelCase} = require('./utils')
+
+class Element extends Block {
+ constructor(prop) {
+ super(prop.style)
+ this.name = prop.name
+ this.attributes = prop.attributes
+ }
+}
+
+
+class Widget {
+ constructor(xom, style) {
+ this.xom = xom
+ this.style = style
+
+ this.inheritProps = ['fontSize', 'lineHeight', 'textAlign', 'verticalAlign', 'color']
+ }
+
+ init() {
+ this.container = this.create(this.xom)
+ this.container.layout()
+
+ this.inheritStyle(this.container)
+ return this.container
+ }
+
+ // 继承父节点的样式
+ inheritStyle(node) {
+ const parent = node.parent || null
+ const children = node.children || {}
+ const computedStyle = node.computedStyle
+
+ if (parent) {
+ this.inheritProps.forEach(prop => {
+ computedStyle[prop] = computedStyle[prop] || parent.computedStyle[prop]
+ })
+ }
+
+ Object.values(children).forEach(child => {
+ this.inheritStyle(child)
+ })
+ }
+
+ create(node) {
+ let classNames = (node.attributes.class || '').split(' ')
+ classNames = classNames.map(item => splitLineToCamelCase(item.trim()))
+ const style = {}
+ classNames.forEach(item => {
+ Object.assign(style, this.style[item] || {})
+ })
+
+ const args = {name: node.name, style}
+
+ const attrs = Object.keys(node.attributes)
+ const attributes = {}
+ for (const attr of attrs) {
+ const value = node.attributes[attr]
+ const CamelAttr = splitLineToCamelCase(attr)
+
+ if (value === '' || value === 'true') {
+ attributes[CamelAttr] = true
+ } else if (value === 'false') {
+ attributes[CamelAttr] = false
+ } else {
+ attributes[CamelAttr] = value
+ }
+ }
+ attributes.text = node.content
+ args.attributes = attributes
+ const element = new Element(args)
+ node.children.forEach(childNode => {
+ const childElement = this.create(childNode)
+ element.add(childElement)
+ })
+ return element
+ }
+}
+
+module.exports = {Widget}
diff --git a/node_modules/wxml-to-canvas/src/xml-parser.js b/node_modules/wxml-to-canvas/src/xml-parser.js
new file mode 100644
index 0000000..de7526c
--- /dev/null
+++ b/node_modules/wxml-to-canvas/src/xml-parser.js
@@ -0,0 +1,164 @@
+
+/**
+ * Module dependencies.
+ */
+
+
+/**
+ * Expose `parse`.
+ */
+
+
+/**
+ * Parse the given string of `xml`.
+ *
+ * @param {String} xml
+ * @return {Object}
+ * @api public
+ */
+
+function parse(xml) {
+ xml = xml.trim()
+
+ // strip comments
+ xml = xml.replace(//g, '')
+
+ return document()
+
+ /**
+ * XML document.
+ */
+
+ function document() {
+ return {
+ declaration: declaration(),
+ root: tag()
+ }
+ }
+
+ /**
+ * Declaration.
+ */
+
+ function declaration() {
+ const m = match(/^<\?xml\s*/)
+ if (!m) return
+
+ // tag
+ const node = {
+ attributes: {}
+ }
+
+ // attributes
+ while (!(eos() || is('?>'))) {
+ const attr = attribute()
+ if (!attr) return node
+ node.attributes[attr.name] = attr.value
+ }
+
+ match(/\?>\s*/)
+
+ return node
+ }
+
+ /**
+ * Tag.
+ */
+
+ function tag() {
+ const m = match(/^<([\w-:.]+)\s*/)
+ if (!m) return
+
+ // name
+ const node = {
+ name: m[1],
+ attributes: {},
+ children: []
+ }
+
+ // attributes
+ while (!(eos() || is('>') || is('?>') || is('/>'))) {
+ const attr = attribute()
+ if (!attr) return node
+ node.attributes[attr.name] = attr.value
+ }
+
+ // self closing tag
+ if (match(/^\s*\/>\s*/)) {
+ return node
+ }
+
+ match(/\??>\s*/)
+
+ // content
+ node.content = content()
+
+ // children
+ let child
+ while (child = tag()) {
+ node.children.push(child)
+ }
+
+ // closing
+ match(/^<\/[\w-:.]+>\s*/)
+
+ return node
+ }
+
+ /**
+ * Text content.
+ */
+
+ function content() {
+ const m = match(/^([^<]*)/)
+ if (m) return m[1]
+ return ''
+ }
+
+ /**
+ * Attribute.
+ */
+
+ function attribute() {
+ const m = match(/([\w:-]+)\s*=\s*("[^"]*"|'[^']*'|\w+)\s*/)
+ if (!m) return
+ return {name: m[1], value: strip(m[2])}
+ }
+
+ /**
+ * Strip quotes from `val`.
+ */
+
+ function strip(val) {
+ return val.replace(/^['"]|['"]$/g, '')
+ }
+
+ /**
+ * Match `re` and advance the string.
+ */
+
+ function match(re) {
+ const m = xml.match(re)
+ if (!m) return
+ xml = xml.slice(m[0].length)
+ return m
+ }
+
+ /**
+ * End-of-source.
+ */
+
+ function eos() {
+ return xml.length == 0
+ }
+
+ /**
+ * Check for `prefix`.
+ */
+
+ function is(prefix) {
+ return xml.indexOf(prefix) == 0
+ }
+}
+
+module.exports = parse
diff --git a/package-lock.json b/package-lock.json
index 83cfb72..baff0ad 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,27 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@miniprogram-component-plus/video-swiper/-/video-swiper-1.0.1.tgz",
"integrity": "sha512-1rlmsS3/TR0Zu0nZHwEwb9UCQWY/ofPv73zU56FLfZh72Xw+BcIzfohrDxrGs5QpoL4KCLl9G7UB5w+3ZRSZzQ=="
+ },
+ "eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
+ },
+ "widget-ui": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/widget-ui/-/widget-ui-1.0.2.tgz",
+ "integrity": "sha512-gDXosr5mflJdMA1weU1A47aTsTFfMJhfA4EKgO5XFebY3eVklf80KD4GODfrjo8J2WQ+9YjL1Rd9UUmKIzhShw==",
+ "requires": {
+ "eventemitter3": "^4.0.0"
+ }
+ },
+ "wxml-to-canvas": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/wxml-to-canvas/-/wxml-to-canvas-1.1.1.tgz",
+ "integrity": "sha512-3mDjHzujY/UgdCOXij/MnmwJYerVjwkyQHMBFBE8zh89DK7h7UTzoydWFqEBjIC0rfZM+AXl5kDh9hUcsNpSmg==",
+ "requires": {
+ "widget-ui": "^1.0.2"
+ }
}
}
}
diff --git a/package.json b/package.json
index 8b6ff59..2ce1222 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"author": "",
"license": "ISC",
"dependencies": {
- "@miniprogram-component-plus/video-swiper": "^1.0.1"
+ "@miniprogram-component-plus/video-swiper": "^1.0.1",
+ "wxml-to-canvas": "^1.1.1"
}
}
From 49a7bade362cfd753513629848a847868059024f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=94=90=E6=98=8E=E6=98=8E?= <970899069@qq.com>
Date: Wed, 30 Dec 2020 10:31:55 +0800
Subject: [PATCH 3/5] =?UTF-8?q?[=E6=9B=B4=E6=96=B0]=E5=8F=98=E6=9B=B4?=
=?UTF-8?q?=E4=BA=86=E8=8E=B7=E5=8F=96=E4=BC=81=E4=B8=9A=E4=BF=A1=E6=81=AF?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE,=E7=AE=80=E5=8C=96=E9=85=8D=E7=BD=AE?=
=?UTF-8?q?=E6=96=87=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app.js | 2 +-
components/storeTabBar/storeTabBar.js | 3 +--
lib/storeConfig.js | 13 -------------
pages/config/config.js | 21 +++++++++++----------
4 files changed, 13 insertions(+), 26 deletions(-)
delete mode 100644 lib/storeConfig.js
diff --git a/app.js b/app.js
index 820a03e..0b5cd90 100644
--- a/app.js
+++ b/app.js
@@ -25,6 +25,6 @@ App({
goodUrl : "/pages/goods/show?goodsId=",
cardUrl : "/pages/card/index?cardid="
},
- id : 1
+ storeTabBarConfig: [] //店铺tabBar配置信息
}
})
diff --git a/components/storeTabBar/storeTabBar.js b/components/storeTabBar/storeTabBar.js
index e4bb99a..c1e5982 100644
--- a/components/storeTabBar/storeTabBar.js
+++ b/components/storeTabBar/storeTabBar.js
@@ -4,8 +4,6 @@
* 碌碌无为枉半生,一朝惊醒万事空。
*/
-import { tabBar } from "../../lib/storeConfig"
-
Component({
/**
* 组件接收参数
@@ -33,6 +31,7 @@ Component({
*/
pageLifetimes: {
show(){
+ let tabBar = getApp().globalData.storeTabBarConfig
let selectedIndex = tabBar.findIndex(val=> val.pagePath == '/' + this.data.pagesUrl)
this.setData({
list : tabBar,
diff --git a/lib/storeConfig.js b/lib/storeConfig.js
deleted file mode 100644
index 1a7db34..0000000
--- a/lib/storeConfig.js
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/**
- * Web唐明明
- * 匆匆数载恍如梦,岁月迢迢华发增。
- * 碌碌无为枉半生,一朝惊醒万事空。
- */
-
-// 企业tabBar配置
-const tabBar = []
-
-export {
- tabBar
-}
\ No newline at end of file
diff --git a/pages/config/config.js b/pages/config/config.js
index 2128690..a699175 100644
--- a/pages/config/config.js
+++ b/pages/config/config.js
@@ -4,7 +4,6 @@
* 碌碌无为枉半生,一朝惊醒万事空。
*/
-import { tabBar } from "../../lib/storeConfig"
import { mall, video, ticket, user } from "../../lib/tabBarData"
Page({
@@ -21,31 +20,33 @@ Page({
wx.getStorage({
key : 'compayId',
success : res=>{
-
wx.$api.publics.storeConfig({
company_id: res.data
}).then(res => {
- let tabBarVal = res.concat({})
+ let tabBarVal = res.concat({}),
+ newTabBar = []
+
tabBarVal.forEach(res => {
switch (res.slug) {
case "video":
- tabBar.push(video)
+ newTabBar.push(video)
break;
case "mall":
- tabBar.push(mall)
+ newTabBar.push(mall)
break;
case "ticket":
- tabBar.push(ticket)
+ newTabBar.push(ticket)
break;
default :
- tabBar.push(user)
+ newTabBar.push(user)
break;
}
})
- if(tabBarVal.length == tabBar.length){
- wx.reLaunch({
- url: tabBar[0].pagePath,
+ if(tabBarVal.length == newTabBar.length){
+ getApp().globalData.storeTabBarConfig = newTabBar
+ wx.redirectTo({
+ url: newTabBar[0].pagePath,
})
}
})
From aa90f73d69f37a0b79842453ed73d17f746253f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=94=90=E6=98=8E=E6=98=8E?= <970899069@qq.com>
Date: Wed, 30 Dec 2020 11:50:55 +0800
Subject: [PATCH 4/5] =?UTF-8?q?[=E6=96=B0=E5=A2=9E]=E5=A2=9E=E5=8A=A0?=
=?UTF-8?q?=E4=BA=86=E7=9B=B4=E6=92=AD=E5=88=97=E8=A1=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apis/index.js | 4 +-
apis/interfaces/live.js | 6 +--
components/swiperVideo/swiperVideo.js | 3 --
components/swiperVideo/swiperVideo.wxml | 4 +-
components/swiperVideo/swiperVideo.wxss | 3 +-
pages/shortVideo/index.js | 13 +++++
pages/shortVideo/index.wxml | 18 +++----
pages/shortVideo/index.wxss | 64 +++++++++++++++++++++++--
project.config.json | 5 +-
9 files changed, 96 insertions(+), 24 deletions(-)
diff --git a/apis/index.js b/apis/index.js
index f31dbbc..f4d4faa 100644
--- a/apis/index.js
+++ b/apis/index.js
@@ -15,6 +15,7 @@ import company from "./interfaces/company"
import companyModule from "./interfaces/home"
import ticket from "./interfaces/ticket"
import address from "./interfaces/address"
+import live from "./interfaces/live"
export default{
publics,
@@ -28,5 +29,6 @@ export default{
company,
companyModule,
ticket,
- address
+ address,
+ live
}
diff --git a/apis/interfaces/live.js b/apis/interfaces/live.js
index 9da3502..4b1d036 100644
--- a/apis/interfaces/live.js
+++ b/apis/interfaces/live.js
@@ -1,11 +1,11 @@
/*
- * 电子名片
+ * 直播
*/
import {req} from "../request"
-const card = data => req({url: "cardpersonal" , data: data}) //名片信息
+const rooms = () => req({url: "lives/rooms"}) //获取直播间列表
export default({
- card
+ rooms
})
diff --git a/components/swiperVideo/swiperVideo.js b/components/swiperVideo/swiperVideo.js
index 1b36a98..6e12469 100644
--- a/components/swiperVideo/swiperVideo.js
+++ b/components/swiperVideo/swiperVideo.js
@@ -43,9 +43,6 @@ Component({
methods: {
// 视频滚动了
changeVideo(e){
-
- console.log(e)
-
let videoLists = this.data.videoList,
current = e.detail.current,
currentId = this.data.playId,
diff --git a/components/swiperVideo/swiperVideo.wxml b/components/swiperVideo/swiperVideo.wxml
index fc7c1c3..bb9e0a0 100644
--- a/components/swiperVideo/swiperVideo.wxml
+++ b/components/swiperVideo/swiperVideo.wxml
@@ -2,6 +2,7 @@
-
+
diff --git a/components/swiperVideo/swiperVideo.wxss b/components/swiperVideo/swiperVideo.wxss
index 8b4285a..2da71f0 100644
--- a/components/swiperVideo/swiperVideo.wxss
+++ b/components/swiperVideo/swiperVideo.wxss
@@ -15,7 +15,8 @@
-webkit-overflow-scrolling:touch;
}
-.videoSwiperItem video{
+.videoSwiperItemVideo,
+.videoCover{
width: 100%;
height: 100%;
}
diff --git a/pages/shortVideo/index.js b/pages/shortVideo/index.js
index bf9fbbc..b2d465a 100644
--- a/pages/shortVideo/index.js
+++ b/pages/shortVideo/index.js
@@ -14,6 +14,7 @@ Page({
videoIndex : 0, //当前播放视频的下标
videoId : "", //当前播放的视频id
playState : true, //视频播放状态
+ rooms : [], //直播列表
},
/**
@@ -29,6 +30,18 @@ Page({
})
},
+ /**
+ * 获取直播间列表
+ */
+ onShow(){
+ wx.$api.live.rooms().then(res=>{
+ console.log(res.list)
+ this.setData({
+ rooms: res.list
+ })
+ })
+ },
+
/***
* 视频的播放状态
*/
diff --git a/pages/shortVideo/index.wxml b/pages/shortVideo/index.wxml
index dded866..32d0160 100644
--- a/pages/shortVideo/index.wxml
+++ b/pages/shortVideo/index.wxml
@@ -1,13 +1,5 @@
-
-进入直播间
-
-
-
- 改变全局id
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/pages/shortVideo/index.wxss b/pages/shortVideo/index.wxss
index 7133322..30ae81f 100644
--- a/pages/shortVideo/index.wxss
+++ b/pages/shortVideo/index.wxss
@@ -7,7 +7,7 @@
page{
- /* background: #0e0c1a; */
+ background: #0e0c1a;
}
.videoSwiper{
@@ -19,13 +19,69 @@
.videos-content{
position: relative;
height: 100vh;
- display: none;
+ box-sizing: border-box;
+ padding-bottom: calc(48px + env(safe-area-inset-bottom));
+}
+
+/* 直播信息 */
+.live-rooms{
+ position: absolute;
+ top: calc(180rpx + env(safe-area-inset-bottom));
+ left: 30rpx;
+}
+
+.live-rooms-cover{
+ width: 98rpx;
+ height: 98rpx;
+ border-radius: 50%;
+ vertical-align: top;
+}
+
+.live-rooms-nav{
+ position: relative;
+ display: inline-block;
+ width: 98rpx;
+ height: 98rpx;
+ margin-left: 30rpx;
+}
+
+.live-rooms-nav:first-child{
+ margin-left: 0;
+}
+
+.live-rooms-nav::before,
+.live-rooms-nav::after{
+ position: absolute;
+ content: "";
+}
+
+.live-rooms-nav::before{
+ width: 98rpx;
+ height: 98rpx;
+ border:solid 4rpx #FF8C37;
+ border-radius: 50%;
+ box-sizing: border-box;
+}
+
+.live-rooms-nav::after{
+ content: "直播中";
+ position: absolute;
+ bottom: 0;
+ left: 10rpx;
+ width: 78rpx;
+ background: #FF8C37;
+ color: white;
+ height: 32rpx;
+ line-height: 32rpx;
+ font-size: 20rpx;
+ text-align: center;
+ border-radius: 16rpx;
}
/* 视频信息 */
.video-info{
position: absolute;
- bottom: 50rpx;
+ bottom: calc(78px + env(safe-area-inset-bottom));
left: 30rpx;
width: calc(100% - 218rpx);
}
@@ -51,7 +107,7 @@
.video-tool{
position: absolute;
right: 30rpx;
- bottom: 50rpx;
+ bottom: calc(78px + env(safe-area-inset-bottom));
}
.video-tool-item{
diff --git a/project.config.json b/project.config.json
index 3e74c5d..dff0407 100644
--- a/project.config.json
+++ b/project.config.json
@@ -40,7 +40,7 @@
},
"compileType": "miniprogram",
"libVersion": "2.13.2",
- "appid": "wx49efb36db851933d",
+ "appid": "wxd931d03dfe955254",
"projectname": "%E8%A1%8C%E4%B8%9A%E7%89%88Saas",
"debugOptions": {
"hidedInDevtools": []
@@ -59,7 +59,8 @@
"list": []
},
"miniprogram": {
- "list": [{
+ "list": [
+ {
"name": "登录",
"pathName": "pages/login/login",
"query": "",
From e2b2490e1ae0911c959be9384aa442e9458c8c60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=94=90=E6=98=8E=E6=98=8E?= <970899069@qq.com>
Date: Wed, 30 Dec 2020 15:13:40 +0800
Subject: [PATCH 5/5] =?UTF-8?q?[=E6=9B=B4=E6=96=B0]=E6=9B=B4=E6=96=B0?=
=?UTF-8?q?=E8=A7=86=E9=A2=91=E7=BB=84=E4=BB=B6=E9=85=8D=E7=BD=AE,?=
=?UTF-8?q?=E8=B0=83=E6=95=B4=E7=9B=B4=E6=92=AD=E5=BC=B9=E5=87=BA=E6=A0=B7?=
=?UTF-8?q?=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
components/swiperVideo/swiperVideo.js | 6 +--
components/swiperVideo/swiperVideo.wxml | 4 ++
components/swiperVideo/swiperVideo.wxss | 3 +-
pages/shortVideo/index.js | 34 +++++++++++---
pages/shortVideo/index.wxml | 23 +++++----
pages/shortVideo/index.wxss | 62 ++++++++++++++++++-------
6 files changed, 94 insertions(+), 38 deletions(-)
diff --git a/components/swiperVideo/swiperVideo.js b/components/swiperVideo/swiperVideo.js
index 6e12469..853b0ac 100644
--- a/components/swiperVideo/swiperVideo.js
+++ b/components/swiperVideo/swiperVideo.js
@@ -31,8 +31,9 @@ Component({
* 组件的初始数据
*/
data: {
- controls: false,
- showPlay: false,
+ controls: true,
+ showPlay: true,
+ showFull: false,
isPlay : false,
playId : 0
},
@@ -60,7 +61,6 @@ Component({
videoContextPrev.play()
this.setData({
- isPlay: true,
playId: prevId
})
},
diff --git a/components/swiperVideo/swiperVideo.wxml b/components/swiperVideo/swiperVideo.wxml
index bb9e0a0..ff1b4da 100644
--- a/components/swiperVideo/swiperVideo.wxml
+++ b/components/swiperVideo/swiperVideo.wxml
@@ -8,6 +8,8 @@
controls="{{controls}}"
object-fit="{{fit}}"
show-center-play-btn="{{showPlay}}"
+ show-fullscreen-btn="{{showFull}}"
+ enable-progress-gesture="{{false}}"
data-videoid="{{item.video_id}}"
bindtap="videoPlay"
bindplay="vipdeBindPlay"
@@ -17,5 +19,7 @@
>
+
+
diff --git a/components/swiperVideo/swiperVideo.wxss b/components/swiperVideo/swiperVideo.wxss
index 2da71f0..0b89ea4 100644
--- a/components/swiperVideo/swiperVideo.wxss
+++ b/components/swiperVideo/swiperVideo.wxss
@@ -23,13 +23,14 @@
/* 视频按钮 */
.videoLayer-play{
- position: relative;
+ position: absolute;
width: 78rpx;
height: 78rpx;
left: calc(50% - 39rpx);
top: calc(50% - 39rpx);
opacity: 0;
transition: all .5s;
+ z-index: 99;
}
.videoLayer-play.show{
diff --git a/pages/shortVideo/index.js b/pages/shortVideo/index.js
index b2d465a..769a0e5 100644
--- a/pages/shortVideo/index.js
+++ b/pages/shortVideo/index.js
@@ -5,16 +5,17 @@
*/
Page({
-
/**
* 页面的初始数据
*/
data: {
- videoList : [], //获取短视频列表
- videoIndex : 0, //当前播放视频的下标
- videoId : "", //当前播放的视频id
+ videoList : [], //获取短视频列表
+ videoIndex : 0, //当前播放视频的下标
+ videoId : "", //当前播放的视频id
playState : true, //视频播放状态
rooms : [], //直播列表
+ sysInfo : {}, //系统信息
+ showLive : false //直播层状态
},
/**
@@ -31,17 +32,36 @@ Page({
},
/**
- * 获取直播间列表
+ * 生命周期函数--监听页面显示
*/
onShow(){
+ // 获取直播间列表
wx.$api.live.rooms().then(res=>{
- console.log(res.list)
this.setData({
- rooms: res.list
+ rooms : res.list,
+ sysInfo : wx.getSystemInfoSync().safeArea
})
+ console.log(this.data.sysInfo)
})
},
+ /**
+ * 展示直播数量
+ */
+ onLiveLay(e){
+ if(e.currentTarget.dataset.type == "video"){
+ if(this.data.showLive){
+ this.setData({
+ showLive: false
+ })
+ }
+ }else{
+ this.setData({
+ showLive: !this.data.showLive
+ })
+ }
+ },
+
/***
* 视频的播放状态
*/
diff --git a/pages/shortVideo/index.wxml b/pages/shortVideo/index.wxml
index 32d0160..69872ec 100644
--- a/pages/shortVideo/index.wxml
+++ b/pages/shortVideo/index.wxml
@@ -1,5 +1,14 @@
+
+
+
+
+
+
+
+
-
+
+
-
-
-
-
-
-
-
+
+
+ {{rooms.length}}个直播
-
-
@ {{videoList[videoIndex].company.name || "-"}}
diff --git a/pages/shortVideo/index.wxss b/pages/shortVideo/index.wxss
index 30ae81f..0acb713 100644
--- a/pages/shortVideo/index.wxss
+++ b/pages/shortVideo/index.wxss
@@ -4,9 +4,7 @@
* 匆匆数载恍如梦,岁月迢迢华发增。
* 碌碌无为枉半生,一朝惊醒万事空。
*/
-
-
- page{
+page{
background: #0e0c1a;
}
@@ -17,22 +15,29 @@
}
.videos-content{
+ margin-top: 0;
position: relative;
height: 100vh;
box-sizing: border-box;
padding-bottom: calc(48px + env(safe-area-inset-bottom));
+ transition: margin-top .5s;
+}
+
+.videos-content.marginTop{
+ margin-top: calc(134px + env(safe-area-inset-top));
}
/* 直播信息 */
.live-rooms{
position: absolute;
- top: calc(180rpx + env(safe-area-inset-bottom));
- left: 30rpx;
+ top: 0;
+ padding-top: calc(60px + env(safe-area-inset-top));
+ white-space: nowrap;
}
.live-rooms-cover{
- width: 98rpx;
- height: 98rpx;
+ width: 52px;
+ height: 52px;
border-radius: 50%;
vertical-align: top;
}
@@ -40,13 +45,17 @@
.live-rooms-nav{
position: relative;
display: inline-block;
- width: 98rpx;
- height: 98rpx;
- margin-left: 30rpx;
+ width: 52px;
+ height: 52px;
+ margin: 0 15rpx;
}
.live-rooms-nav:first-child{
- margin-left: 0;
+ margin-left: 30rpx;
+}
+
+.live-rooms-nav:last-child{
+ margin-right: 30rpx;
}
.live-rooms-nav::before,
@@ -56,8 +65,8 @@
}
.live-rooms-nav::before{
- width: 98rpx;
- height: 98rpx;
+ width: 52px;
+ height: 52px;
border:solid 4rpx #FF8C37;
border-radius: 50%;
box-sizing: border-box;
@@ -67,8 +76,8 @@
content: "直播中";
position: absolute;
bottom: 0;
- left: 10rpx;
- width: 78rpx;
+ left: 5px;
+ width: 42px;
background: #FF8C37;
color: white;
height: 32rpx;
@@ -78,10 +87,29 @@
border-radius: 16rpx;
}
+/* 直播数量 */
+.videoLayer-live{
+ position: absolute;
+ top: calc(60px + env(safe-area-inset-top));
+ left: 30rpx;
+ right: 30rpx;
+ color: white;
+ text-align: center;
+}
+
+.videoLayer-live text{
+ background: rgba(0, 0, 0, .5);
+ padding: 0 20rpx;
+ line-height: 50rpx;
+ font-size: 26rpx;
+ border-radius: 25rpx;
+ display: inline-block;
+}
+
/* 视频信息 */
.video-info{
position: absolute;
- bottom: calc(78px + env(safe-area-inset-bottom));
+ bottom: calc(88px + env(safe-area-inset-bottom));
left: 30rpx;
width: calc(100% - 218rpx);
}
@@ -107,7 +135,7 @@
.video-tool{
position: absolute;
right: 30rpx;
- bottom: calc(78px + env(safe-area-inset-bottom));
+ bottom: calc(88px + env(safe-area-inset-bottom));
}
.video-tool-item{