Compare commits

...

120 Commits
main ... xiao

Author SHA1 Message Date
DESKTOP-RQ919RC\Pc
ed3f12b759 4.6新样式部分提交 2025-04-18 19:03:57 +08:00
DESKTOP-RQ919RC\Pc
ec7dc0b8df 图片上传服务器 2025-04-18 14:07:30 +08:00
DESKTOP-RQ919RC\Pc
6d57b07cef 4.6新样式 2025-04-17 18:54:19 +08:00
DESKTOP-RQ919RC\Pc
6132cd8db2 4.4首页新公寓样式和轮播图,公寓列表标签筛选 2025-04-16 18:59:05 +08:00
DESKTOP-RQ919RC\Pc
ced718c079 标注,4.4之前 2025-04-16 18:33:36 +08:00
DESKTOP-RQ919RC\Pc
626155a820 生成海报提交和详情修改右上角操作栏 2025-04-15 19:00:55 +08:00
DESKTOP-RQ919RC\Pc
3f8653b337 分享海报 2025-04-14 19:17:58 +08:00
DESKTOP-RQ919RC\Pc
b90d67fcd5 生成公寓分享图片 2025-04-11 18:59:28 +08:00
DESKTOP-RQ919RC\Pc
77702b3d24 将详情页分享title撤回,修改求房源分享的title 2025-04-10 19:01:22 +08:00
DESKTOP-RQ919RC\Pc
a729434ef9 添加新统计、扩大开屏广告点击范围、修改公寓列表的学校滚动定位不准、详情页修改默认提示文本、详情修改分享文本和取消分享图、求房源顶部加返回首页按钮 2025-04-10 15:38:37 +08:00
A1300399510
efc800d474 增加开屏广告和修改轮播图问题 2025-02-26 18:56:47 +08:00
A1300399510
b55f1ddfac 加几个请求状态 2025-02-25 19:19:29 +08:00
A1300399510
ff28e698b8 租房新通知 2025-02-24 18:58:52 +08:00
A1300399510
d733bb6aa3 新联系咨询 2025-02-21 19:04:24 +08:00
A1300399510
3e52da9b75 useSocket增加appid字段 2024-12-17 18:21:35 +08:00
A1300399510
5d13c7312f Merge remote-tracking branch 'origin/xiao' into xiao 2024-12-09 16:16:27 +08:00
A1300399510
87b9919576 no message 2024-12-09 16:15:10 +08:00
A1300399510
e6e7de1d79 Revert "no message"
This reverts commit 751572c1b4bcd7f31bcbb547df970a37a7441698.
2024-12-09 16:14:13 +08:00
A1300399510
751572c1b4 no message 2024-12-09 16:11:23 +08:00
A1300399510
27d3cb9cb5 no message 2024-12-06 13:28:54 +08:00
A1300399510
68734c864b 增加分享朋友圈 2024-11-12 14:33:37 +08:00
A1300399510
a6cc6e8dd8 no message 2024-11-06 19:05:43 +08:00
A1300399510
befe71dbdc no message 2024-10-29 14:34:43 +08:00
A1300399510
4aaf2f706c no message 2024-10-28 10:31:28 +08:00
A1300399510
2489554cd0 no message 2024-10-25 18:46:51 +08:00
A1300399510
992b0a78b1 no message 2024-10-23 18:36:42 +08:00
A1300399510
cd9085afc2 增加旧页面跳转 2024-10-23 11:43:03 +08:00
A1300399510
768ad1d475 增加搜索统计 2024-10-23 11:05:00 +08:00
A1300399510
d155f9c9d5 修改统计调错方法 2024-10-23 10:42:38 +08:00
A1300399510
d5fb61e725 提交统计 2024-10-22 15:18:26 +08:00
A1300399510
2445843155 no message 2024-09-28 19:42:00 +08:00
A1300399510
b521c63467 修改自动循环播放,进度条和底部重合 2024-09-28 18:55:34 +08:00
A1300399510
5726a164df 预览组件 2024-09-27 19:06:49 +08:00
A1300399510
87d9baf367 增加预览组件 2024-09-26 19:03:30 +08:00
A1300399510
d79738dd15 公寓列表 找房源列表换弹窗按钮 2024-05-27 17:38:57 +08:00
A1300399510
77d8988f87 修改首页弹窗 2024-05-27 16:54:42 +08:00
A1300399510
9ca9afad56 no message 2024-05-27 15:16:54 +08:00
A1300399510
7d2885e806 修改 弹窗按钮 加载中不显示 2024-05-27 15:04:23 +08:00
A1300399510
5d84503b4a no message 2024-05-24 18:38:34 +08:00
A1300399510
cf83a7deb9 首页加一个弹窗 2024-05-24 18:29:43 +08:00
A1300399510
74e98f5e79 修改bug 2024-05-08 18:49:41 +08:00
A1300399510
07ada9d949 修改一个地图找房小bug 2024-04-24 19:02:01 +08:00
A1300399510
ab68eb1dae 公寓详情进入学校距离 2024-04-18 18:54:33 +08:00
A1300399510
63c96b34c9 修改公寓联系弹窗样式 2024-04-17 18:41:58 +08:00
A1300399510
9a45b7f42b 增加公寓列表下拉刷新 2024-04-17 14:49:21 +08:00
A1300399510
b168bb21b1 no message 2024-04-17 14:15:12 +08:00
A1300399510
e41c4af2e3 修改公寓列表的请求方式 2024-04-17 14:12:32 +08:00
A1300399510
cc65dd8e00 距离院校新样式提交 2024-04-15 19:01:48 +08:00
A1300399510
2fdda45cea 头像加入一个报错提示,审核时不出现播放视频,距离院校新样式(还没) 2024-04-12 18:51:48 +08:00
A1300399510
425f2dd197 加入审核模式下播放不了视频 2024-04-12 11:38:35 +08:00
A1300399510
6f84410c11 详情附近院校距离提交测试 2024-04-10 18:58:28 +08:00
A1300399510
bea30fb716 院校距离弹窗 2024-04-09 19:01:09 +08:00
A1300399510
58ddcd1469 距离院校弹窗(还没) 2024-04-08 19:03:42 +08:00
A1300399510
496edf367e 小程序加入筛选更多(还没) 2024-04-07 19:04:42 +08:00
A1300399510
f2ddc05331 删除不要代码 2024-03-29 18:35:43 +08:00
A1300399510
260efcfce1 删掉一下打印和不用图片、公寓详情的简介自动换行 2024-03-29 12:17:21 +08:00
A1300399510
72eb5874fe 删掉一些不用的代码 2024-03-28 19:03:09 +08:00
A1300399510
e4598544e3 删除不需要的代码,删除公寓预定页面 2024-03-28 11:07:48 +08:00
A1300399510
d8779cef12 删除打印无用代码,将图标上传服务器 2024-03-26 19:06:07 +08:00
A1300399510
71c76ae21b 修改地图插件版本号、将中介房源列表单独路径、公寓详情的同品牌公寓收藏绑数据、删除一下旧代码 2024-03-26 18:29:27 +08:00
A1300399510
4c5013f3b3 修改我的 顶一顶 弹出认证框,发布添加提示文本,优化下架确认框样式。 2024-03-25 19:08:59 +08:00
A1300399510
63d65b9e2d 顶一顶后弹窗-还没 2024-03-22 19:04:33 +08:00
A1300399510
16ac41dba3 4.1版本 2024-03-18 19:06:37 +08:00
A1300399510
7b8de0d120 房源公寓增加收藏 2024-03-15 19:07:53 +08:00
A1300399510
3991cb2ec7 求房源筛选修改全局 2024-03-14 19:08:03 +08:00
A1300399510
3a61ca91cb 列表筛选值全局 2024-03-13 19:08:04 +08:00
A1300399510
5b3e1db74b 修改渲染数组为空问题 2024-03-04 18:54:23 +08:00
A1300399510
507c40ecb3 no message 2024-02-19 10:44:22 +08:00
A1300399510
00fb5b96bf no message 2024-02-02 11:34:14 +08:00
A1300399510
a9f58aa9b2 no message 2023-11-01 19:02:14 +08:00
A1300399510
b251d4daa5 修改 2023-08-15 18:31:01 +08:00
A1300399510
7c6e6d4dc7 修改 2023-08-15 14:55:24 +08:00
A1300399510
95913f7bf3 修改求房源列表筛选的判断 2023-07-21 11:27:36 +08:00
A1300399510
1885c660c1 删除判断 2023-07-17 10:01:05 +08:00
A1300399510
6f458557ec 修改筛选发布时间默认值 2023-07-13 12:27:21 +08:00
A1300399510
57f59bea72 修改筛选条件“发布时间”为不限 2023-07-11 17:49:49 +08:00
A1300399510
8085d1fb78 提交 2023-07-07 19:38:35 +08:00
A1300399510
2c4278ba5f 修改系统消息 2023-07-06 19:01:41 +08:00
66b161db72 房源数量类型转换 2023-07-06 18:46:06 +08:00
ce84cdad7c 选项框下边框 2023-07-06 18:40:48 +08:00
A1300399510
3e8b72023f 恢复系统通知的群发 2023-07-06 15:52:48 +08:00
A1300399510
76a417f7ec 提交新系统通知 2023-07-06 15:33:18 +08:00
350b692f78 图片判断 增加先判断视频再判断图片 2023-07-06 14:51:34 +08:00
d409c00d2a 添加ispic是否显示图片判断 2023-07-06 14:39:20 +08:00
c0a51810c0 isvideo判断 2023-07-06 12:29:32 +08:00
A1300399510
e8600255d7 修改点击加号判断名称 2023-07-06 10:53:26 +08:00
A1300399510
1653b3d632 修改一些bug 2023-07-05 19:15:00 +08:00
A1300399510
9a7d7371fd Merge branch 'xiao' of https://x--mo.com:9003/gter.net/HKRentingMiniprogram into xiao 2023-07-05 16:56:47 +08:00
A1300399510
f7ed879537 删除旧版本代码 2023-07-05 16:56:38 +08:00
6f6031e2f8 增加PC端打开地图显示地图标记点 2023-07-05 14:19:36 +08:00
A1300399510
90c139f358 接口引入地图找房state 2023-07-04 19:16:06 +08:00
83e75412af 地图房源重叠处理 2023-07-04 19:02:19 +08:00
A1300399510
a8fc59ad6f 在我的-发布 列表增加发布时间 2023-07-04 15:27:31 +08:00
A1300399510
f59702ae1a 增加全局的地图找房入口 2023-07-04 12:32:08 +08:00
6e6b4d5ef2 切换地图显示类型时清空数据 2023-07-04 11:28:50 +08:00
A1300399510
8a75127988 提交 2023-07-04 10:16:06 +08:00
180c83c7a5 地图房源调整地图中心 2023-07-03 16:46:33 +08:00
40b961e27f 地图房源调整地图中心 2023-07-03 16:43:27 +08:00
A1300399510
8ffbb977b0 Merge branch 'xiao' of https://x--mo.com:9003/gter.net/HKRentingMiniprogram into xiao 2023-07-03 16:41:51 +08:00
A1300399510
67ed6940ad get请求接口加扫码参数 2023-07-03 16:41:34 +08:00
A1300399510
b8c9097dd6 打开地图找房的 tab 的中介 2023-07-03 15:59:17 +08:00
A1300399510
55017dbf13 修改打开user页面的tab 2023-07-03 15:58:36 +08:00
0e845c5f48 ios公寓地图房源修改 2023-07-03 15:04:41 +08:00
A1300399510
e5fffe9268 删除”独立套房“筛选,修改求房源筛选组件的名称 2023-07-03 14:43:00 +08:00
d3c6af5296 地图总房源数和搜索房源总数互通 2023-07-03 14:41:14 +08:00
f26297b542 地图总房源数和搜索房源总数互通 2023-07-03 14:37:42 +08:00
a22ca015f5 搜索页面加载更多数据后地图房源不显示 2023-07-03 09:51:03 +08:00
A1300399510
3c81975e52 提交 2023-06-30 18:56:57 +08:00
2d72cd5b3f 地图房源接口防抖处理 地图房源请求数据增加到50 退出页面清空筛选条件 2023-06-30 17:58:37 +08:00
A1300399510
2872a00278 提交 2023-06-30 17:18:04 +08:00
A1300399510
a6fce674f0 提交 2023-06-30 15:43:04 +08:00
A1300399510
8315ee61fd 提交 2023-06-30 15:39:11 +08:00
A1300399510
d055919bde Merge branch 'xiao' of https://x--mo.com:9003/gter.net/HKRentingMiniprogram into xiao
# Conflicts:
#	template/listOperations/listOperations.wxml
2023-06-30 15:37:21 +08:00
A1300399510
b57561db44 提交 2023-06-30 15:35:41 +08:00
71b7e23abf 地图房源搜索-搜索组件样式 2023-06-30 15:34:15 +08:00
A1300399510
1b5f89b876 提交 2023-06-30 14:54:12 +08:00
A1300399510
4fddb770f9 提交 2023-06-30 10:21:26 +08:00
A1300399510
9e3fe3aa38 提交 2023-06-29 19:13:15 +08:00
A1300399510
ce81909b43 提交 2023-06-29 16:57:59 +08:00
A1300399510
2d8f407e26 4.0版本上线后,地图找房前 2023-06-29 16:33:52 +08:00
337 changed files with 34463 additions and 12539 deletions

2
.gitignore vendored
View File

@ -2,4 +2,4 @@
/.git /.git
*.log *.log
project.private.config.json project.private.config.json
project.config.json node_modules

4
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"recommendations": [
]
}

8
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"files.associations": {
"*.wxss": "css",
"*.tpl": "html",
"*.vue": "vue",
"*.wxml": "wxml"
}
}

100
app.js
View File

@ -1,7 +1,42 @@
//app.js wx9c68fbf7886ea9c4 租房的 wxcf0a799771cf2ae6 港校的 //app.js wx9c68fbf7886ea9c4 租房的 wxcf0a799771cf2ae6 港校的
var initial_url = 'https://app.gter.net/tenement'; var initial_url = 'https://app.gter.net/tenement';
var __ = require('./utils/miucms.js'); var __ = require('./utils/miucms.js');
import './utils/xstat';
// // 保存原始的Page构造器
// const originPage = Page;
// // 重写Page构造器
// Page = function (pageConfig) {
// // 添加全局的onShow逻辑
// const originOnLoad = pageConfig.onLoad;
// pageConfig.onLoad = function () {
// __.statistics({})
// if (originOnLoad) originOnLoad.apply(this, arguments);
// };
// const originOnShare = pageConfig.onShareAppMessage;
// if (originOnShare) {
// // pageConfig.onShareAppMessage = function () {
// pageConfig.onShareAppMessage = function (e) {
// __.statistics({
// name: "share"
// })
// // if (originOnShare) originOnShare.apply(this, arguments);
// return originOnShare.apply(this, [e]);
// };
// }
// // 调用原始的Page函数
// return originPage(pageConfig);
// };
App({ App({
xstatConfig: {
appKey: wx.getAccountInfoSync().miniProgram.appId, // 自动获取 小程序appid
debug: true, //是否打开调试模式
LOG_URL: 'https://stat.gter.net/send', // 上报地址
},
randomString(n) { randomString(n) {
let str = 'abcdefghijklmnopqrstuvwxyz9876543210'; let str = 'abcdefghijklmnopqrstuvwxyz9876543210';
let tmp = '', let tmp = '',
@ -24,19 +59,16 @@ App({
title: '更新提示', title: '更新提示',
content: '检测到新版本,是否下载新版本并重启小程序?', content: '检测到新版本,是否下载新版本并重启小程序?',
success: function (res) { success: function (res) {
if (res.confirm) { if (res.confirm) self.downLoadAndUpdate(updateManager)
self.downLoadAndUpdate(updateManager) else if (res.cancel) {
} else if (res.cancel) {
wx.showModal({ wx.showModal({
title: '温馨提示', title: '温馨提示',
content: '本次版本更新涉及到新的功能添加,旧版本无法正常访问', content: '本次版本更新涉及到新的功能添加,旧版本无法正常访问',
showCancel: false, showCancel: false,
confirmText: "确定更新", confirmText: "确定更新",
success: function (res) { success: function (res) {
if (res.confirm) {
//下载新版本,并重新应用 //下载新版本,并重新应用
self.downLoadAndUpdate(updateManager) if (res.confirm) self.downLoadAndUpdate(updateManager)
}
} }
}) })
} }
@ -68,15 +100,20 @@ App({
}) })
}, },
onLaunch: function (options) { onLaunch: function (options) {
// __.statistics({
// data: {
// scene: options.scene
// },
// path: options.path,
// query: options.query,
// name: "onLaunch"
// })
this.globalData.options = options; this.globalData.options = options;
__.initial(this) __.initial(this)
if (wx.getEnterOptionsSync().query && wx.getEnterOptionsSync().query.scancode_time) { if (wx.getEnterOptionsSync().query && wx.getEnterOptionsSync().query.scancode_time) this.globalData.scancode_time = wx.getEnterOptionsSync().query.scancode_time
this.globalData.scancode_time = wx.getEnterOptionsSync().query.scancode_time if (wx.getUserProfile) this.globalData.canIUseGetUserProfile = true;
}
if (wx.getUserProfile) {
this.globalData.canIUseGetUserProfile = true;
}
try { try {
@ -103,10 +140,7 @@ App({
} }
}, },
onShow() {
},
computeNavigateBarHeight: function () { computeNavigateBarHeight: function () {
var systemInfo = wx.getSystemInfoSync(); var systemInfo = wx.getSystemInfoSync();
var data = wx.getMenuButtonBoundingClientRect() var data = wx.getMenuButtonBoundingClientRect()
@ -125,17 +159,25 @@ App({
} }
}, },
onShow: function (options) { onShow: function (options) {
// console.log('onShow', options)
this.globalData.source = options.path || ''; this.globalData.source = options.path || '';
// 判断socket从后台打开 并且已经断开链接了,需要重启
// if (this.globalData.isHideState && this.globalData.socketTask && this.globalData.socketTask['readyState'] != 1) {
// }
// this.globalData.isHideState = false
const timer = setInterval(() => {
if (this.globalData.config && this.globalData.config.lists) {
__.useSocket()
clearInterval(timer)
}
}, 100)
}, },
onHide: function () { onHide: function () {
this.globalData.isHideState = true
}, },
onError: function () { onError: function () {
// 这里回调错误信息 // 这里回调错误信息
console.log('onError')
}, },
// get: function () { // get: function () {
// return this.globalData.config; // return this.globalData.config;
@ -174,7 +216,7 @@ App({
listTab: {}, listTab: {},
canIUseGetUserProfile: false, canIUseGetUserProfile: false,
scancode_time: "", scancode_time: "",
irentCouponBig: true, irentCouponBig: false,
unreadMessagesState: false, unreadMessagesState: false,
firstWxParseImgLoaddState: false, firstWxParseImgLoaddState: false,
topTitle: "", // 寄托港校租房 寄托香港租房 topTitle: "", // 寄托港校租房 寄托香港租房
@ -183,5 +225,25 @@ App({
1: "#50e3c2", 1: "#50e3c2",
6: "#b3c7f4" 6: "#b3c7f4"
}, },
isMapFindState: false, // 地图找房入口
isShowVideo: true, // 是否显示视频
socketTask: null, // 全局的 socket 值
isHideState: true, // 判断是否 隐藏了 在 onshow 为 true 是代表小程序后台打开
brandSelectionObj: {}, // 品牌公寓筛选全局值
personSelectionObj: {}, // 个人房源筛选全局值
intermediarySelectionObj: {}, // 中介房源筛选全局值
restSelectionObj: {}, // 求房源筛选全局值
editShelfState: "", // 判断 我的页面 在点击 编辑上架 后重新进入是否需要 刷新数据的 update 代表需要更新数据
popwindow: "", // 首页弹窗信息
isConnected: false,
offerkaipingadvertisement: {}, // 开屏广告 数据
offerkaipingadvertisementState: false, // 开屏广告 状态
initialState: false,
} }
}) })

View File

@ -3,48 +3,85 @@
"pages/index/index", "pages/index/index",
"pages/appeal/appeal", "pages/appeal/appeal",
"pages/restOfWorld/restOfWorld", "pages/restOfWorld/restOfWorld",
"pages/needHousing/needHousing",
"pages/personList/personList", "pages/personList/personList",
"pages/intermediaryList/intermediaryList",
"pages/agentList/agentList",
"pages/brandApartmentList/brandApartmentList",
"pages/irentList/irentList", "pages/irentList/irentList",
"pages/quarantineLists/quarantineLists",
"pages/report/report", "pages/report/report",
"pages/irentPark/irentPark", "pages/irentPark/irentPark",
"pages/user/user", "pages/user/user",
"pages/search/search", "pages/search/search",
"pages/edit/edit", "pages/edit/edit",
"pages/ad/ad", "pages/ad/ad",
"pages/brandApartmentDetail/brandApartmentDetail",
"pages/irentDetail/irentDetail", "pages/irentDetail/irentDetail",
"pages/irentForm/irentForm",
"pages/show/show", "pages/show/show",
"pages/video_show/video_show",
"pages/share/share", "pages/share/share",
"pages/login/index",
"pages/messageCenter/messageCenter", "pages/messageCenter/messageCenter",
"pages/webViewwebweb/index", "pages/webViewwebweb/index",
"pages/circularize/circularize", "pages/circularize/circularize",
"pages/askHousing/askHousing", "pages/askHousing/askHousing",
"pages/transfer/transfer", "pages/transfer/transfer",
"pages/findingMap/findingMap" "pages/video_show/video_show"
], ],
"subpackages": [
"subpackages": [{ {
"root": "pagesLoginRequired", "root": "pagesLoginRequired",
"name": "pagesLoginRequired", "name": "pagesLoginRequired",
"pages": [ "pages": [
"pages/setAvatarNickname/setAvatarNickname" "pages/setAvatarNickname/setAvatarNickname"
] ]
}], },
{
"root": "mapFind",
"pages": [
"pages/placeMap/index"
]
}
],
"preloadRule": { "preloadRule": {
"pages/index/index": { "pages/index/index": {
"network": "all", "network": "all",
"packages": [ "packages": [
"pagesLoginRequired" "pagesLoginRequired",
"mapFind"
] ]
}, },
"pages/show/show": { "pages/show/show": {
"network": "all", "network": "all",
"packages": [ "packages": [
"pagesLoginRequired" "pagesLoginRequired",
"mapFind"
]
},
"pages/brandApartmentList/brandApartmentList": {
"network": "all",
"packages": [
"pagesLoginRequired",
"mapFind"
]
},
"pages/agentList/agentList": {
"network": "all",
"packages": [
"pagesLoginRequired",
"mapFind"
]
},
"pages/personList/personList": {
"network": "all",
"packages": [
"pagesLoginRequired",
"mapFind"
]
},
"pages/search/search": {
"network": "all",
"packages": [
"pagesLoginRequired",
"mapFind"
] ]
} }
}, },
@ -56,7 +93,10 @@
"enablePullDownRefresh": true, "enablePullDownRefresh": true,
"navigationStyle": "custom" "navigationStyle": "custom"
}, },
"requiredPrivateInfos": ["chooseLocation", "getLocation"], "requiredPrivateInfos": [
"chooseLocation",
"getLocation"
],
"permission": { "permission": {
"scope.userLocation": { "scope.userLocation": {
"desc": "你的位置信息将用于小程序位置的获取" "desc": "你的位置信息将用于小程序位置的获取"
@ -67,11 +107,15 @@
"wxc7845752d17217d1", "wxc7845752d17217d1",
"wxfe8d2300e92c8e44" "wxfe8d2300e92c8e44"
], ],
"embeddedAppIdList": ["wxa9296b07391c2bc7"], "embeddedAppIdList": [
"requiredBackgroundModes": ["location"], "wxa9296b07391c2bc7"
],
"requiredBackgroundModes": [
"location"
],
"plugins": { "plugins": {
"chooseLocation": { "chooseLocation": {
"version": "1.0.10", "version": "1.1.1",
"provider": "wx76a9a06e5b4e693e" "provider": "wx76a9a06e5b4e693e"
} }
} }

0
common/common.wxss Normal file
View File

27
css/common.wxss Normal file
View File

@ -0,0 +1,27 @@
/* 公共的flex 布局方法 */
.flexflex {
display: flex;
}
.flexcenter {
display: flex;
justify-content: center;
align-items: center;
}
.flexacenter {
display: flex;
align-items: center;
}
.flex1 {
flex: 1;
}
/* 文字一行显示 */
.one-line-display {
word-break: keep-all;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

6
img/arrow-green.svg Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="7px" height="12px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -900 -691 )">
<path d="M 6.76909722222222 5.47265625 C 6.92303240740741 5.62109375 7 5.796875 7 6 C 7 6.203125 6.92303240740741 6.37890625 6.76909722222222 6.52734375 L 1.32465277777778 11.77734375 C 1.17071759259259 11.92578125 0.988425925925926 12 0.777777777777778 12 C 0.56712962962963 12 0.384837962962963 11.92578125 0.230902777777778 11.77734375 C 0.0769675925925926 11.62890625 0 11.453125 0 11.25 L 0 0.75 C 0 0.546874999999998 0.0769675925925926 0.371093749999998 0.230902777777778 0.22265625 C 0.384837962962963 0.0742187499999991 0.56712962962963 0 0.777777777777778 0 C 0.988425925925926 0 1.17071759259259 0.0742187499999991 1.32465277777778 0.22265625 L 6.76909722222222 5.47265625 Z " fill-rule="nonzero" fill="#50e3c2" stroke="none" transform="matrix(1 0 0 1 900 691 )" />
</g>
</svg>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="12px" height="9px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -2574 -340 )">
<path d="M 11.7832258064516 1.24242424242424 C 11.9277419354839 1.38383838383838 12 1.55555555555556 12 1.75757575757576 C 12 1.95959595959596 11.9277419354839 2.13131313131313 11.7832258064516 2.27272727272727 L 6.17806451612903 7.75757575757576 L 5.12516129032258 8.78787878787879 C 4.98064516129032 8.92929292929293 4.80516129032258 9 4.59870967741935 9 C 4.39225806451613 9 4.21677419354839 8.92929292929293 4.07225806451613 8.78787878787879 L 3.01935483870968 7.75757575757576 L 0.216774193548387 5.01515151515152 C 0.0722580645161291 4.87373737373737 0 4.7020202020202 0 4.5 C 0 4.2979797979798 0.0722580645161291 4.12626262626263 0.216774193548387 3.98484848484849 L 1.26967741935484 2.95454545454545 C 1.4141935483871 2.81313131313131 1.58967741935484 2.74242424242424 1.79612903225806 2.74242424242424 C 2.00258064516129 2.74242424242424 2.17806451612903 2.81313131313131 2.32258064516129 2.95454545454545 L 4.59870967741935 5.18939393939394 L 9.67741935483871 0.212121212121212 C 9.82193548387097 0.0707070707070704 9.99741935483871 0 10.2038709677419 0 C 10.4103225806452 0 10.5858064516129 0.0707070707070704 10.7303225806452 0.212121212121212 L 11.7832258064516 1.24242424242424 Z " fill-rule="nonzero" fill="#000000" stroke="none" transform="matrix(1 0 0 1 2574 340 )" />
</g>
</svg>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 435 B

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="18px" height="18px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -321 -1696 )">
<path d="M 7.875 15.0703125 C 8.078125 15.0703125 8.25390625 14.99609375 8.40234375 14.84765625 L 13.72265625 9.52734375 C 13.87109375 9.37890625 13.9453125 9.203125 13.9453125 9 C 13.9453125 8.796875 13.87109375 8.62109375 13.72265625 8.47265625 L 8.40234375 3.15234375 C 8.25390625 3.00390625 8.078125 2.9296875 7.875 2.9296875 C 7.671875 2.9296875 7.49609375 3.00390625 7.34765625 3.15234375 L 6.15234375 4.34765625 C 6.00390625 4.49609375 5.9296875 4.671875 5.9296875 4.875 C 5.9296875 5.078125 6.00390625 5.25390625 6.15234375 5.40234375 L 9.75 9 L 6.15234375 12.59765625 C 6.00390625 12.74609375 5.9296875 12.921875 5.9296875 13.125 C 5.9296875 13.328125 6.00390625 13.50390625 6.15234375 13.65234375 L 7.34765625 14.84765625 C 7.49609375 14.99609375 7.671875 15.0703125 7.875 15.0703125 Z M 16.79296875 4.482421875 C 17.59765625 5.861328125 18 7.3671875 18 9 C 18 10.6328125 17.59765625 12.138671875 16.79296875 13.517578125 C 15.98828125 14.896484375 14.896484375 15.98828125 13.517578125 16.79296875 C 12.138671875 17.59765625 10.6328125 18 9 18 C 7.3671875 18 5.861328125 17.59765625 4.482421875 16.79296875 C 3.103515625 15.98828125 2.01171875 14.896484375 1.20703125 13.517578125 C 0.40234375 12.138671875 0 10.6328125 0 9 C 0 7.3671875 0.40234375 5.861328125 1.20703125 4.482421875 C 2.01171875 3.103515625 3.103515625 2.01171875 4.482421875 1.20703125 C 5.861328125 0.402343749999998 7.3671875 0 9 0 C 10.6328125 0 12.138671875 0.402343749999998 13.517578125 1.20703125 C 14.896484375 2.01171875 15.98828125 3.103515625 16.79296875 4.482421875 Z " fill-rule="nonzero" fill="#50e3c2" stroke="none" transform="matrix(1 0 0 1 321 1696 )" />
</g>
</svg>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

BIN
img/load.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 978 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

BIN
img/subway-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="30px" height="30px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -494 -916 )">
<path d="M 5.45454545454546 21.8181818181818 L 8.18181818181818 21.8181818181818 L 8.18181818181818 24.5454545454545 L 5.45454545454546 24.5454545454545 L 5.45454545454546 21.8181818181818 Z M 5.45454545454546 5.45454545454545 L 8.18181818181818 5.45454545454545 L 8.18181818181818 8.18181818181818 L 5.45454545454546 8.18181818181818 L 5.45454545454546 5.45454545454545 Z M 21.8181818181818 5.45454545454545 L 24.5454545454545 5.45454545454545 L 24.5454545454545 8.18181818181818 L 21.8181818181818 8.18181818181818 L 21.8181818181818 5.45454545454545 Z M 2.72727272727273 19.0909090909091 L 2.72727272727273 27.2514204545455 L 10.9090909090909 27.2514204545455 L 10.9090909090909 19.0909090909091 L 2.72727272727273 19.0909090909091 Z M 2.72727272727273 2.72727272727273 L 2.72727272727273 10.9090909090909 L 10.9090909090909 10.9090909090909 L 10.9090909090909 2.72727272727273 L 2.72727272727273 2.72727272727273 Z M 19.0909090909091 2.72727272727273 L 19.0909090909091 10.9090909090909 L 27.2727272727273 10.9090909090909 L 27.2727272727273 2.72727272727273 L 19.0909090909091 2.72727272727273 Z M 0 16 L 14 16 L 14 30 L 0 30 L 0 16 Z M 21.8181818181818 27.2727272727273 L 24.5454545454545 27.2727272727273 L 24.5454545454545 30 L 21.8181818181818 30 L 21.8181818181818 27.2727272727273 Z M 27.2727272727273 27.2727272727273 L 30 27.2727272727273 L 30 30 L 27.2727272727273 30 L 27.2727272727273 27.2727272727273 Z M 27.2727272727273 16.3636363636364 L 30 16.3636363636364 L 30 24.5454545454545 L 21.8181818181818 24.5454545454545 L 21.8181818181818 21.8181818181818 L 19.0909090909091 21.8181818181818 L 19.0909090909091 30 L 16 30 L 16 16.3636363636364 L 24.5454545454545 16.3636363636364 L 24.5454545454545 19.0909090909091 L 27.2727272727273 19.0909090909091 L 27.2727272727273 16.3636363636364 Z M 0 0 L 14 0 L 14 14 L 0 14 L 0 0 Z M 16 0 L 30 0 L 30 14 L 16 14 L 16 0 Z " fill-rule="nonzero" fill="#62b1ff" stroke="none" transform="matrix(1 0 0 1 494 916 )" />
</g>
</svg>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="18px" height="8px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -1209 -789 )">
<path d="M 17.8958333333333 3.73472041612484 C 17.9652777777778 3.80407455570004 18 3.88383181621153 18 3.9739921976593 C 18 4.07108799306459 17.9652777777778 4.15431296055483 17.8958333333333 4.22366710013004 L 13.8958333333333 7.90637191157347 C 13.7847222222222 8.00346770697876 13.6631944444444 8.02427394885132 13.53125 7.96879063719116 C 13.3993055555556 7.90637191157347 13.3333333333333 7.80580840918942 13.3333333333333 7.66710013003901 L 13.3333333333333 5.33680104031209 L 0.333333333333333 5.33680104031209 C 0.236111111111111 5.33680104031209 0.15625 5.30559167750325 0.09375 5.24317295188557 C 0.03125 5.18075422626788 0 5.10099696575639 0 5.0039011703511 L 0 3.00650195058518 C 0 2.90940615517989 0.03125 2.8296488946684 0.09375 2.76723016905072 C 0.15625 2.70481144343303 0.236111111111111 2.67360208062419 0.333333333333333 2.67360208062419 L 13.3333333333333 2.67360208062419 L 13.3333333333333 0.34330299089727 C 13.3333333333333 0.197659297789337 13.3993055555556 0.0970957954052878 13.53125 0.0416124837451237 C 13.6631944444444 -0.0138708279150421 13.7847222222222 0.00346770697875964 13.8958333333333 0.0936280884265281 L 17.8958333333333 3.73472041612484 Z " fill-rule="nonzero" fill="#61b1fc" stroke="none" transform="matrix(1 0 0 1 1209 789 )" />
</g>
</svg>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="20px" height="20px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -2102 -463 )">
<path d="M 19.5286195286195 14.9494949494949 C 19.8428731762065 15.2637485970819 20 15.645342312009 20 16.0942760942761 C 20 16.5432098765432 19.8428731762065 16.9248035914703 19.5286195286195 17.2390572390572 L 17.2390572390572 19.5286195286195 C 16.9248035914703 19.8428731762065 16.5432098765432 20 16.0942760942761 20 C 15.645342312009 20 15.2637485970819 19.8428731762065 14.9494949494949 19.5286195286195 L 10 14.5791245791246 L 5.05050505050505 19.5286195286195 C 4.73625140291807 19.8428731762065 4.35465768799102 20 3.90572390572391 20 C 3.45679012345679 20 3.07519640852974 19.8428731762065 2.76094276094276 19.5286195286195 L 0.471380471380471 17.2390572390572 C 0.157126823793491 16.9248035914703 0 16.5432098765432 0 16.0942760942761 C 0 15.645342312009 0.157126823793491 15.2637485970819 0.471380471380471 14.9494949494949 L 5.42087542087542 10 L 0.471380471380471 5.05050505050505 C 0.157126823793491 4.73625140291807 0 4.35465768799102 0 3.90572390572391 C 0 3.45679012345679 0.157126823793491 3.07519640852974 0.471380471380471 2.76094276094276 L 2.76094276094276 0.471380471380471 C 3.07519640852974 0.15712682379349 3.45679012345679 0 3.90572390572391 0 C 4.35465768799102 0 4.73625140291807 0.15712682379349 5.05050505050505 0.471380471380471 L 10 5.42087542087542 L 14.9494949494949 0.471380471380471 C 15.2637485970819 0.15712682379349 15.645342312009 0 16.0942760942761 0 C 16.5432098765432 0 16.9248035914703 0.15712682379349 17.2390572390572 0.471380471380471 L 19.5286195286195 2.76094276094276 C 19.8428731762065 3.07519640852974 20 3.45679012345679 20 3.90572390572391 C 20 4.35465768799102 19.8428731762065 4.73625140291807 19.5286195286195 5.05050505050505 L 14.5791245791246 10 L 19.5286195286195 14.9494949494949 Z " fill-rule="nonzero" fill="#aaaaaa" stroke="none" transform="matrix(1 0 0 1 2102 463 )" />
</g>
</svg>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -489 -1380 )">
<path d="M 7 13.3958333333333 C 7.18055555555556 13.3958333333333 7.33680555555556 13.3298611111111 7.46875 13.1979166666667 L 12.1979166666667 8.46875 C 12.3298611111111 8.33680555555555 12.3958333333333 8.18055555555555 12.3958333333333 8 C 12.3958333333333 7.81944444444444 12.3298611111111 7.66319444444444 12.1979166666667 7.53125 L 7.46875 2.80208333333333 C 7.33680555555556 2.67013888888889 7.18055555555556 2.60416666666667 7 2.60416666666667 C 6.81944444444445 2.60416666666667 6.66319444444445 2.67013888888889 6.53125 2.80208333333333 L 5.46875 3.86458333333333 C 5.33680555555556 3.99652777777778 5.27083333333333 4.15277777777778 5.27083333333333 4.33333333333333 C 5.27083333333333 4.51388888888889 5.33680555555556 4.67013888888889 5.46875 4.80208333333333 L 8.66666666666667 8 L 5.46875 11.1979166666667 C 5.33680555555556 11.3298611111111 5.27083333333333 11.4861111111111 5.27083333333333 11.6666666666667 C 5.27083333333333 11.8472222222222 5.33680555555556 12.0034722222222 5.46875 12.1354166666667 L 6.53125 13.1979166666667 C 6.66319444444445 13.3298611111111 6.81944444444445 13.3958333333333 7 13.3958333333333 Z M 14.9270833333333 3.984375 C 15.6423611111111 5.21006944444444 16 6.54861111111111 16 8 C 16 9.45138888888889 15.6423611111111 10.7899305555556 14.9270833333333 12.015625 C 14.2118055555556 13.2413194444444 13.2413194444444 14.2118055555556 12.015625 14.9270833333333 C 10.7899305555556 15.6423611111111 9.45138888888889 16 8 16 C 6.54861111111111 16 5.21006944444444 15.6423611111111 3.984375 14.9270833333333 C 2.75868055555556 14.2118055555556 1.78819444444444 13.2413194444444 1.07291666666667 12.015625 C 0.357638888888889 10.7899305555556 0 9.45138888888889 0 8 C 0 6.54861111111111 0.357638888888889 5.21006944444444 1.07291666666667 3.984375 C 1.78819444444444 2.75868055555556 2.75868055555556 1.78819444444444 3.984375 1.07291666666667 C 5.21006944444444 0.357638888888888 6.54861111111111 0 8 0 C 9.45138888888889 0 10.7899305555556 0.357638888888888 12.015625 1.07291666666667 C 13.2413194444444 1.78819444444444 14.2118055555556 2.75868055555556 14.9270833333333 3.984375 Z " fill-rule="nonzero" fill="#333333" stroke="none" transform="matrix(1 0 0 1 489 1380 )" />
</g>
</svg>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 B

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="410px" height="176px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -1355 -525 )">
<path d="M 410 149.99904249698 L 410 176 L 0 175.992220833275 L 0 150 C 5.59999999999991 150 10 145.6 10 140 C 10 134.4 5.59999999999991 130 0 130.001047820082 L 0 30 C 0 13.2 13.1999999999998 0 30 0 L 189 0 C 189 8.39999999999998 195.6 15 204 15 C 212.4 15 219 8.39999999999998 218.999999993792 0 L 219.001244376811 0 L 380 0 C 396.8 0 410 13.2 410 30 L 410 130 C 404.4 130 400 134.4 400 140 C 400 145.6 404.4 150 410 149.999042373321 L 410 130.001048239889 L 410 149.99904249698 Z M 0 130.001047882063 L 0 149.99903317808 L 0 130.001047882063 Z M 189.002758033491 0 L 218.999999993792 0 L 189.002758033491 0 Z " fill-rule="nonzero" fill="#f2f2f2" stroke="none" transform="matrix(1 0 0 1 1355 525 )" />
</g>
</svg>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 817 B

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

BIN
img/walk-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
img/wechat-name-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

11
img/wechat-name-icon.svg Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="22px" height="22px" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter x="-50.00%" y="-50.00%" width="200.00%" height="200.00%" filterUnits="objectBoundingBox" id="filter696">
<feColorMatrix type="matrix" values="0.933333333333333 0 0 0 0.0777777777777778 0 0.933333333333333 0 0 0.0777777777777778 0 0 0.933333333333333 0 0.0777777777777778 0 0 0 1 0 " in="SourceGraphic" />
</filter>
</defs>
<g transform="matrix(1 0 0 1 -929 -806 )">
<image preserveAspectRatio="none" style="overflow:visible" width="22" height="22" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAQKADAAQAAAABAAAAQAAAAABGUUKwAAAGw0lEQVR4Ae1bvVYbRxSeWYGIASeL7RxTbp4A0rlDdOmsR5CfAOjSGbp0KFVK5DKV4QmiPIFF5y5Ll3MSfBaDDRKgyXdXWnuZvbM7u1oJHSIV7M6dO3fu983c+V2EmP1mDMwYmDHwP2ZATgq763nuzYVYu+2LdVTqhvVKsR4+lejQUwkRVBzRmVsWx4HvB2HemP+MlYDlZ14NoF6qvsBTDcBaApJCdqQj2nDw6OJfv21ZLLda6QRQS/c+ii0Ab6BNvdwesQWkD0db1W/Fr2X3jNIIiIAD9DbAuyyOEYVwFmEhm2USUQoBi0+9ulJiv7wWz2IKPUKKnc+n/mGWZlb+SASErX4u9pVSjayK4vmI72MlqTW//qQSLsaJta+S7DcpZav6WOyMEhaFCVj63ltXt+LAZnCDo0foIe2FqjgM/vb9NGjuqud1e6KOFq6B2JdpupQXDpYV8erTP34nS5fLL0TAALz6Iz3W5QmM08DVLNpCw3FlG45jXFHfcQBIhnoCWZGbRUjITUAWeLTIGXxqfv7g75JzZf0Wn3i7sGUkoigJuQjIAi+k/HNhXjSyunlRUsLwuBYtodQGZ6MICRXOECej7nh7Jd6i23tcPlp+7/KD37i6CO4MbpxuURnZvrkMWtVHK9RwNcbON0LJF0vP3d+vguCKyU+IrAlwKu5viMOfEhYgcKR8hS7f5PLGIbu+DNoLiysnaIw6Y3+135Or0Dli8hIiKwIG87z6JVEaAgL/6dRvcXnjlAFgJ4WE9eriyjF03mf5kEkAdf2brngLQ65ujLr9JFter59IMIeDfLH83H2TFQqZBDiO+zNWeMmuhgGPYl53atJpkNCeX1zZRL2eVrfb78ou5WvyO0nnTkpLUOsD/JYmpsXHGY32uvy+0uTLcPrVXFBbAwyaOJZMJQC7OtPGpjmuqS7mm/Xr0JemXoAWaoRBl8fTNJ0Yf4+eeH8lNzjyBF3fMxa6pwxqaYD1kytG6cPfH0xuGXsAHWYkwYfLzpbJ2H3Kh8vtRC8gDAMsvHdGArB5qXNFaG3PyadBZvLNhIV8TiNgQwdFu7qiGxvd1jjS5Bv5qNsGAQkskQ5LAMUTt82FoXZUcFqfnI+ExTQbsATg9HadA0j7eU4+TTKnwjeSCRNLAB1dc6Cmaerj/COZ6UzAhIklAHOjq1eAhcaxLpvWNOcrh4n8ZwnggOlneJzOtMjy+MoSAAO1aQFTmh/RLZRmkCVA03nQSZYAHFG3Hxzq4f2jjmtOF5SRprNDkGg8xS1SB8LyzDTC6/aobmyErH4sASgcJEobDiITehDgvqDeF+o1l1dUhpF9D2U7NuXZRRyHCcbYEKAraq4iallOPk0yk48mTCwBc3PCZ0EZFki6rqyUv2K0tdm/FTXdH0rjmwO2UVkCBis+eaIbQmjUdRmXpljlT2g47WwZ2bKOf3YKlyemTRxLALmEu7m27hrd1Zk2Fbou0k1GVkgE4ndtCoabOOY+kcMS2TMSAIXDSCn+vD636wWDq7FkL4rbsnmnZS1OdKzITDn+YrFQ/UYC6O6d68Z9JaxHd+zM6pwNG+CkQ2UR+w1bfcw/7AFu2ncERgLCSiXXC5S39NSzciocCyqiVoSEIfiabezT5SlCxWXISu09qQRU5/nYw1iwbzsWEIBqFdtr3CMwzvEi6FIZW/B0acq1PhmHnRY9Tb9UAmg2wBHTG70wMd07Fwe63JQmO5enfq3iyE3uyCoqR3mkQ7p5zh661/ShRrL1yfcsOzKq3PQkdns90UkeN2MAGeFeUD+pLfopHMKx2Vd87OOQ1DNNfxHeTAJIcRBf/NKWWqyo85ETRZ80FgG8oSfKHZvZw4qAIQnUC9Z0Z2Gg8Ocpuq086VTwdG+JMLKxlzoGxA1gMGGnNIq9/q16ZzszxG0WfV965u2bWp5mjzz3ltY9gJyljQaBNTnuOLI5vyz2suLOVD5LPvxE5gCfyNRMuk5F/mg7e5AN6x5AymSYBj565379vtrufhTvbKdIzoZJhnHoda8H8tPA06AMH002ODl7HsApRjJ0+Y3onXs6srweQERieYvVHX1+q7hFzhcXis5IuUIAn8ocYBHU+FKr9lLUibiZQZiJDWxg6EPJejyPe8+7YtRtWBOQBR6GAiVlru4XdwbHWOx1XFxHfwf4YxqcsxY7erl42oqALPBxg5N6B3j6Pml31PoyCZg28LRcxh5le5RWj5OWSsA0gad1PW3OygIekWAkYBrAU2vDwcP5x/jKfEz/Q8QSEC4zw395iXiazJMuZDDNBnTFnXc+n4yHs1pmDMwYmDHwwBj4DyubxFjRI9QYAAAAAElFTkSuQmCC" x="929px" y="806px" filter="url(#filter696)" />
</g>
</svg>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
mapFind/img/downIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
mapFind/img/pcMarker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1 0 0 1 -1882 -1184 )">
<path d="M 11.6666666666667 10.7291666666667 C 11.8472222222222 10.7291666666667 12.0034722222222 10.6631944444444 12.1354166666667 10.53125 L 13.1979166666667 9.46875 C 13.3298611111111 9.33680555555555 13.3958333333333 9.18055555555555 13.3958333333333 9 C 13.3958333333333 8.81944444444444 13.3298611111111 8.66319444444444 13.1979166666667 8.53125 L 8.46875 3.80208333333333 C 8.33680555555556 3.67013888888889 8.18055555555556 3.60416666666667 8 3.60416666666667 C 7.81944444444445 3.60416666666667 7.66319444444445 3.67013888888889 7.53125 3.80208333333333 L 2.80208333333333 8.53125 C 2.67013888888889 8.66319444444444 2.60416666666667 8.81944444444444 2.60416666666667 9 C 2.60416666666667 9.18055555555555 2.67013888888889 9.33680555555555 2.80208333333333 9.46875 L 3.86458333333333 10.53125 C 3.99652777777778 10.6631944444444 4.15277777777778 10.7291666666667 4.33333333333333 10.7291666666667 C 4.51388888888889 10.7291666666667 4.67013888888889 10.6631944444444 4.80208333333333 10.53125 L 8 7.33333333333333 L 11.1979166666667 10.53125 C 11.3298611111111 10.6631944444444 11.4861111111111 10.7291666666667 11.6666666666667 10.7291666666667 Z M 14.9270833333333 3.984375 C 15.6423611111111 5.21006944444444 16 6.54861111111111 16 8 C 16 9.45138888888889 15.6423611111111 10.7899305555556 14.9270833333333 12.015625 C 14.2118055555556 13.2413194444444 13.2413194444444 14.2118055555556 12.015625 14.9270833333333 C 10.7899305555556 15.6423611111111 9.45138888888889 16 8 16 C 6.54861111111111 16 5.21006944444444 15.6423611111111 3.984375 14.9270833333333 C 2.75868055555556 14.2118055555556 1.78819444444444 13.2413194444444 1.07291666666667 12.015625 C 0.357638888888889 10.7899305555556 0 9.45138888888889 0 8 C 0 6.54861111111111 0.357638888888889 5.21006944444444 1.07291666666667 3.984375 C 1.78819444444444 2.75868055555556 2.75868055555556 1.78819444444444 3.984375 1.07291666666667 C 5.21006944444444 0.357638888888888 6.54861111111111 0 8 0 C 9.45138888888889 0 10.7899305555556 0.357638888888888 12.015625 1.07291666666667 C 13.2413194444444 1.78819444444444 14.2118055555556 2.75868055555556 14.9270833333333 3.984375 Z " fill-rule="nonzero" fill="#fdda55" stroke="none" transform="matrix(1 0 0 1 1882 1184 )" />
</g>
</svg>

View File

@ -0,0 +1,886 @@
// pages/Map/Map.js
let app = getApp()
var miucms = require('../../../utils/miucms.js');
Page({
data: {
headerObj: {
person: "个人",
intermediary: "中介",
apartment: "公寓",
},
headerObjTab: "person",
windowHeight: 0, //屏幕高度
mapEnableScroll: true, //设置地图是否拖动
tabValue: "school", // area school
longitude: 113.36110, //默认定位经度
latitude: 23.12463, //默认定位纬度
mapScale: 11, //地图大小
showPlace: false, //显示地方详情
//公寓地区id
areaMarkerIds: [],
//公寓地区内容
areaMarkerIdsObj: {},
//公寓数据
areaMarkerList: [],
customCalloutMarkerIds: [], //按区域/学校数据
customCalloutMarkerIdsObj: {},
//按学校数据
markersList: [],
//地区房价数据
priceList: [],
//个人/中介地区房源筛选列表
selectPriceList: [],
//地区房价ID
priceIdList: [],
//地区房价
placePriceList: {},
//用户所选地区
selectPlace: {},
//用户所选地区房源详情价格
selectPlacePrice: {},
//地区房源详情
placeInfoList: [],
//地区弹窗
placePopBox: false,
//公寓弹窗
apartmentPopBox: false,
//用户所选公寓
apartmentObj: {},
apartmentListId: '', //公寓列表id
allPlaceListBoxWidth: 0, //当前页面地区房源宽度
scrollTopNum: 0, //记录滚动条
personListId: '', //个人地区房价id
selectGroupIndex: null,
cloneInfo: '', //复制字段
pages: 1, //页数
count: 0, //品牌数量
types: { //筛选组件-出租
data: null,
value: ''
},
money: { //金额
rent_min: 0,
rent_max: ''
},
moreCondition: { //更多
show: false,
data: {
gender: "0",
leaseterm: "0",
publish: "0",
}
},
brands: { //品牌
list: [],
value: '',
obj: {}
},
roomlistings: { //楼型
list: [],
value: '',
obj: {}
},
roomtype: { //房型
list: [],
value: '',
obj: {}
},
//当前地区全部房源数据
placeAllList: [],
//语言包
langs: '',
//防抖
mapSelectCan: true,
//是否设置加载
mapCoordinateSet: true,
//是否可以加载更多数据
loadingMoreData: true,
//设置地图房源列表滚动条高度
mapSelectScrollTop: 0,
//是否初次加载地区
mapFirstLoading: true,
platform:'',//平台
mapMarkerTime:'',//计时器
},
get_config() {
var that = this;
if (app.globalData.config && app.globalData.config.lists) {
this.setData({
screen_data: app.globalData.screen_data,
})
this.getSelectList()
this.getHouseList()
this.getDtailsLangs()
} else {
setTimeout(function () {
that.get_config()
}, 10)
}
},
// 切换学校/区域
switchTab(e) {
this.setData({
tabValue: e.currentTarget.dataset.type,
markersList:[]
})
this.getHouseList()
},
showPlacePopBox() {
this.setData({
placePopBox: !this.data.placePopBox,
selectPriceList:[]
})
if (this.data.headerObjTab === 'apartment') return
if(this.data.placePopBox)this.getSelectPlaceList()
this.setListOperations()
},
//查看详情
publicJumps(e) {
let uniqid = e.currentTarget.dataset.uniqid
let url = e.currentTarget.dataset.url
if (url) {
wx.navigateTo({
url,
})
} else {
if (this.data.headerObjTab === 'apartment') {
wx.navigateTo({
url: `/pages/brandApartmentDetail/brandApartmentDetail?uniqid=${uniqid}`,
})
} else {
wx.navigateTo({
url: `/pages/show/show?uniqid=${uniqid}`,
})
}
}
},
//设置筛选属性
setListOperations() {
const listOperations = this.selectComponent('#listOperations');
listOperations.setSelectData(!this.data.placePopBox);
},
//监听滚动条
scrollChange() {
this._observer = wx.createIntersectionObserver(this, {
thresholds: [1, 1],
observeAll: true
})
this._observer
.relativeTo('#apartmentView')
.observe('.pos-id', (res) => {
let num = res.intersectionRatio == 1 && res.intersectionRatio % 1 == 0 ? res.dataset.num : null
// console.log(num)
if (!num && num != 0) return
if (this.data.headerObjTab === 'apartment') {
if (this.data.apartmentObj.id === this.data.areaMarkerList[num].id) return
} else if (this.data.headerObjTab === 'person') {
if (this.data.selectPlacePrice.id === this.data.priceList[num].id) return
}
this.setNowMarker(num)
})
},
//设置当前房间列表id
setNowMarker(num) {
if (this.data.headerObjTab !== 'apartment') {
let List = JSON.parse(JSON.stringify(this.data.priceList))
List.map(res => {
res.zIndex = 0
})
List[num].zIndex = 666
this.setData({
priceList: List,
selectPlacePrice: List[num],
longitude: this.data.priceList[num].longitude,
latitude: this.data.priceList[num].latitude,
})
} else if (this.data.headerObjTab === 'apartment') {
let obj = this.data.areaMarkerIdsObj[this.data.areaMarkerList[num].id]
this.data.areaMarkerList[this.data.apartmentObj.id - 1].zIndex = 0
this.data.areaMarkerList[num].zIndex = 666
this.setData({
areaMarkerList: this.data.areaMarkerList,
areaMarkerIdsObj: this.data.areaMarkerIdsObj,
apartmentObj: this.data.areaMarkerList[num],
longitude: this.data.areaMarkerList[num].longitude,
latitude: this.data.areaMarkerList[num].latitude,
})
}
},
callouttap(e) { //点击地图marker
let id = e.detail.markerId;
console.log(id)
let object = null;
if (this.data.headerObjTab === 'apartment') { //公寓
this.data.areaMarkerList.find((obj) => {
if (obj.id === id) {
object = obj
obj.zIndex = 666
}
})
this.setData({
areaMarkerList: this.data.areaMarkerList,
apartmentListId: 'Marker' + object.id,
apartmentObj: object,
})
} else if (this.data.showPlace && this.data.headerObjTab !== 'apartment') { //点击个人/中介地区房源
this.data.priceList.find((obj) => {
if (obj.id === id) object = obj
})
this.setData({
selectPlacePrice: object,
personListId: 'Marker' + object.id
})
this.scrollChange()
} else { //个人/中介地区
this.data.markersList.find((obj) => {
if (obj.id === id) object = obj
})
this.setData({
selectPlace: object,
// selectPlacePrice: this.data.selectPlacePrice.id ? this.data.selectPlacePrice : this.data.priceList[0],
showPlace: true,
mapScale: 15,
latitude: object.latitude,
longitude: object.longitude,
mapFirstLoading: true,
})
// console.log('object', object)
this.getPlaceList()
// this.getSelectPlaceList() //个人/中心房源搜索
this.setListOperations()
//获取房价元素宽度
this.getPlaceWidth()
}
},
cloneBtn() {
wx.setClipboardData({
data: this.data.cloneInfo.wechat,
success(res) {
wx.getClipboardData({
success(res) {
console.log(res.data) // data
}
})
}
})
},
//筛选选中标签
submitOperations(e) {
let {
type
} = e.detail
this.setData({
loadingMoreData: true,
mapSelectScrollTop: 0
})
if (type == "rent") this.submitMoney(e)
if (type == "types") this.submittype(e)
if (type == "moreCondition") this.myEventSelectSubmit(e)
if (type == 'brand') this.submitBrands(e)
if (type == 'house') this.submitRoomtype(e)
if (type == 'floor') this.submitRoomlistings(e)
},
//清空选项标签
clearSubmitOption() {
this.setData({
pages: 1
})
if (this.data.headerObjTab === 'apartment') { //公寓页面
this.getApartmentList()
} else {
if (this.data.showPlace) {
this.getSelectPlaceList()
} else {
this.getPlaceList()
}
}
},
// 选择房型
submitRoomtype(e) {
this.data.roomtype.value = e.detail.value || e.currentTarget.dataset.value;
this.setData({
roomtype: this.data.roomtype
})
this.clearSubmitOption()
},
// 选择楼型
submitRoomlistings(e) {
this.data.roomlistings.value = e.detail.value || e.currentTarget.dataset.value
this.setData({
roomlistings: this.data.roomlistings
})
this.clearSubmitOption()
},
// 选择品牌
submitBrands(e) {
this.data.brands.value = e.detail.value || e.currentTarget.dataset.value;
this.setData({
brands: this.data.brands
})
this.clearSubmitOption()
},
// 提交出租方式
submittype(e) {
this.data.types.value = e.detail.types || e.detail.data;
this.setData({
types: this.data.types,
selectGroupIndex: null
})
this.clearSubmitOption()
},
// 租金条件筛选提交
submitMoney(e) {
this.data.money = Object.assign({}, e.detail);
this.setData({
selectGroupIndex: null,
money: this.data.money
})
this.clearSubmitOption()
},
// 提交更多
myEventSelectSubmit(e) {
this.setData({
moreCondition: {
show: false,
data: e.detail
},
selectGroupIndex: null
})
this.clearSubmitOption()
},
//获取宽度
getPlaceWidth() {
let query = wx.createSelectorQuery();
let that = this
let type = '.pos-id'
query.select(type).boundingClientRect(function (res) {
if (!res) return
that.setData({
allPlaceListBoxWidth: res.width
})
}).exec()
},
//获取房源筛选
getSelectList() {
miucms.request(`${app.globalData.baseURL}/tenement/v2/api/map/region`).then(res => {
if (res.code === 200) {
let data = res.data
//获取品牌
data.brand.forEach(item => {
item.value = item.id;
this.data.brands.obj[item.id] = item.name;
})
this.data.brands.list = [{
value: '',
name: '全部品牌'
}, ...data.brand];
//获取房型
data.roomtype.forEach(item => {
item.value = item.id;
this.data.roomtype.obj[item.id] = item.name;
})
this.data.roomtype.list = [{
value: '',
name: '全部房型'
}, ...data.roomtype];
//获取楼型
data.roomlistings.forEach(item => {
item.value = item.id;
this.data.roomlistings.obj[item.id] = item.name;
})
this.data.roomlistings.list = [{
value: '',
name: '全部楼型'
}, ...data.roomlistings];
this.setData({
types: {
data: data.type
},
brands: this.data.brands,
roomtype: this.data.roomtype,
roomlistings: this.data.roomlistings
})
}
})
},
setValue(e) {
let {
key,
value
} = e.currentTarget.dataset
this.setData({
[key]: value,
mapScale: 11,
showPlace: false,
loadingMoreData: true,
listCount:null
})
this.clearScreen()
if (value === 'apartment') {
this.getApartmentList()
} else {
this.getHouseList()
}
this.getPlaceWidth()
},
//地图视野变化
mapViewChange(type, causedBy) {
if (type.type === 'begin' && type.causedBy === "gesture") {
this.setData({
selectPlacePrice: {}
})
}
if (type.type === 'end' && type.causedBy === "drag" && this.data.showPlace && this.data.headerObjTab !== 'apartment') { //地图移动获取数据
this.getPlaceList(`${type.detail.centerLocation.latitude},${type.detail.centerLocation.longitude}`)
} else if (type.type === 'end' && type.causedBy === "scale" && this.data.showPlace && this.data.headerObjTab !== 'apartment') {
if (type.detail.scale > 12) return
this.clearScreen()
this.backPerson()
this.setData({
mapCoordinateSet: true,
selectPlacePrice: {},
pages: 1,
})
}
},
//返回选择学校/区域页面
backPerson() {
this.clearScreen()
if (this.data.showPlace) {
this.setData({
loadingMoreData: true,
mapFirstLoading: true,
selectPlace: '',
showPlace: false,
mapScale: 11,
priceList: [],
priceIdList: null,
selectPlacePrice: null,
listCount:null
})
} else {
wx.navigateBack({
fail: function () {
wx.navigateTo({
url: '/pages/index/index',
})
}
})
}
},
//
//个人/中介加载更多
loadingMore() {
if (!this.data.loadingMoreData) return
this.setData({
pages: ++this.data.pages
})
this.getSelectPlaceList()
},
//解析数据列表坐标参数
getDataList(data, setLangs = false) {
let List = []
let arr = []
let obj = {}
let repeatArr={}
if (data.length) {
let dataObj = {
iconPath:this.data.platform==='windows'?"/mapFind/img/pcMarker.png":'/img/lucency.png',
width: this.data.platform==='windows'?20:0,
height: this.data.platform==='windows'?20:0,
joinCluster: this.data.headerObjTab !== 'apartment' && this.data.showPlace ? false : false,
customCallout: {
anchorY: 0,
anchorX: 0,
display: 'ALWAYS',
},
// callout: {
// content:'1',
// anchorY: 0,
// anchorX: 0,
// display: 'ALWAYS',
// },
// label:{
// content:'1',
// anchorY: 0,
// anchorX: 0,
// display: 'ALWAYS',
// }
}
data.map((res, index) => { //latitude longitude
if (this.data.showPlace || this.data.headerObjTab === 'apartment' ? true : res.count > 0) {
res.id = res.id ? res.id : index + 1
List.push({
latitude: res.center ? res.center.split(',')[1] : res.coordinate ? res.coordinate.split(',')[0] : res.point ? res.point.split(',')[1] : '',
longitude: res.center ? res.center.split(',')[0] : res.coordinate ? res.coordinate.split(',')[1] : res.point ? res.point.split(',')[0] : '',
imageurl: res.image,
brand: res.company,
...dataObj,
...res
})
if(repeatArr[res.point]){
let ojb={
id:res.id,
}
repeatArr[res.point].push(res.id)
}else{
repeatArr[res.point]=[]
repeatArr[res.point].push(res.id)
}
if(!setLangs||this.data.pages===1)arr.push(res.id)
if(!setLangs||this.data.pages===1)obj[res.id] = {
title: this.data.headerObjTab === 'person' || this.data.headerObjTab === 'intermediary' ? !this.data.showPlace ? res.name : 'HK$ ' + res.rent : 'HK$ ' + res.rentprice,
num: this.data.headerObjTab === 'person' || this.data.headerObjTab === 'intermediary' ? res.count : ''
}
}
})
List[0].zIndex = 666
}
if(setLangs&&this.data.pages>1){
arr=this.data.priceIdList
obj=this.data.placePriceList
}
if (this.data.headerObjTab !== 'apartment' && this.data.showPlace) List = this.handleDetailData(List, setLangs)
if(this.data.headerObjTab !== 'apartment' && this.data.showPlace)List=this.repeatSetList(List,repeatArr)
console.log(List)
return {
List,
arr,
obj
}
},
// windowsMarkerSet(data,type){
// this.data.mapMarkerTime=setInterval(()=>{
// let datas=JSON.parse(JSON.stringify(data))
// while(datas.length){
// let num=Math.floor(Math.random()*datas.length)
// let markerNum=null
// let key=null
// data.map((res,index)=>{
// if(res.id===datas[num].id){
// markerNum=index
// }
// })
// key=`${type}[${markerNum}]`
// this.setData({
// [key]:{
// ...datas[num],
// alpha:datas[num].alpha?0:1
// }
// })
// datas.splice(num,1)
// }
// // this.setData({
// // markersList:data
// // })
// },500)
// },
//坐标重叠处理
repeatSetList(data,idList){
let List=JSON.parse(JSON.stringify(data))
let idLists=idList
for(let item in idLists){
if(idLists[item].length>1){
for(let i=0;idLists[item].length>i;i++){
for(let j=0;j<List.length;j++){
if(List[j].id===idLists[item][i]){
List[j].customCallout.anchorX=Math.floor(Math.random()*20)
List[j].customCallout.anchorY=Math.floor(Math.random()*20)
continue;
}
}
}
}
}
return List
},
// 专门梳理v4出现的 语音包 及 不同房源值的处理
handleDetailData(data, setLangs) {
let langs = this.data.langs || {}
if (Object.keys(langs).length == 0) {
setTimeout(() => {
this.handleDetailData(data, setLangs)
}, 300)
} else {
if (!data) return
data.forEach(ele => {
// 这个是将 详情键 替换语言包里的值
let list = ['type', 'rentalduration', 'intermediary', "property", "elevator", "sunshinearea", "gender"]
if (Array.isArray(ele['floor'])) list.push('floor') // 判断 楼层是否需要 替换值, 因为在求房源里是多个值
let differentNames = { // 需要替换的 键名
"intermediary": "intermediary_text"
}
list.forEach(element => {
if (ele[element] == -1) {} else if (ele[element] == 0) ele[differentNames[element] ? differentNames[element] : element] = '不限' // 当 值为 [0] 时为不限
else ele[differentNames[element] ? differentNames[element] : element] = langs[element][ele[element]]
})
let tabArr = ["gptype", "type", "elevator", "sunshinearea", "gender"]
let tabList = []
tabArr.forEach(el => {
if (ele[el] && ele[el] != -1) tabList.push(ele[el])
})
ele['tabList'] = tabList
let location = langs.location // 遍历替换区域的值 所有房源
let pendingData = ele['location']
ele['location'] = `${location[Math.trunc(pendingData)]} > ${location[pendingData]}`
})
let lists = null
if (setLangs && this.data.pages > 1) {
lists = this.data.selectPriceList
lists = lists.concat(data)
} else {
lists = data
}
return lists
}
},
//清空选项
clearScreen() {
this.setData({
pages: 1, //页数
types: { //筛选组件-出租
data: this.data.types.data,
value: ''
},
money: { //金额
rent_min: 0,
rent_max: ''
},
moreCondition: { //更多
show: false,
data: {
gender: "0",
leaseterm: "0",
publish: "0",
}
},
brands: { //品牌
...this.data.brands,
value: ''
},
roomlistings: { //楼型
...this.data.roomlistings,
value: '',
},
roomtype: { //房型
...this.data.roomtype,
value: '',
},
})
},
//个人/中介地区列表
getHouseList() {
let data = {
isintermediary: this.data.headerObjTab === 'person' ? 0 : 1
}
let api = null
if (this.data.tabValue === 'school') {
api = miucms.request(`${app.globalData.baseURL}/tenement/v2/api/map/school`, data)
} else {
api = miucms.request(`${app.globalData.baseURL}/tenement/v2/api/map/district`, data)
}
api.then(res => {
if (res.code === 200) {
let data = res.data
let {
List,
arr,
obj
} = this.getDataList(data)
this.setData({
markersList: List,
customCalloutMarkerIds: arr,
customCalloutMarkerIdsObj: obj,
})
if (this.data.mapCoordinateSet) {
this.setData({
mapCoordinateSet: false,
latitude: '22.43183',
longitude:'114.13295',
})
}
// this.windowsMarkerSet(this.data.markersList,'markersList')
}
})
},
//个人/中介搜索列表
getSelectPlaceList() {
wx.showLoading({})
let data = Object.assign({}, this.data.moreCondition.data, this.data.money, {
token: this.data.selectPlace.token,
page: this.data.pages, //当前页数
types: this.data.types.value,
page: this.data.pages,
limit: 20,
})
console.log("this.data.selectPlace",this.data.selectPlace);
miucms.request(`${app.globalData.baseURL}/tenement/v2/api/map/lists`, data).then(res => {
if (res.code === 200) {
let data = res.data.data
let {
List,
arr,
obj
} = this.getDataList(data, true)
let placeData = JSON.parse(JSON.stringify(List)).slice(0, 50)
// let placeArr =JSON.parse(JSON.stringify(List)).slice(0, 30)
// console.log(List)
// console.log(arr)
// console.log(obj,Object.keys(obj).length)
if (data.length < 20) {
this.setData({
loadingMoreData: false,
})
}
this.setData({
priceList: placeData,
priceIdList: arr,
placePriceList: obj,
selectPriceList: List,
listCount: res.data.count+'',
latitude: placeData[0] ? placeData[0].latitude : '',
longitude: placeData[0] ? placeData[0].longitude : '',
})
wx.hideLoading()
}
})
},
//个人/中介房源列表
getPlaceList(location) {
if (!this.data.mapSelectCan) return
this.setData({
mapSelectCan: false
})
let data = Object.assign({}, this.data.moreCondition.data, this.data.money, {
token: this.data.selectPlace.token,
page: this.data.pages, //当前页数
types: this.data.types.value,
page: 1,
limit: 50,
location
})
miucms.request(`${app.globalData.baseURL}/tenement/v2/api/map/lists`, data).then(res => {
if (res.code === 200) {
let data = res.data.data
let {
List,
arr,
obj
} = this.getDataList(data)
// console.log(this.data.mapFirstLoading, ',', location)
if (this.data.mapFirstLoading) {
setTimeout((res) => {
this.setData({
latitude: List[0] ? List[0].latitude : '',
longitude: List[0] ? List[0].longitude : '',
})
},500)
}
// console.log(this.data.latitude, this.data.longitude, List[0])
this.setData({
mapFirstLoading: false,
priceList: List,
priceIdList: arr,
placePriceList: obj,
mapSelectCan: true
})
}else{
this.setData({
mapSelectCan:true
})
}
})
},
//获取公寓数据
getApartmentList() {
let data = Object.assign({}, this.data.money, {
page: this.data.pages, //当前页数
companyid: this.data.brands.value, //品牌
roomtype: this.data.roomtype.value, //房型
roomlistings: this.data.roomlistings.value,
limit: 100
})
miucms.request(`${app.globalData.baseURL}/tenement/v2/api/apartment`, data).then(res => {
if (res.code === 200) {
let data = res.data.data
let {
List,
arr,
obj
} = this.getDataList(data)
// obj=this.checkCoordinate(obj,List)
this.setData({
cloneInfo: res.data.contact,
count: res.data.count,
areaMarkerList: List,
areaMarkerIds: arr,
areaMarkerIdsObj: obj,
latitude: List[0] ? List[0].latitude : '',
longitude: List[0] ? List[0].longitude : '',
apartmentObj: List[0],
})
this.scrollChange()
}
})
},
//获取后台语言包
getDtailsLangs() {
miucms.request(`${app.globalData.baseURL}/tenement/v2/api/details/langs`).then(res => {
if (res.code != 200) return
let data = res.data
this.setData({
langs: data
})
})
},
onReady() {
let that = this
// wx.getSystemInfo({
// success: (res) => {
// this.setData({
// windowHeight: res.windowHeight
// })
// }
// })
setTimeout(function () {
that.get_config()
}, 200)
},
onLoad(options) {
this.mapCtx = wx.createMapContext('map')
this.mapCtx.on('markerClusterClick', res => {
console.log('markerClusterClick', res)
})
wx.getSystemInfo({
success: (res) => {
// windows | mac为pc端
// android | ios为手机端
this.setData({
platform:res.platform
})
console.log(res.platform)
}
});
var that = this;
// this.getMapContxt()
// this.get_config()
},
onShow() {},
onHide() {},
onUnload() {
this._observer&&this._observer.disconnect()
},
onReachBottom() {
},
onShareAppMessage() {
},
onShareTimeline() {
},
})

View File

@ -0,0 +1,7 @@
{
"enablePullDownRefresh": false,
"usingComponents": {
"list-operations": "/template/listOperations/listOperations",
"common-list": "/template/commonList/commonList"
}
}

View File

@ -0,0 +1,202 @@
<import src="/pages/common/common.wxml" />
<view class="container" style="position:fixed;top:0;left:0;">
<view class="top-tool-box">
<view class="header-box" style="height: {{ screen_data['totalTopHeight'] }}px;">
<view class="top-tab-box" style="padding-top: {{ screen_data['statusBarHeight'] }}px;height: {{ screen_data['titleBarHeight'] }}px;box-sizing: content-box;">
<view class="back flexcenter">
<image class="back-icon" mode="heightFix" src="/img/back.png" bindtap="backPerson"></image>
</view>
<view class="header-tab top-tab-box" style="margin-top:14rpx;">
<view class="header-tab-item {{ index == headerObjTab ? 'pitch' : '' }}" wx:for="{{ headerObj }}" wx:key="index" bindtap="setValue" data-key="headerObjTab" data-value="{{ index }}">{{ item }}</view>
</view>
</view>
</view>
<view style="position: fixed;top:0;left:0;z-index: 666;width:100vw;background:#fff;" wx:if="{{(headerObjTab==='apartment'&&placePopBox)||placePopBox}}">
<view class="header-box" style="height: {{ screen_data['totalTopHeight'] }}px;">
<view class="top-tab-box" style="padding-top: {{ screen_data['statusBarHeight'] }}px;height: {{ screen_data['titleBarHeight'] }}px;box-sizing: content-box;position: relative;">
<view class="back flexcenter" style="position: absolute;">
<image class="back-icon" mode="heightFix" style="transform:rotate(270deg);" src="/img/back.png" bindtap="showPlacePopBox"></image>
</view>
<view class="place-pop-box-title">
{{headerObjTab==='apartment'?'品牌公寓':selectPlace.name}}
</view>
</view>
</view>
</view>
<view class="tab-box" style="display: flex;top:{{screen_data['totalTopHeight']+100 }}rpx" wx:if="{{headerObjTab!=='apartment'&&!showPlace}}">
<view class="tab-item flex1 flexcenter {{ tabValue == 'area' ? 'pitch' : '' }}" bindtap="switchTab" data-type='area'>
按区域
</view>
<view class="tab-item flex1 flexcenter {{ tabValue == 'school' ? 'pitch' : '' }}" bindtap="switchTab" data-type='school'>
按学校
</view>
</view>
<view wx:elif="{{ (headerObjTab==='person'&&showPlace)||headerObjTab==='apartment'||placePopBox||headerObjTab==='intermediary' }}" style="top:{{screen_data['totalTopHeight']+60}}rpx" class="tool-btn-box dis-f">
<list-operations id='listOperations' style="width:100%;" money="{{ money }}" property="{{ property }}" types="{{ types }}" mapPlaceBox="{{placePopBox}}" operationstype="{{headerObjTab==='person'?'placeSelectList':headerObjTab==='intermediary'?'placeSelectList':'student'}}" screen_data="{{ screen_data }}" brands="{{ brands }}" roomtype="{{ roomtype }}" roomlistings="{{ roomlistings }}" bindsubmit="submitOperations"></list-operations>
</view>
<!-- 房源数据列表 -->
<view wx:if="{{headerObjTab==='apartment'||placePopBox}}" class="tool-btn-box pos-r dis-f" style="z-index:999;">
<!-- <view style="position:fixed;left:0;top:{{screen_data['titleBarHeight']+screen_data['statusBarHeight']}}px;width:100vw;z-index:230;background:#fff;">
<list-operations style="width:100%;" operationstype="student" money="{{ money }}" brands="{{ brands }}" screen_data="{{ screen_data }}" roomtype="{{ roomtype }}" roomlistings="{{ roomlistings }}" bindsubmit="submitOperations"></list-operations>
</view> -->
<scroll-view scroll-y class="place-pop-box" wx:if="{{placePopBox}}" style="height:{{windowHeight-40-screen_data['totalTopHeight']}}px" bindscrolltolower='loadingMore' scroll-top="{{mapSelectScrollTop}}">
<view style="{{headerObjTab==='apartment'?'padding:0 30rpx':''}}">
<view class="place-information dis-f al-item">
<view style="font-weight: 650;margin:0 10rpx 0 10rpx">
{{headerObjTab==='apartment'?areaMarkerList.length:listCount}}
</view>
套房源
</view>
<view wx:if="{{headerObjTab!=='apartment'}}">
<common-list wx:for="{{ selectPriceList }}" wx:key="index" item="{{ item }}"></common-list>
</view>
<view class="inEnd flexcenter" style="padding-bottom:20rpx;" wx:if="{{headerObjTab!=='apartment'}}">到底了</view>
<template is='apartment-item' wx:if="{{headerObjTab==='apartment'&&areaMarkerList.length>0}}" wx:for="{{areaMarkerList}}" data="{{item}}" wx:key="index" data-uniqid='{{item.uniqid}}'>
</template>
<template is="empty-icon" wx:if="{{(headerObjTab==='apartment'&&areaMarkerList.length===0)||(headerObjTab!=='apartment'&&priceList.length===0)}}">
</template>
<view wx:if="{{headerObjTab==='apartment'&&areaMarkerList.length>0}}">
<view class="dis-f jus-x al-item btm-tps-text" wx:if="{{headerObjTab==='apartment'}}">
有疑问? 来找
<image src="../../../img/smiling-face.png" class="btm-tps-img" mode="" />
{{cloneInfo.nickname}}
</view>
<view class="dis-f jus-x al-item" wx:if="{{headerObjTab==='apartment'}}">
<view class="btm-tps-btn" bindtap="cloneBtn">
复制微信号
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
<view class="map">
<map id="map" enable-poi='true' longitude="{{longitude}}" latitude="{{latitude}}" markers="{{headerObjTab==='apartment'?areaMarkerList:showPlace?priceList:markersList}}" scale="{{mapScale}}" bindregionchange="mapViewChange" style="width: 100%; height: 100%;" bindcallouttap="callouttap" enable-scroll="{{mapEnableScroll}}" bindmarkertap="callouttap" >
<cover-view slot="callout" style="position: relative;">
<block wx:for="{{headerObjTab==='apartment'?areaMarkerIds:showPlace?priceIdList:customCalloutMarkerIds}}" wx:key="index">
<cover-view class="customCallout {{headerObjTab==='apartment'||showPlace?'price-box':tabValue==='school'?'':'circles'}}" marker-id="{{item}}" wx:if="{{headerObjTab==='apartment'?true:showPlace?true:customCalloutMarkerIdsObj[item].num>0}}">
<cover-view wx:if="{{!showPlace&&headerObjTab!=='apartment'}}" class="{{(showPlace&&selectPlacePrice.id===item)||headerObjTab==='apartment'&&apartmentObj.id===item?'check-place-box':'place-price-box'}}">
{{headerObjTab==='apartment'?areaMarkerIdsObj[item].title:showPlace?placePriceList[item].title :customCalloutMarkerIdsObj[item].title }}
</cover-view>
<cover-view wx:if="{{showPlace||headerObjTab==='apartment'}}" class="{{(showPlace&&selectPlacePrice.id===item)||headerObjTab==='apartment'&&apartmentObj.id===item?'check-place-box':'place-price-box'}} {{(headerObjTab==='apartment'||showPlace)&&apartmentObj.id!=item?'apartment-text':''}}">
{{headerObjTab==='apartment'?areaMarkerIdsObj[item].title:showPlace?placePriceList[item].title :customCalloutMarkerIdsObj[item].title }}
</cover-view>
<cover-image src="../../img/downIcon.png" class="check-place-box-triangle" wx:if="{{headerObjTab==='apartment'&&apartmentObj.id===item?true:showPlace&&selectPlacePrice.id===item?true :false}}" mode="" />
<!-- <cover-view class="{{showPlace&&selectPlacePrice.id===item||apartmentObj.id===item?'check-place-box-triangle':''}}">
</cover-view> -->
<cover-view class="{{tabValue==='school'?'name':''}}" wx:if="{{headerObjTab==='apartment'?false:true}}" hidden='{{showPlace?true:false}}'>{{ customCalloutMarkerIdsObj[item].num }}套</cover-view>
</cover-view>
</block>
</cover-view>
</map>
</view>
<!-- 地图轮播模块 -->
<view class="place-info-box">
<scroll-view scroll-x style="height:380rpx" enhanced="true" id='apartmentView' enable-flex='true' scroll-into-view="{{personListId}}" scroll-with-animation scroll-left="{{mapSelectScrollTop}}" class="place-list dis-f al-item" wx:if="{{headerObjTab!=='apartment'&&showPlace&&selectPlacePrice.id}}">
<view wx:for="{{priceList}}" wx:key="index" class="pos-id" id="{{'Marker'+item.id}}" data-num='{{index}}' data-uniqid='{{item.uniqid}}' bindtap="publicJumps">
<view class="place-list-box">
<image wx:if="{{item.verified}}" src="../../img/certified-listing.png" mode="aspectFit" class="place-list-confirm-img" alt="" />
<view class="dis-f al-item">
<view class="title-tab">
{{item.gptype}}
</view>
<view class="title">
{{item.subject}}
</view>
</view>
<view class="dis-f place-list-info-box">
<view class="dis-f place-info">
<view class="tab-text">
{{item.type}} · {{item.acreage}}平方呎 · {{item.gender}} · {{langs.leaseterm[item.leaseterm]}}
<view class="dis-f" style="margin-top:18rpx;">
<view class="currency">
HK$
</view>
<view class="price">
{{item.rent}}
</view>
<view class="interval-time">
/{{item.rentalperiod}}
</view>
</view>
</view>
<view class="dis-f al-item" style="margin-top:16rpx;">
<image src="{{ item.avatar }}" alt="" class="release-info-img" />
<view class="release-info-text">
{{item.author}}
</view>
<view class="release-info-btn dis-f jus-x al-item">
{{langs.intermediary[item.intermediary]}}
</view>
<image wx:if="{{item.isintermediary}}" src="/img/certifying-agent.png" class="confirm-intermediary-img" mode="aspectFill" />
</view>
</view>
<view class="place-img" style="position: relative;">
<image src="{{item.imageurl}}" wx:if="{{item.isvideo||item.ispic}}" class="place-img" mode="center" />
<view wx:if="{{item.isvideo}}" class="video-box dis-f jus-x al-item">
<image class="video-img" src="/img/videoplay.png" mode=""></image>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<!-- bindscroll='scrollChange' wx:elif="{{headerObjTab==='apartment'}}" -->
<scroll-view scroll-x="true" style="height:350rpx" enhanced="true" id='apartmentView' paging-enabled="true" hidden="{{headerObjTab!=='apartment'}}" enable-flex='true' class="place-list dis-f al-item" scroll-left="{{mapSelectScrollTop}}" scroll-into-view="{{apartmentListId}}" scroll-with-animation>
<view wx:for="{{areaMarkerList}}" wx:key="index" class="pos-id" id="{{'Marker'+item.id}}" data-num='{{index}}' data-uniqid='{{item.uniqid}}' bindtap="publicJumps">
<view class="place-list-box dis-f al-item" style="padding:0;background:#000;" data-id="{{item.id}}">
<view class="apartment-img-box">
<view class="apartment-img">
<image src="{{item.image}}" class="img" mode="aspectFill" />
</view>
<view style="width:260rpx;height:186rpx;">
</view>
<view class="apartment-title-text">
{{item.brand}}
</view>
</view>
<view class="apartment-info-box">
<view class="title">
{{item.title}}
</view>
<view class="introduce">
{{item.propaganda}}
</view>
<view class="house-type">
共{{item.roomnum}}个房型
</view>
<view class="dis-f" style="margin-top:20rpx;">
<view class="currency">
HK$
</view>
<view class="price">
{{item.rentprice}}
</view>
<view class="interval-time">
/月起
</view>
</view>
</view>
</view>
</view>
<!-- -->
</scroll-view>
<!-- 底部按钮 -->
<view class="info-box" bindtap="showPlacePopBox" wx:if="{{headerObjTab==='apartment'||showPlace}}">
<view class="dis-f jus-x al-item">
<image src="../../img/placeLogo.svg" class="img" mode="aspectFit" />
</view>
<view class="title" hidden="{{headerObjTab!=='apartment'}}">
共 {{count}} 个品牌公寓
</view>
<view class="title" hidden="{{headerObjTab==='apartment'}}">
{{selectPlace.name}} {{listCount||selectPlace.count}} 套房源
</view>
</view>
</view>
<!-- 弹窗 -->
</view>

View File

@ -0,0 +1,605 @@
/* pages/placeMap/placeMap.wxss */
@import "/pages/common/common.wxss";
page {
height: 100%;
}
.pos-id{
position: relative;
}
.pos-r {
position: relative;
}
.map-box {
display: flex;
flex: 1;
width: 100vw;
position: relative;
}
.top-tool-box{
position: absolute;
z-index: 333;
top: 0;
left: 0;
width: 100vw;
}
.top-tab-box {
display: flex;
align-items: center;
margin-bottom: 20rpx;
}
.customCallout {
box-sizing: border-box;
/* background-color: #fff; */
border: 1px solid #ccc;
border-radius: 30px;
/* width: 232.5rpx; */
width: max-content;
height: 72rpx;
color: #ffffff;
display: inline-flex;
justify-content: space-between;
align-items: center;
padding: 0 24rpx;
font-size: 22rpx;
border-radius: 24rpx;
position: relative;
background-color: rgba(51, 51, 51, 1);
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.349019607843137);
}
.circles {
width: 130rpx;
height: 130rpx;
border-radius: 65rpx;
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx;
font-size: 22rpx;
line-height: 130rpx;
flex-wrap: wrap;
}
.name {
margin-left: 25rpx;
}
.header-box {
background-color: #ffffff;
}
.header-box .back {
padding: 0 32rpx;
height: 100%;
}
.header-box .back .back-icon {
width: 12px;
height: 18px;
}
.header-box .header-tab-item {
padding: 0 24rpx;
font-size: 30rpx;
color: #555555;
}
.header-box .header-tab-item.pitch {
color: #000000;
font-weight: 650;
position: relative;
}
.header-box .header-tab-item.pitch::after {
position: absolute;
bottom: -6rpx;
left: 50%;
transform: translateX(-50%) translateY(100%);
background-color: rgba(253, 218, 85, 1);
width: 58.5rpx;
height: 6rpx;
border-radius: 58.5rpx;
content: "";
}
.map {
width: 100vw;
height: 100vh;
/* flex: 1;
max-height:90vh; */
}
.tab-box {
z-index: 1000;
position: absolute;
top: 21rpx;
left: 50%;
transform: translateX(-50%);
width: 310rpx;
height: 56rpx;
border-radius: 157.5rpx;
background-color: rgba(246, 246, 246, 1);
font-size: 24rpx;
color: #555555;
box-shadow: 0 0 12rpx rgba(0, 0, 0, 0.407843137254902);
justify-content: space-between;
}
.tab-box .tab-item {
height: 100%;
display: flex;
align-items: center;
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 26rpx;
color: #555555;
padding: 0 10rpx;
width: 176rpx;
justify-content: center;
}
.tab-box .tab-item.pitch {
background-color: rgba(242, 82, 101, 1);
border-radius: 157.5rpx;
color: #ffffff;
font-weight: 650;
}
.dis-f {
display: flex;
}
.jus-x {
justify-content: center;
}
.al-item {
align-items: center;
}
.tool-btn-box {
align-items: center;
justify-content: space-around;
/* position: absolute; */
/* top: 0; */
/* left: 0; */
width: 100%;
display: flex;
align-items: center;
/* z-index: 666; */
background-color: #fff;
flex-wrap: wrap;
border-bottom:1rpx solid #e9e9ea;
}
.tool-btn-box .line-box {
width: 4rpx;
height: 34rpx;
background: #f2f2f2;
}
.btn-box {
align-items: center;
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 32rpx;
color: #7F7F7F;
height: 110rpx;
width: 33%;
justify-content: center;
}
.down-btn-box {
width: 32rpx;
height: 32rpx;
border-radius: 16rpx;
margin-left: 20rpx;
background: rgba(229, 232, 240, 1);
justify-content: center;
align-items: center;
}
.select-true-btn {
background: #000;
}
.down-btn-box .img {
width: 16rpx;
height: 16rpx;
}
.price-box {
background: transparent;
min-width: 160rpx;
font-size: 22rpx;
color: #7F7F7F;
text-align: center;
display: flex;
justify-content: center;
font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
font-weight: 400;
padding:0 10rpx;
border:0px solid;
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0);
}
.place-info-box {
position: fixed;
bottom: 0;
z-index:200;
}
.place-info-box .info-box {
width: 100vw;
/* height: 200rpx; */
padding: 20rpx 0 50rpx 0;
background: inherit;
background-color: rgba(255, 255, 255, 1);
border: none;
border-bottom: 0px;
border-radius: 80rpx;
border-bottom-right-radius: 0px;
border-bottom-left-radius: 0px;
-moz-box-shadow: 0px 0px 16rpx rgba(0, 0, 0, 0.156862745098039);
-webkit-box-shadow: 0px 0px 16rpx rgba(0, 0, 0, 0.156862745098039);
box-shadow: 0px 0px 16rpx rgba(0, 0, 0, 0.156862745098039);
}
.place-info-box .info-box .img {
width: 32rpx;
height: 32rpx;
}
.place-info-box .info-box .title {
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 26rpx;
color: #555555;
text-align: center;
margin-top: 20rpx;
}
.place-price-box {
width: 140rpx;
border-radius: 50rpx;
padding:15rpx 0;
font-size: 22rpx;
font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
font-weight: 400;
font-style: normal;
position: relative;
z-index:200;
text-align: center;
border:0px solid transparent;
/* line-height: 50rpx; */
}
.apartment-text{
background: #fff;
border:1px solid #ccc;
}
.check-place-box {
width: 140rpx;
border-radius: 50rpx;
padding:15rpx 10rpx;
background: #000;
font-size: 22rpx;
color: #FDDF6D;
font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
font-weight: 400;
font-style: normal;
position:absolute;
z-index:260;
border:1px solid transparent;
/* line-height: 50rpx; */
}
.dis-n{
display: none;
}
.check-place-box-triangle{
width: 20rpx;
height:20rpx;
object-fit: contain;
/* border-style: solid; */
/* border-color: #000 transparent transparent transparent; */
/* border-width: 10rpx; */
position: absolute;
bottom:-5rpx;
}
.place-list {
overflow-x: scroll;
white-space: nowrap;
width:100vw;
transition: all 0.1s linear;
}
.place-list-box {
width: 690rpx;
border-radius: 20rpx;
padding:30rpx 20rpx;
background: #fff;
margin-left: 20rpx;
box-shadow: 0rpx 0rpx 20rpx rgba(0, 0, 0, 0.5);
position: relative;
}
.place-list-box .apartment-info-box{
border-radius:0 20rpx 20rpx 20rpx;
padding:25rpx 20rpx;
background:#fff;
height:246rpx;
width: 100%;
position: absolute;
z-index:555;
top:0;
left:254rpx;
width: 442rpx;
}
.place-list-box .apartment-info-box .title{
font-family: 'PingFangSC-Semibold', 'PingFang SC Semibold', 'PingFang SC', sans-serif;
font-weight: 650;
font-style: normal;
font-size: 32rpx;
color: #000000;
margin-left:0;
}
.place-list-box .apartment-info-box .introduce{
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 22rpx;
margin-top:20rpx;
width: 400rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.place-list-box .apartment-info-box .house-type{
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
color: #AAAAAA;
font-size:22rpx;
margin-top:20rpx;
}
.place-list-box .apartment-img-box{
width: 270rpx;
border-radius: 20rpx 20rpx 0 20rpx;
background:#000;
}
.place-list-box .apartment-img-box .apartment-img{
width: 270rpx;
height: 187rpx;
border-radius:20rpx 20rpx 0 20rpx;
background:#fff;
position: absolute;
top:0;
left:0;
z-index:666;
}
.place-list-box .apartment-img-box .apartment-img .img{
width:254rpx;
height:190rpx;
border-radius:20rpx 20rpx 0 20rpx;
background:#ccc;
}
.place-list-box .apartment-img-box .apartment-title-text{
height:60rpx;
width: 240rpx;
text-align: center;
line-height:60rpx;
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 24rpx;
color: #FDDA55;
}
.place-list-box .place-list-confirm-img{
width:140rpx;
height:140rpx;
position: absolute;
top:-8rpx;
right:-10rpx;
z-index: 666;
object-fit: contain;
}
.place-list-box .title {
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 30rpx;
color: #000000;
width: 400rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
margin-left:15rpx;
}
.place-list-box .title-tab {
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 26rpx;
color: #FDDF6D;
background: #000;
border-radius: 8rpx;
text-align: center;
padding: 4rpx 15rpx;
}
.place-list-box .place-list-info-box{
justify-content: space-between;
align-items: center;
margin-top: 30rpx;
}
.place-list-box .place-img{
width: 140rpx;
height: 163rpx;
border-radius:14rpx;
object-fit: contain;
/* margin-top:20rpx; */
/* background:#555555; */
}
.place-list-box .video-box{
width: 140rpx;
height: 163rpx;
position: absolute;
top:0;
left:0;
z-index:333;
background-color: rgba(51, 51, 51, 0.733333333333333);
border-radius:20rpx;
}
.place-list-box .video-img{
width:60rpx;
height:60rpx;
}
.place-list-box .place-info{
flex-direction: column;
justify-content: space-between;
height:163rpx;
}
.place-list-box .tab-text{
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 24rpx;
color: #555555;
}
.place-list-box .currency{
font-family: 'Arial-Black', 'Arial Black', sans-serif;
font-weight: 900;
color: #000000;
font-size:24rpx;
line-height:46rpx;
}
.place-list-box .price{
font-family: 'Arial-Black', 'Arial Black', sans-serif;
font-weight: 900;
font-size: 32rpx;
color: #F95D5D;
line-height:38rpx;
margin-left:10rpx;
}
.place-list-box .interval-time{
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 21rpx;
color: #555555;
line-height:43rpx;
margin-left:10rpx;
}
.place-list-box .place-info .release-info-img{
width:30rpx;
height:30rpx;
border-radius:15rpx;
}
.place-list-box .place-info .release-info-text{
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 26rpx;
color: #555555;
margin-left:10rpx;
}
.place-list-box .place-info .release-info-btn{
padding:0 10rpx;
height: 40rpx;
background: inherit;
background-color: rgba(242, 242, 242, 0);
box-sizing: border-box;
border-width: 1rpx;
border-style: solid;
border-color: rgba(215, 215, 215, 1);
border-radius: 23rpx;
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 22rpx;
color: #555555;
margin-left:20rpx;
line-height: 40rpx;
}
.place-list-box .place-info .confirm-intermediary-img{
width:120rpx;
height:30rpx;
margin-left:30rpx;
}
.place-pop-box{
width:100vw;
height:100vh;
z-index: 220;
overflow-y: scroll;
background:#f6f6f6;
}
.place-pop-box-title{
font-family: 'PingFangSC-Semibold', 'PingFang SC Semibold', 'PingFang SC', sans-serif;
font-weight: 650;
font-style: normal;
font-size: 35rpx;
margin:0 auto;
}
.place-pop-box .place-information{
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
color: #555555;
font-style: normal;
font-size: 24rpx;
height:86rpx;
padding:0 30rpx;
}
.btm-tps-text{
font-family: 'PingFangSC-Regular', 'PingFang SC', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 23rpx;
color: #7F7F7F;
margin-top:60rpx;
}
.btm-tps-img{
width:28rpx;
height:28rpx;
margin:0 10rpx;
}
.btm-tps-btn{
width: 280rpx;
height: 67rpx;
background: inherit;
background-color: rgba(217, 236, 255, 1);
border: none;
border-radius: 82rpx;
-moz-box-shadow: 0px 0px 16rpx rgba(98, 177, 255, 0.0784313725490196);
-webkit-box-shadow: 0px 0px 16rpx rgba(98, 177, 255, 0.0784313725490196);
box-shadow: 0px 0px 16rpx rgba(98, 177, 255, 0.0784313725490196);
font-family: 'PingFangSC-Semibold', 'PingFang SC Semibold', 'PingFang SC', sans-serif;
font-weight: 650;
font-style: normal;
font-size: 28rpx;
color: #62B1FF;
text-align: center;
line-height:67rpx;
margin:30rpx 0 60rpx 0;
}
.inEnd {
color: #aaaaaa;
margin: 0 auto;
font-size: 21rpx;
}

View File

@ -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.

View File

@ -0,0 +1,94 @@
# EventEmitter3
[![Version npm](https://img.shields.io/npm/v/eventemitter3.svg?style=flat-square)](https://www.npmjs.com/package/eventemitter3)[![Build Status](https://img.shields.io/travis/primus/eventemitter3/master.svg?style=flat-square)](https://travis-ci.org/primus/eventemitter3)[![Dependencies](https://img.shields.io/david/primus/eventemitter3.svg?style=flat-square)](https://david-dm.org/primus/eventemitter3)[![Coverage Status](https://img.shields.io/coveralls/primus/eventemitter3/master.svg?style=flat-square)](https://coveralls.io/r/primus/eventemitter3?branch=master)[![IRC channel](https://img.shields.io/badge/IRC-irc.freenode.net%23primus-00a8ff.svg?style=flat-square)](https://webchat.freenode.net/?channels=primus)
[![Sauce Test Status](https://saucelabs.com/browser-matrix/eventemitter3.svg)](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)

View File

@ -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<EventEmitter.EventNames<EventTypes>>;
/**
* Return the listeners registered for a given event.
*/
listeners<T extends EventEmitter.EventNames<EventTypes>>(
event: T
): Array<EventEmitter.EventListener<EventTypes, T>>;
/**
* Return the number of listeners listening to a given event.
*/
listenerCount(event: EventEmitter.EventNames<EventTypes>): number;
/**
* Calls each of the listeners registered for a given event.
*/
emit<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
...args: EventEmitter.EventArgs<EventTypes, T>
): boolean;
/**
* Add a listener for a given event.
*/
on<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn: EventEmitter.EventListener<EventTypes, T>,
context?: Context
): this;
addListener<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn: EventEmitter.EventListener<EventTypes, T>,
context?: Context
): this;
/**
* Add a one-time listener for a given event.
*/
once<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn: EventEmitter.EventListener<EventTypes, T>,
context?: Context
): this;
/**
* Remove the listeners of a given event.
*/
removeListener<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn?: EventEmitter.EventListener<EventTypes, T>,
context?: Context,
once?: boolean
): this;
off<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn?: EventEmitter.EventListener<EventTypes, T>,
context?: Context,
once?: boolean
): this;
/**
* Remove all listeners, or those of the specified event.
*/
removeAllListeners(event?: EventEmitter.EventNames<EventTypes>): this;
}
declare namespace EventEmitter {
export interface ListenerFn<Args extends any[] = any[]> {
(...args: Args): void;
}
export interface EventEmitterStatic {
new <
EventTypes extends ValidEventTypes = string | symbol,
Context = any
>(): EventEmitter<EventTypes, Context>;
}
/**
* `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 ValidEventTypes> = T extends string | symbol
? T
: keyof T;
export type ArgumentMap<T extends object> = {
[K in keyof T]: T[K] extends (...args: any[]) => void
? Parameters<T[K]>
: T[K] extends any[]
? T[K]
: any[];
};
export type EventListener<
T extends ValidEventTypes,
K extends EventNames<T>
> = T extends string | symbol
? (...args: any[]) => void
: (
...args: ArgumentMap<Exclude<T, string | symbol>>[Extract<K, keyof T>]
) => void;
export type EventArgs<
T extends ValidEventTypes,
K extends EventNames<T>
> = Parameters<EventListener<T, K>>;
export const EventEmitter: EventEmitterStatic;
}
export = EventEmitter;

View File

@ -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;
}

View File

@ -0,0 +1,59 @@
{
"name": "eventemitter3",
"version": "4.0.7",
"description": "EventEmitter3 focuses on performance while maintaining a Node.js AND browser compatible interface.",
"main": "index.js",
"typings": "index.d.ts",
"scripts": {
"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",
"benchmark": "find benchmarks/run -name '*.js' -exec benchmarks/start.sh {} \\;",
"test": "nyc --reporter=html --reporter=text mocha test/test.js",
"prepublishOnly": "npm run browserify && npm run minify",
"test-browser": "node test/browser.js"
},
"files": [
"index.js",
"index.d.ts",
"umd"
],
"repository": {
"type": "git",
"url": "git://github.com/primus/eventemitter3.git"
},
"keywords": [
"EventEmitter",
"EventEmitter2",
"EventEmitter3",
"Events",
"addEventListener",
"addListener",
"emit",
"emits",
"emitter",
"event",
"once",
"pub/sub",
"publish",
"reactor",
"subscribe"
],
"author": "Arnout Kazemier",
"license": "MIT",
"bugs": {
"url": "https://github.com/primus/eventemitter3/issues"
},
"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"
},
"__npminstall_done": true,
"_from": "eventemitter3@4.0.7",
"_resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz"
}

View File

@ -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<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
'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;
}
},{}]},{},[1])(1)
});

View File

@ -0,0 +1 @@
!function(e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).EventEmitter3=e()}(function(){return function i(s,f,c){function u(t,e){if(!f[t]){if(!s[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(a)return a(t,!0);var r=new Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}var o=f[t]={exports:{}};s[t][0].call(o.exports,function(e){return u(s[t][1][e]||e)},o,o.exports,i,s,f,c)}return f[t].exports}for(var a="function"==typeof require&&require,e=0;e<c.length;e++)u(c[e]);return u}({1:[function(e,t,n){"use strict";var r=Object.prototype.hasOwnProperty,v="~";function o(){}function f(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function i(e,t,n,r,o){if("function"!=typeof n)throw new TypeError("The listener must be a function");var i=new f(n,r||e,o),s=v?v+t:t;return e._events[s]?e._events[s].fn?e._events[s]=[e._events[s],i]:e._events[s].push(i):(e._events[s]=i,e._eventsCount++),e}function u(e,t){0==--e._eventsCount?e._events=new o:delete e._events[t]}function s(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(v=!1)),s.prototype.eventNames=function(){var e,t,n=[];if(0===this._eventsCount)return n;for(t in e=this._events)r.call(e,t)&&n.push(v?t.slice(1):t);return Object.getOwnPropertySymbols?n.concat(Object.getOwnPropertySymbols(e)):n},s.prototype.listeners=function(e){var t=v?v+e:e,n=this._events[t];if(!n)return[];if(n.fn)return[n.fn];for(var r=0,o=n.length,i=new Array(o);r<o;r++)i[r]=n[r].fn;return i},s.prototype.listenerCount=function(e){var t=v?v+e:e,n=this._events[t];return n?n.fn?1:n.length:0},s.prototype.emit=function(e,t,n,r,o,i){var s=v?v+e:e;if(!this._events[s])return!1;var f,c=this._events[s],u=arguments.length;if(c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),u){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,t),!0;case 3:return c.fn.call(c.context,t,n),!0;case 4:return c.fn.call(c.context,t,n,r),!0;case 5:return c.fn.call(c.context,t,n,r,o),!0;case 6:return c.fn.call(c.context,t,n,r,o,i),!0}for(p=1,f=new Array(u-1);p<u;p++)f[p-1]=arguments[p];c.fn.apply(c.context,f)}else for(var a,l=c.length,p=0;p<l;p++)switch(c[p].once&&this.removeListener(e,c[p].fn,void 0,!0),u){case 1:c[p].fn.call(c[p].context);break;case 2:c[p].fn.call(c[p].context,t);break;case 3:c[p].fn.call(c[p].context,t,n);break;case 4:c[p].fn.call(c[p].context,t,n,r);break;default:if(!f)for(a=1,f=new Array(u-1);a<u;a++)f[a-1]=arguments[a];c[p].fn.apply(c[p].context,f)}return!0},s.prototype.on=function(e,t,n){return i(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return i(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,n,r){var o=v?v+e:e;if(!this._events[o])return this;if(!t)return u(this,o),this;var i=this._events[o];if(i.fn)i.fn!==t||r&&!i.once||n&&i.context!==n||u(this,o);else{for(var s=0,f=[],c=i.length;s<c;s++)(i[s].fn!==t||r&&!i[s].once||n&&i[s].context!==n)&&f.push(i[s]);f.length?this._events[o]=1===f.length?f[0]:f:u(this,o)}return this},s.prototype.removeAllListeners=function(e){var t;return e?(t=v?v+e:e,this._events[t]&&u(this,t)):(this._events=new o,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=v,s.EventEmitter=s,void 0!==t&&(t.exports=s)},{}]},{},[1])(1)});

File diff suppressed because one or more lines are too long

21
node_modules/.store/node_modules/eventemitter3/LICENSE generated vendored Normal file
View File

@ -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.

View File

@ -0,0 +1,94 @@
# EventEmitter3
[![Version npm](https://img.shields.io/npm/v/eventemitter3.svg?style=flat-square)](https://www.npmjs.com/package/eventemitter3)[![Build Status](https://img.shields.io/travis/primus/eventemitter3/master.svg?style=flat-square)](https://travis-ci.org/primus/eventemitter3)[![Dependencies](https://img.shields.io/david/primus/eventemitter3.svg?style=flat-square)](https://david-dm.org/primus/eventemitter3)[![Coverage Status](https://img.shields.io/coveralls/primus/eventemitter3/master.svg?style=flat-square)](https://coveralls.io/r/primus/eventemitter3?branch=master)[![IRC channel](https://img.shields.io/badge/IRC-irc.freenode.net%23primus-00a8ff.svg?style=flat-square)](https://webchat.freenode.net/?channels=primus)
[![Sauce Test Status](https://saucelabs.com/browser-matrix/eventemitter3.svg)](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)

View File

@ -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<EventEmitter.EventNames<EventTypes>>;
/**
* Return the listeners registered for a given event.
*/
listeners<T extends EventEmitter.EventNames<EventTypes>>(
event: T
): Array<EventEmitter.EventListener<EventTypes, T>>;
/**
* Return the number of listeners listening to a given event.
*/
listenerCount(event: EventEmitter.EventNames<EventTypes>): number;
/**
* Calls each of the listeners registered for a given event.
*/
emit<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
...args: EventEmitter.EventArgs<EventTypes, T>
): boolean;
/**
* Add a listener for a given event.
*/
on<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn: EventEmitter.EventListener<EventTypes, T>,
context?: Context
): this;
addListener<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn: EventEmitter.EventListener<EventTypes, T>,
context?: Context
): this;
/**
* Add a one-time listener for a given event.
*/
once<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn: EventEmitter.EventListener<EventTypes, T>,
context?: Context
): this;
/**
* Remove the listeners of a given event.
*/
removeListener<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn?: EventEmitter.EventListener<EventTypes, T>,
context?: Context,
once?: boolean
): this;
off<T extends EventEmitter.EventNames<EventTypes>>(
event: T,
fn?: EventEmitter.EventListener<EventTypes, T>,
context?: Context,
once?: boolean
): this;
/**
* Remove all listeners, or those of the specified event.
*/
removeAllListeners(event?: EventEmitter.EventNames<EventTypes>): this;
}
declare namespace EventEmitter {
export interface ListenerFn<Args extends any[] = any[]> {
(...args: Args): void;
}
export interface EventEmitterStatic {
new <
EventTypes extends ValidEventTypes = string | symbol,
Context = any
>(): EventEmitter<EventTypes, Context>;
}
/**
* `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 ValidEventTypes> = T extends string | symbol
? T
: keyof T;
export type ArgumentMap<T extends object> = {
[K in keyof T]: T[K] extends (...args: any[]) => void
? Parameters<T[K]>
: T[K] extends any[]
? T[K]
: any[];
};
export type EventListener<
T extends ValidEventTypes,
K extends EventNames<T>
> = T extends string | symbol
? (...args: any[]) => void
: (
...args: ArgumentMap<Exclude<T, string | symbol>>[Extract<K, keyof T>]
) => void;
export type EventArgs<
T extends ValidEventTypes,
K extends EventNames<T>
> = Parameters<EventListener<T, K>>;
export const EventEmitter: EventEmitterStatic;
}
export = EventEmitter;

336
node_modules/.store/node_modules/eventemitter3/index.js generated vendored Normal file
View File

@ -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;
}

View File

@ -0,0 +1,59 @@
{
"name": "eventemitter3",
"version": "4.0.7",
"description": "EventEmitter3 focuses on performance while maintaining a Node.js AND browser compatible interface.",
"main": "index.js",
"typings": "index.d.ts",
"scripts": {
"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",
"benchmark": "find benchmarks/run -name '*.js' -exec benchmarks/start.sh {} \\;",
"test": "nyc --reporter=html --reporter=text mocha test/test.js",
"prepublishOnly": "npm run browserify && npm run minify",
"test-browser": "node test/browser.js"
},
"files": [
"index.js",
"index.d.ts",
"umd"
],
"repository": {
"type": "git",
"url": "git://github.com/primus/eventemitter3.git"
},
"keywords": [
"EventEmitter",
"EventEmitter2",
"EventEmitter3",
"Events",
"addEventListener",
"addListener",
"emit",
"emits",
"emitter",
"event",
"once",
"pub/sub",
"publish",
"reactor",
"subscribe"
],
"author": "Arnout Kazemier",
"license": "MIT",
"bugs": {
"url": "https://github.com/primus/eventemitter3/issues"
},
"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"
},
"__npminstall_done": true,
"_from": "eventemitter3@4.0.7",
"_resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz"
}

View File

@ -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<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
'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;
}
},{}]},{},[1])(1)
});

View File

@ -0,0 +1 @@
!function(e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).EventEmitter3=e()}(function(){return function i(s,f,c){function u(t,e){if(!f[t]){if(!s[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(a)return a(t,!0);var r=new Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}var o=f[t]={exports:{}};s[t][0].call(o.exports,function(e){return u(s[t][1][e]||e)},o,o.exports,i,s,f,c)}return f[t].exports}for(var a="function"==typeof require&&require,e=0;e<c.length;e++)u(c[e]);return u}({1:[function(e,t,n){"use strict";var r=Object.prototype.hasOwnProperty,v="~";function o(){}function f(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function i(e,t,n,r,o){if("function"!=typeof n)throw new TypeError("The listener must be a function");var i=new f(n,r||e,o),s=v?v+t:t;return e._events[s]?e._events[s].fn?e._events[s]=[e._events[s],i]:e._events[s].push(i):(e._events[s]=i,e._eventsCount++),e}function u(e,t){0==--e._eventsCount?e._events=new o:delete e._events[t]}function s(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(v=!1)),s.prototype.eventNames=function(){var e,t,n=[];if(0===this._eventsCount)return n;for(t in e=this._events)r.call(e,t)&&n.push(v?t.slice(1):t);return Object.getOwnPropertySymbols?n.concat(Object.getOwnPropertySymbols(e)):n},s.prototype.listeners=function(e){var t=v?v+e:e,n=this._events[t];if(!n)return[];if(n.fn)return[n.fn];for(var r=0,o=n.length,i=new Array(o);r<o;r++)i[r]=n[r].fn;return i},s.prototype.listenerCount=function(e){var t=v?v+e:e,n=this._events[t];return n?n.fn?1:n.length:0},s.prototype.emit=function(e,t,n,r,o,i){var s=v?v+e:e;if(!this._events[s])return!1;var f,c=this._events[s],u=arguments.length;if(c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),u){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,t),!0;case 3:return c.fn.call(c.context,t,n),!0;case 4:return c.fn.call(c.context,t,n,r),!0;case 5:return c.fn.call(c.context,t,n,r,o),!0;case 6:return c.fn.call(c.context,t,n,r,o,i),!0}for(p=1,f=new Array(u-1);p<u;p++)f[p-1]=arguments[p];c.fn.apply(c.context,f)}else for(var a,l=c.length,p=0;p<l;p++)switch(c[p].once&&this.removeListener(e,c[p].fn,void 0,!0),u){case 1:c[p].fn.call(c[p].context);break;case 2:c[p].fn.call(c[p].context,t);break;case 3:c[p].fn.call(c[p].context,t,n);break;case 4:c[p].fn.call(c[p].context,t,n,r);break;default:if(!f)for(a=1,f=new Array(u-1);a<u;a++)f[a-1]=arguments[a];c[p].fn.apply(c[p].context,f)}return!0},s.prototype.on=function(e,t,n){return i(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return i(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,n,r){var o=v?v+e:e;if(!this._events[o])return this;if(!t)return u(this,o),this;var i=this._events[o];if(i.fn)i.fn!==t||r&&!i.once||n&&i.context!==n||u(this,o);else{for(var s=0,f=[],c=i.length;s<c;s++)(i[s].fn!==t||r&&!i[s].once||n&&i[s].context!==n)&&f.push(i[s]);f.length?this._events[o]=1===f.length?f[0]:f:u(this,o)}return this},s.prototype.removeAllListeners=function(e){var t;return e?(t=v?v+e:e,this._events[t]&&u(this,t)):(this._events=new o,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=v,s.EventEmitter=s,void 0!==t&&(t.exports=s)},{}]},{},[1])(1)});

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,9 @@
module.exports = {
presets: [
["@babel/preset-env", {
targets: {
node: "current"
}
}]
]
};

View File

@ -0,0 +1,40 @@
declare type LayoutData = {
left: number;
top: number;
width: number;
height: number;
};
declare type LayoutNode = {
id: number;
style: Object;
children: LayoutNode[];
layout?: LayoutData;
};
declare class Element {
static uuid(): number;
parent: Element | null;
id: number;
style: {
[key: string]: any;
};
computedStyle: {
[key: string]: any;
};
lastComputedStyle: {
[key: string]: any;
};
children: {
[key: string]: Element;
};
layoutBox: LayoutData;
constructor(style?: {
[key: string]: any;
});
getAbsolutePosition(element: Element): any;
add(element: Element): void;
remove(element?: Element): void;
getNodeTree(): LayoutNode;
applyLayout(layoutNode: LayoutNode): void;
layout(): void;
}
export default Element;

View File

@ -0,0 +1,5 @@
export default class EventEmitter {
emit(event: string, data?: any): void;
on(event: string, callback: any): void;
off(event: string, callback: any): void;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,36 @@
declare const textStyles: string[];
declare const scalableStyles: string[];
declare const layoutAffectedStyles: string[];
declare 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: boolean;
scale: number;
};
export { getDefaultStyle, scalableStyles, textStyles, layoutAffectedStyles };

View File

@ -0,0 +1,6 @@
module.exports = {
transform: {
"^.+\\.js$": "babel-jest",
"^.+\\.ts$": "ts-jest"
}
};

View File

@ -0,0 +1,27 @@
{
"name": "widget-ui",
"version": "1.0.2",
"description": "",
"main": "dist/index.js",
"scripts": {
"test": "jest",
"build": "webpack"
},
"author": "",
"license": "ISC",
"dependencies": {
"eventemitter3": "^4.0.0"
},
"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"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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
}

View File

@ -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)
})

View File

@ -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"
]
}

206
node_modules/.store/node_modules/widget-ui/tslint.json generated vendored Normal file
View File

@ -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"
]
}

Some files were not shown because too many files have changed in this diff Show More