Commit f3a77362 by 施宇

11

parent feba233e
Showing with 7755 additions and 522 deletions
......@@ -2,9 +2,9 @@
App({
onLaunch: function () {
// 展示本地存储能力
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// var logs = wx.getStorageSync('logs') || []
// logs.unshift(Date.now())
// wx.setStorageSync('logs', logs)
// 登录
wx.login({
......
{
"pages": [
"pages/tab/home/home",
"pages/form/good/index",
"pages/tab/good/good",
"pages/tab/price/price",
"pages/form/bj/index",
"pages/list/bj/index",
"pages/detail/xj/index",
"pages/list/xj/index",
"pages/login/index",
"pages/tab/price/price",
"pages/tab/home/home",
"pages/tab/message/message",
"pages/tab/me/me",
"pages/search/index/index",
"pages/searchresult/index"
"pages/search/result/index",
"pages/form/xj/index",
"pages/detail/good/index",
"pages/detail/xj/index"
],
"window": {
"backgroundTextStyle": "light",
......
......@@ -45,7 +45,84 @@ image {
}
/*复用样式*/
/* 公共导航切换样式 */
.switch-tab-com{
height: 88rpx;
line-height: 88rpx;
text-align: center;
}
.switch-tab-com view {
font-size: 32rpx;
flex: 1;
font-weight: 600;
position: relative;
color: #515559;
}
.switch-tab-com view.active {
color: #0d84d1;
}
.switch-tab-com view.active .active-bg {
position: absolute;
display: inline-block;
width: 68rpx;
height: 25rpx;
background-color: rgba(13, 132, 209, 0.1);
bottom: 15rpx;
left: 50%;
margin-left: -34rpx;
border-radius: 30rpx;
}
/* 公共导航切换样式 */
/* /头部搜索公共样式 */
.search-com{
padding: 15rpx 24rpx;
position: relative;
}
.search-com .icon {
position: absolute;
font-size: 40rpx;
color: #adb6bf;
top: 22rpx;
left: 49rpx;
}
.search-com input {
background: #fff;
height: 58rpx;
border-radius: 50rpx;
padding: 0 18rpx 0 75rpx;
box-sizing: border-box;
background-color: #f0f4f7;
font-size: 24rpx;
}
.search-com .placeholderClass {
color: #adb6bf;
}
/* /头部搜索公共样式 */
/* 暂无数据公共样式 */
.nodata {
text-align: center;
}
.nodata .img {
width: 600rpx;
height: 393rpx;
margin: 0 auto;
}
.nodata .h3 {
font-size: 48rpx;
color: #2e3033;
}
.nodata .p {
font-size: 26rpx;
color: #8a9299;
}
/* 暂无数据公共样式 */
.px-hr-top {
border-top: 1px solid #f5f9fc;
}
......@@ -63,7 +140,8 @@ image {
.bold {
font-weight: 600;
}
.nobold{
.nobold {
font-weight: 400;
}
......@@ -78,14 +156,16 @@ image {
.nowrap {
white-space: nowrap;
}
.t-com{
color:#8A9299;
.t-com {
color: #8a9299;
}
.c-com{
color:#515559;
.c-com {
color: #515559;
}
/**询报价列表**/
/**询报价列表**/
.xb-com-content {
border-radius: 20rpx 20rpx 0px 0px;
background-color: #fff;
......@@ -106,6 +186,10 @@ image {
font-size: 22rpx;
color: #adb6bf;
}
.xb-com-content .title .price {
font-size: 32rpx;
color: #EA1717;
}
.xb-com-content .desc {
padding: 7rpx 24rpx 40rpx 40rpx;
......@@ -113,21 +197,24 @@ image {
font-size: 26rpx;
color: #515559;
}
.xb-com-content .desc .left{
flex:1;
}
.xb-com-content .desc .left view {
padding-top: 16rpx;
}
.xb-com-content .desc .left .t-com{
.xb-com-content .desc .left .t-com {
flex: 0 0 78rpx;
}
.xb-com-content .desc .left .price .t-com {
flex: 0 0 104rpx;
}
.xb-com-content .desc .right {
height: 220rpx;
width: 220rpx;
flex:0 0 220rpx;
height:220rpx;
margin-top: 16px;
}
......@@ -145,22 +232,26 @@ image {
height: 30rpx;
width: 2px;
}
.btn-com{
height:98rpx;
.btn-com {
height: 98rpx;
font-size: 32rpx;
color:#fff;
margin:0 55rpx;
color: #fff;
margin: 0 55rpx;
text-align: center;
line-height: 98rpx;
border-radius:8rpx;
border-radius: 8rpx;
}
.btn-com-y{
background-color: #EAAD37;
box-shadow:0px 6px 10px 0px rgba(242,191,97,0.5);
.btn-com-y {
background-color: #eaad37;
box-shadow: 0px 6px 10px 0px rgba(242, 191, 97, 0.5);
}
.btn-com-b{
background-color: #0D84D1;
box-shadow:0px 6px 10px 0px rgba(97,160,242,0.3);
.btn-com-b {
background-color: #0d84d1;
box-shadow: 0px 6px 10px 0px rgba(97, 160, 242, 0.3);
}
/**询报价列表**/
/**字体**/
@import 'res/fonts/iconfont.wxss'
......@@ -29,6 +29,8 @@ Component({
* 组件的方法列表
*/
methods: {
emitevent:function(){
this.triggerEvent('emitevent')
}
}
})
......@@ -2,7 +2,7 @@
<block>
<!-- 询报价展示 -->
<block wx:if="{{priceType==1}}">
<view class="price-item" wx:for="{{priceList}}" wx:key="*this">
<view class="price-item" wx:for="{{priceList}}" wx:key="*this" bindtap="emitevent">
<view class="item-header px-hr-bottom row verCenter bothSide nowrap">
<view class="row verCenter">
<text class="mark xun" wx:if="{{xb==1}}">询</text>
......@@ -27,7 +27,7 @@
</block>
<!-- 搜索页的商品展示 -->
<block wx:if="{{priceType==2}}">
<view class="price-item" wx:for="{{priceList}}" wx:key="*this">
<view class="price-item" wx:for="{{priceList}}" wx:key="*this" bindtap="emitevent">
<view class="item-header px-hr-bottom row verCenter bothSide nowrap">
<view class="row verCenter">
<text class="mark bao" wx:if="{{item.type==1}}">贸易商</text>
......@@ -49,7 +49,7 @@
</block>
<!-- 搜索页面询报价展示 -->
<block wx:if="{{priceType==3}}">
<view class="price-item" wx:for="{{priceList}}" wx:key="*this">
<view class="price-item" wx:for="{{priceList}}" wx:key="*this" bindtap="emitevent">
<view class="item-header px-hr-bottom row verCenter bothSide nowrap">
<view class="row verCenter">
<text class="mark xun" wx:if="{{xb==1}}">询价</text>
......@@ -77,7 +77,7 @@
</block>
<!-- 我的报价展示 -->
<block wx:if="{{priceType==4}}">
<view class="price-item" wx:for="{{priceList}}" wx:key="*this">
<view class="price-item" wx:for="{{priceList}}" wx:key="*this" bindtap="emitevent">
<view class="item-header px-hr-bottom row verCenter bothSide nowrap">
<view class="row verCenter">
<text class="mark bao">报价</text>
......@@ -102,4 +102,20 @@
</view>
</view>
</block>
<!-- 商品管理 -->
<block wx:if="{{priceType == 5}}">
<view class="price-item" wx:for="{{priceList}}" wx:key="*this" bindtap="emitevent">
<view class="item-header row verCenter bothSide nowrap">
<view class="row verCenter">
<text class="name ellipsis good-name">{{item.name}}</text>
<text class="icon iconfont iconiconxiantiaoshouji14 good-icon"></text>
</view>
<text class="price">¥{{item.price}}</text>
</view>
<view class="item-middle row verCenter nowrap">
<text class="brand ellipsis"><text>品牌:</text>{{item.brand}}</text>
<text class="num bold"><text class="nobold">库存: </text>{{item.num}}PCS</text>
</view>
</view>
</block>
</block>
\ No newline at end of file
......@@ -12,6 +12,7 @@
overflow: hidden;
}
.item-header .mark {
border-radius: 2px;
font-size: 24rpx;
......@@ -35,7 +36,6 @@
}
.p
.price-item .name, .price-item .company {
color: #515559;
margin-right: 24rpx;
......@@ -44,7 +44,16 @@
.price-item .name {
font-size: 32rpx;
}
.price-item .good-name{
margin-right:0;
flex:1;
}
.item-header .good-icon{
font-size: 50rpx;
color:#ADB6BF;
flex:0 0 50rpx;
margin:0 16rpx;
}
.price-item .company {
font-size: 26rpx;
}
......
// pages/detail/good/index.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
\ No newline at end of file
{
"usingComponents": {},
"navigationBarBackgroundColor": "#0D84D1",
"navigationBarTextStyle": "white",
"backgroundColor": "#0d84d1",
"navigationBarTitleText": ""
}
\ No newline at end of file
<!--pages/detail/good/index.wxml-->
<view class="detail-view">
<view class="t-desc">
<view class="top row bothSide verCenter">
<view class="company row verCenter">
<text class="name bold">深圳市德卡科技股份有限公司深圳</text>
</view>
<text class="icon iconfont iconiconxiantiaoshouji6"></text>
</view>
<view class="bottom row">
<view class="yes">
<text class="icon iconfont iconiconxiantiaoshouji11"></text>
<text>公司认证</text>
</view>
<view class="yes">
<text class="icon iconfont iconiconxiantiaoshouji11"></text>
<text>贸易商</text>
</view>
</view>
</view>
<view class="xb-com-content">
<view class="title row bothSide verCenter nowrap px-hr-bottom">
<text class="name bold ellipsis">STM32F407ZGT6STM32F407ZGT6STM32F407ZGT6</text>
<text class="price bold">¥100.0120</text>
</view>
<view class="desc row bothSide">
<view class="left">
<view class="brand row">
<text class="t-com">品牌:</text>
<text class="c-com">Texas Instruments</text>
</view>
<view class="fz row">
<text class="t-com">封装:</text>
<text class="c-com">LQFP-64</text>
</view>
<view class="hq row">
<text class="t-com">货期:</text>
<text class="c-com">现货</text>
</view>
<view class="num row">
<text class="t-com">库存:</text>
<text class="c-com bold">100,000 PCS</text>
</view>
<view class="bjsj row">
<text class="t-com">更新时间:</text>
<text class="c-com">2019-05-10 10:15</text>
</view>
</view>
<cover-image class="right" src="/res/images/imgs/iclogo.png"></cover-image>
</view>
</view>
<!-- <view class="zxgt btn-com btn-com-y">
<text class="icon iconfont iconiconxiantiaoshouji11"></text>
<text class="gt-t">在线沟通</text>
</view> -->
<view class="zxgt btn-com btn-com-b">
<text class="gt-t">编辑商品</text>
</view>
</view>
\ No newline at end of file
/* pages/detail/good/index.wxss */
@import '/res/css/detail.wxss'
\ No newline at end of file
// pages/detail/xj/index.js
let arr = [
{
name: "STM32F407ZGT6",
price: "100.012",
brand: "Texas InstrumentsTexas",
num: "100,000",
desc: "深圳地区原装现货深圳地区原装现货",
time: "05-10 10:15",
company: "朗新科技股份有限公司"
},
{
name: "STM32F407ZGT6",
price: "100.012",
brand: "Texas InstrumentsTexas",
num: "100,000",
desc: "深圳地区原装现货深圳地区原装现货",
time: "05-10 10:15",
company: "深圳邦马特科技有限公司"
}
]
Page({
/**
* 页面的初始数据
*/
data: {
priceList: undefined,
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let seft = this;
wx.showLoading({
title: '加载中',
})
setTimeout(() => {
wx.hideLoading()
seft.setData({ priceList: arr })
}, 2000)
},
/**
......
{
"usingComponents": {
"priceItem": "/components/priceItem/priceItem"
},
"usingComponents": {},
"navigationBarBackgroundColor": "#0D84D1",
"navigationBarTextStyle": "white",
"backgroundColor": "#0d84d1",
......
<!--pages/detail/xj/index.wxml-->
<view class="xj-detail-view">
<view class="detail-view">
<view class="t-desc">
<view class="top row bothSide verCenter">
<view class="company row verCenter">
......@@ -19,12 +19,12 @@
</view>
</view>
</view>
<view class="bj-desc">
<view class="xb-com-content">
<view class="title row bothSide verCenter nowrap px-hr-bottom">
<text class="name bold ellipsis">STM32F407ZGT6STM32</text>
<text class="price bold">¥100.0120</text>
</view>
<view class="desc">
<view class="desc desc-xj-detail">
<view class="brand row">
<text class="t-com">品牌:</text>
<text class="c-com">Texas Instruments</text>
......
/* pages/detail/xj/index.wxss */
.t-desc {
background-color: #0d84d1;
color: #fff;
font-size: 26rpx;
padding: 24rpx 24rpx 62rpx;
}
.company {
flex: 1;
}
.company .bao {
flex: 0 0 87rpx;
height: 36rpx;
text-align: center;
line-height: 36rpx;
border-radius: 2rpx;
margin-right: 24rpx;
}
.company .name {
font-size: 32rpx;
flex: 1;
}
.top .icon {
font-size: 40rpx;
}
.bottom {
flex-wrap: wrap;
}
.bottom .yes {
margin: 24rpx 24rpx 0 0;
}
.yes .icon {
color: #61a0f2;
font-size: 30rpx;
margin-right: 12rpx;
}
.bj-desc{
border-radius: 20rpx 20rpx 0px 0px;
position: relative;
background-color: #fff;
top:-22rpx;
}
.bj-desc .title {
margin-left: 24rpx;
padding: 32rpx 24rpx 24rpx 0;
}
.title .name {
font-size: 36rpx;
color: #2e3033;
}
.title .price {
font-size: 32rpx;
color: #ea1717;
margin-left: 27rpx;
}
.bj-desc .desc {
padding: 0 40rpx;
font-size: 26rpx;
}
.bjsj .t-com{
flex:0 0 130rpx;
}
.bjsj .c-com,.bz .c-com{
color:#8A9299
}
.desc view {
padding-top: 16rpx;
}
.zxgt{
position: absolute;
bottom:94rpx;
left:0;
right:0;
}
.zxgt .icon{
margin-right:7rpx;
font-size: 40rpx;
vertical-align:middle;
}
\ No newline at end of file
@import '/res/css/detail.wxss'
\ No newline at end of file
/* pages/form/bj/index.wxss */
.form-view {
}
.tip {
padding: 12rpx 24rpx;
background-color: #fff6e6;
}
.tip .close-icon {
color: #d8dfe6;
}
.tip .icon {
font-size: 30rpx;
}
.tip-left {
color: #eaa217;
}
.tip-left .tip-icon {
margin-right: 7rpx;
vertical-align: middle;
}
.tip-c {
font-size: 24rpx;
}
.form-item {
margin-left: 24rpx;
padding: 27rpx 0;
font-size: 28rpx;
color: #515559;
position: relative;
}
.form-item .placeholderClass {
color: #adb6bf;
font-size: 28rpx;
}
.form-item-title {
flex: 0 0 71rpx;
text-align: right;
}
.form-item-right {
flex: 1;
padding: 0 24rpx 0 117rpx;
}
.bj-item .price-type {
border-left: 1px solid #d8dfe6;
}
.price-type .price-value {
font-size: 32rpx;
color: #515559;
padding: 7rpx 11rpx 7rpx 16rpx;
}
.price-type .icon {
color: #d8dfe6;
font-size: 26rpx;
}
.qx-item {
text-align: right;
}
.qx-item radio {
margin-left: 50rpx;
}
.form-hr {
height: 10rpx;
background-color: #f5f9fc;
}
textarea {
width: 100%;
height: 150rpx;
}
.hf-btn {
margin: 60rpx 55rpx;
}
.price-ul {
position: absolute;
top: 100rpx;
right: 24rpx;
background-color: #fff;
box-shadow: 2px 2px 5px #ddd;
z-index: 2;
border-radius: 2rpx;
display: none;
}
.price-ul.show {
display: block;
}
.price-ul .price-li {
padding: 25rpx 40rpx;
text-align: center;
font-size: 32rpx;
}
.price-ul .price-li.active {
color: #0d84d1;
}
@import '/res/css/form.wxss'
// pages/form/good/index.js
Page({
/**
* 页面的初始数据
*/
data: {
isShowSwitch: false
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
switchPrice: function () {
this.setData({
isShowSwitch: !this.data.isShowSwitch
})
}
})
\ No newline at end of file
{
"usingComponents": {},
"navigationBarTitleText": "新增商品"
}
\ No newline at end of file
<!--pages/form/good/index.wxml-->
<view class="form-view">
<view class="tip row bothSide verCenter">
<view class="tip-left">
<text class="icon iconfont iconiconxiantiaoshouji12 tip-icon"></text>
<text class="tip-c">批量商品上传请到<text class="pc-url">www.icsales.com</text>操作</text>
</view>
<text class="icon iconfont iconiconxiantiaoshouji13 close-icon"></text>
</view>
<view class="upload-view column verCenter">
<view class="upload column verCenter rowCenter">
<text class="icon iconfont iconiconxiantiaoshouji15"></text>
<text class="upload-text">上传图片</text>
</view>
<view class="text">据说上传图片更容易被采纳报价</view>
</view>
<view class="form-item row verCenter">
<text class="form-item-title">*型号</text>
<view class="form-item-right">
<input placeholder="请输入产品型号(必填)" placeholder-class="placeholderClass"></input>
</view>
</view>
<view class="form-item row verCenter px-hr-top">
<text class="form-item-title">*品牌</text>
<view class="form-item-right">
<input placeholder="请输入品牌(必填)" placeholder-class="placeholderClass"></input>
</view>
</view>
<view class="form-item row verCenter px-hr-top">
<text class="form-item-title"> 封装</text>
<view class="form-item-right">
<input placeholder="请输入封装" placeholder-class="placeholderClass"></input>
</view>
</view>
<view class="form-item row verCenter px-hr-top">
<text class="form-item-title">*库存</text>
<view class="form-item-right">
<input placeholder="请输入库存数量(必填)" placeholder-class="placeholderClass"></input>
</view>
</view>
<view class="form-item row verCenter px-hr-top bj-item">
<text class="form-item-title">*报价</text>
<view class="form-item-right row verCenter bothSide">
<input placeholder="请输入单价" placeholder-class="placeholderClass"></input>
<view class="price-type" bindtap="switchPrice">
<text class="price-value">RMB</text>
<text class="icon iconfont iconbianzu1"></text>
</view>
</view>
<view class="price-ul {{isShowSwitch?'show':''}}">
<view class="price-li active">RMB</view>
<view class="price-li px-hr-top">USD</view>
</view>
</view>
<view class="form-item row verCenter px-hr-top qx-item px-hr-bottom">
<text class="form-item-title">*货期</text>
<view class="form-item-right">
<radio-group>
<label>
<radio value="1" checked/>现货
</label>
<label>
<radio value="2" checked/>期货
</label>
</radio-group>
</view>
</view>
<view class="btn-com btn-com-b hf-btn">
<text class="icon iconfont iconiconxiantiaoshouji15"></text>
<text>新增商品</text>
</view>
</view>
\ No newline at end of file
/* pages/form/good/index.wxss */
@import '/res/css/form.wxss'
\ No newline at end of file
// pages/form/xj/index.js
Page({
/**
* 页面的初始数据
*/
data: {
isShowSwitch: false
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
switchPrice: function () {
this.setData({
isShowSwitch: !this.data.isShowSwitch
})
}
})
\ No newline at end of file
{
"usingComponents": {},
"navigationBarTitleText": "发布询价"
}
\ No newline at end of file
<!--pages/form/xj/index.wxml-->
<view class="form-view">
<view class="tip row bothSide verCenter">
<view class="tip-left">
<text class="icon iconfont iconiconxiantiaoshouji12 tip-icon"></text>
<text class="tip-c">填写完整信息,有利于提高回复报价效率</text>
</view>
<text class="icon iconfont iconiconxiantiaoshouji13 close-icon"></text>
</view>
<view class="upload-view column verCenter">
<view class="upload column verCenter rowCenter">
<text class="icon iconfont iconiconxiantiaoshouji15"></text>
<text class="upload-text">上传图片</text>
</view>
<view class="text">据说上传图片更容易让人报价</view>
</view>
<view class="form-item row verCenter">
<text class="form-item-title">*型号</text>
<view class="form-item-right">
<input placeholder="请输入产品型号(必填)" placeholder-class="placeholderClass"></input>
</view>
</view>
<view class="form-item row verCenter px-hr-top">
<text class="form-item-title">*品牌</text>
<view class="form-item-right">
<input placeholder="请输入品牌(必填)" placeholder-class="placeholderClass"></input>
</view>
</view>
<view class="form-item row verCenter px-hr-top">
<text class="form-item-title"> 封装</text>
<view class="form-item-right">
<input placeholder="请输入封装" placeholder-class="placeholderClass"></input>
</view>
</view>
<view class="form-item row verCenter px-hr-top">
<text class="form-item-title">*数量</text>
<view class="form-item-right">
<input placeholder="请输入数量(必填)" placeholder-class="placeholderClass"></input>
</view>
</view>
<view class="form-item row verCenter px-hr-top bj-item">
<text class="form-item-title">*价格</text>
<view class="form-item-right row verCenter bothSide">
<input placeholder="请输入单价" placeholder-class="placeholderClass"></input>
<view class="price-type" bindtap="switchPrice">
<text class="price-value">RMB</text>
<text class="icon iconfont iconbianzu1"></text>
</view>
</view>
<view class="price-ul {{isShowSwitch?'show':''}}">
<view class="price-li active">RMB</view>
<view class="price-li px-hr-top">USD</view>
</view>
</view>
<view class="form-item row verCenter px-hr-top qx-item">
<text class="form-item-title">*货期</text>
<view class="form-item-right">
<radio-group>
<label>
<radio value="1" checked/>现货
</label>
<label>
<radio value="2" checked/>期货
</label>
</radio-group>
</view>
</view>
<view class="form-hr"></view>
<view class="form-item row px-hr-bottom">
<text class="form-item-title">备注</text>
<view class="form-item-right">
<textarea placeholder="请输入备注" placeholder-class="placeholderClass" maxlength="-1" />
</view>
</view>
<view class="btn-com btn-com-b hf-btn">发布询价</view>
</view>
\ No newline at end of file
/* pages/form/xj/index.wxss */
@import '/res/css/form.wxss'
\ No newline at end of file
......@@ -111,5 +111,10 @@ Page({
*/
onShareAppMessage: function () {
},
goBj:function(){
wx.navigateTo({
url: "/pages/form/bj/index",
})
}
})
\ No newline at end of file
......@@ -60,5 +60,5 @@
</view>
</view>
<view class="btn-com btn-com-b bj-btn">继续报价,剩余1次</view>
<view class="btn-com btn-com-b bj-btn" bindtap="goBj">继续报价,剩余1次</view>
</view>
\ No newline at end of file
......@@ -93,5 +93,10 @@ Page({
*/
onShareAppMessage: function () {
},
emitevent:function(){
wx.navigateTo({
url: "/pages/detail/xj/index",
})
}
})
\ No newline at end of file
......@@ -48,7 +48,7 @@
<view wx:if="{{priceList&&priceList.length==0}}" class="nodata">
暂无数据
</view>
<priceItem price-list="{{priceList}}" wx:if="{{priceList&&priceList.length!==0}}" price-type="3" xb="2"></priceItem>
<priceItem price-list="{{priceList}}" wx:if="{{priceList&&priceList.length!==0}}" price-type="3" xb="2" bindemitevent="emitevent"></priceItem>
</view>
</view>
</view>
\ No newline at end of file
......@@ -62,5 +62,10 @@ Page({
*/
onShareAppMessage: function () {
},
confirmTap:function(){
wx.navigateTo({
url: "/pages/search/result/index",
})
}
})
\ No newline at end of file
<!--pages/search/index/index.wxml-->
<view class="search-view">
<view class="search-section">
<view class="search-com">
<text class="icon iconfont iconiconxiantiaoshouji8"></text>
<input placeholder='请输入芯片型号' placeholder-class="placeholderClass" bindtap="toSearch"></input>
<input placeholder='请输入芯片型号' placeholder-class="placeholderClass" auto-focus bindconfirm="confirmTap"></input>
</view>
<view class="rm_search">
<text class="title beforeLine">热门搜索</text>
......
/* pages/search/index/index.wxss */
.search-section {
padding: 15rpx 24rpx;
position: relative;
}
.search-section .icon {
position: absolute;
font-size: 40rpx;
color: #adb6bf;
top: 22rpx;
left: 49rpx;
}
.search-section input {
background: #fff;
height: 58rpx;
border-radius: 50rpx;
padding: 0 18rpx 0 75rpx;
box-sizing: border-box;
background-color: #f0f4f7;
font-size: 24rpx;
}
.search-section .placeholderClass {
color: #adb6bf;
}
.title {
font-weight: 600;
font-size: 28rpx;
......
......@@ -181,5 +181,10 @@ Page({
}
},
toXj:function(){
wx.navigateTo({
url: "/pages/form/xj/index"
})
}
})
\ No newline at end of file
{
"usingComponents": {
"priceItem": "/components/priceItem/priceItem"
}
},
"navigationBarTitleText": "搜索"
}
\ No newline at end of file
<!--pages/searchresult/index.wxml-->
<view class="searchresult-view">
<view class="search-section">
<view class="search-com">
<text class="icon iconfont iconiconxiantiaoshouji8"></text>
<input placeholder='请输入芯片型号' placeholder-class="placeholderClass" bindtap="toSearch"></input>
</view>
<view class="searchresult-tab row">
<view class="switch-tab-com row">
<view bindtap="switchTab" class="{{tabIndex == 1&&'active'}}" data-index="1">
<text>商品</text>
<text class="active-bg"></text>
......@@ -17,19 +17,19 @@
<view class="searchresult-content">
<view wx:if="{{priceList&&priceList.length==0}}" class="nodata">
<cover-image src="/res/images/imgs/nodata.png" class="img"></cover-image>
<view class="h3">未搜索到相关信息</view>
<view class="h3 bold">未搜索到相关信息</view>
<view class="p">您还可以发布询价。</view>
<view class="nodata_fb fb_btn">
<view class="nodata_fb btn-com btn-com-b" bindtap="toXj">
<text>快速发布询价</text>
</view>
</view>
<priceItem price-list="{{priceList}}" wx:if="{{priceList&&priceList.length!==0}}" price-type="{{type}}"></priceItem>
<priceItem price-list="{{priceList}}" wx:if="{{priceList&&priceList.length!==0}}" price-type="{{type}}" xb="1"></priceItem>
</view>
<view class="fast_fb fb_btn" wx:if="{{priceList&&priceList.length!==0}}">
<view class="fast_fb btn-com btn-com-b" wx:if="{{priceList&&priceList.length!==0}}" bindtap="toXj">
<text>快速发布询价</text>
</view>
<view class="concat_custom" wx:if="{{priceList&&priceList.length==0}}">
<text class="icon iconfont iconiconxiantiaoshouji11"></text>
<text>快速发布询价</text>
<text>联系客服帮您找</text>
</view>
</view>
\ No newline at end of file
/* pages/searchresult/index.wxss */
.searchresult-view {
min-height: 100%;
position: relative;
padding-bottom: 234rpx;
box-sizing: border-box;
}
.fast_fb {
position: absolute;
bottom: 68rpx;
left:0;
right:0;
}
.nodata .p {
margin-top: 14rpx;
}
.nodata_fb {
margin-top:40rpx;
}
.concat_custom {
position: absolute;
bottom: 68rpx;
left: 0;
right: 0;
text-align: center;
color:#61A0F2;
font-size: 28rpx;
}
.concat_custom .icon{
font-size: 40rpx;
margin-right:16rpx;
vertical-align: sub;
}
/* pages/searchresult/index.wxss */
.searchresult-view {
min-height: 100%;
position: relative;
padding-bottom: 234rpx;
box-sizing: border-box;
}
.search-section {
padding: 15rpx 24rpx;
position: relative;
}
.search-section .icon {
position: absolute;
font-size: 40rpx;
color: #adb6bf;
top: 22rpx;
left: 49rpx;
}
.search-section input {
background: #fff;
height: 58rpx;
border-radius: 50rpx;
padding: 0 18rpx 0 75rpx;
box-sizing: border-box;
background-color: #f0f4f7;
font-size: 24rpx;
}
.search-section .placeholderClass {
color: #adb6bf;
}
.searchresult-tab {
height: 88rpx;
line-height: 88rpx;
text-align: center;
}
.searchresult-tab view {
font-size: 32rpx;
flex: 1;
font-weight: 600;
position: relative;
color: #515559;
}
.searchresult-tab view.active {
color: #0d84d1;
}
.searchresult-tab view.active .active-bg {
position: absolute;
display: inline-block;
width: 68rpx;
height: 25rpx;
background-color: rgba(13, 132, 209, 0.1);
bottom: 15rpx;
left: 50%;
margin-left: -34rpx;
border-radius: 30rpx;
}
.fast_fb {
position: absolute;
bottom: 68rpx;
left: 55rpx;
right: 55rpx;
}
.nodata {
text-align: center;
}
.nodata .img {
width: 600rpx;
height: 393rpx;
margin: 0 auto;
}
.nodata .h3 {
font-weight: 600;
font-size: 48rpx;
color: #2e3033;
}
.nodata .p {
font-size: 26rpx;
color: #8a9299;
margin-top: 14rpx;
}
.nodata_fb {
margin: 40rpx 55rpx;
}
.concat_custom {
position: absolute;
bottom: 68rpx;
left: 0;
right: 0;
text-align: center;
color:#61A0F2;
font-size: 28rpx;
}
.concat_custom .icon{
font-size: 40rpx;
margin-right:16rpx;
vertical-align: sub;
}
// pages/tab/good/good.js
let arr = [
{
name: "STM32F407ZGT6",
price: "100.012",
brand: "Texas InstrumentsTexas",
num: "100,000",
}
]
Page({
/**
* 页面的初始数据
*/
data: {
priceList:undefined
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let seft = this;
wx.showLoading({
title: '加载中',
})
setTimeout(() => {
wx.hideLoading()
seft.setData({ priceList: arr })
}, 2000)
},
/**
......@@ -54,7 +73,7 @@ Page({
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
console.log(1111)
},
/**
......@@ -62,5 +81,15 @@ Page({
*/
onShareAppMessage: function () {
},
fbGood: function () {
wx.navigateTo({
url: "/pages/form/good/index",
})
},
emitevent:function(){
wx.navigateTo({
url: "/pages/detail/good/index",
})
}
})
\ No newline at end of file
{
"usingComponents": {},
"usingComponents": {
"priceItem": "/components/priceItem/priceItem"
},
"navigationBarTitleText": "商品管理"
}
\ No newline at end of file
<!--pages/tab/good/good.wxml-->
<view class="good-view">
<view class="search-section">
<view class="search-com">
<text class="icon iconfont iconiconxiantiaoshouji8"></text>
<input placeholder='请输入芯片型号' placeholder-class="placeholderClass" bindtap="toSearch"></input>
</view>
......@@ -14,4 +14,24 @@
<text>2019-05-14 10:40</text>
</text>
</view>
<view class="good-content">
<view wx:if="{{priceList&&priceList.length==0}}" class="nodata">
<cover-image src="/res/images/imgs/nodata.png" class="img"></cover-image>
<view class="h3 bold">未搜索到相关信息</view>
<view class="p">您还可以发布询价。</view>
<view class="btn-com btn-com-b add-good-btn">
<text class="icon iconfont iconiconxiantiaoshouji15"></text>
<text>新增商品</text>
</view>
</view>
<priceItem price-list="{{priceList}}" wx:if="{{priceList&&priceList.length!==0}}" price-type="5" bindemitevent="emitevent"></priceItem>
</view>
<view class="good-btn-div" wx:if="{{priceList&&priceList.length!==0}}">
<view class="btn-com btn-com-b add-good-btn" bindtap="fbGood">
<text class="icon iconfont iconiconxiantiaoshouji15"></text>
<text>新增商品</text>
</view>
</view>
</view>
\ No newline at end of file
/* pages/tab/good/good.wxss */
.search-section {
padding: 15rpx 24rpx;
position: relative;
}
.search-section .icon {
position: absolute;
font-size: 40rpx;
.good-view {
min-height: 100%;
padding-bottom: 118rpx;
box-sizing: border-box;
}
.good-total {
padding: 37rpx 24rpx 24rpx 0;
margin-left: 24rpx;
font-size: 22rpx;
color: #adb6bf;
top: 22rpx;
left: 49rpx;
}
.search-section input {
background: #fff;
height: 58rpx;
border-radius: 50rpx;
padding: 0 18rpx 0 75rpx;
box-sizing: border-box;
background-color: #f0f4f7;
.good-total .good-num {
font-size: 24rpx;
}
.search-section .placeholderClass {
color: #adb6bf;
.good-total .good-num .num {
color: #515559;
}
.good-total {
padding:37rpx 24rpx 24rpx 0;
margin-left:24rpx;
font-size: 22rpx;
color:#ADB6BF;
.good-btn-div{
position: fixed;
left:0;
bottom:0;
right:0;
background-color: #fff;
height:118rpx;
}
.good-total .good-num{
font-size: 24rpx;
.add-good-btn {
margin-top:10rpx;
}
.add-good-btn .icon {
margin-right: 8rpx;
font-size: 32rpx;
}
.nodata .p{
margin-top:14rpx;
}
.good-total .good-num .num{
color:#515559;
.nodata .add-good-btn{
margin-top:40rpx;
}
\ No newline at end of file
......@@ -133,5 +133,20 @@ Page({
wx.navigateTo({
url: '/pages/search/index/index',
})
},
toXj: function () {
wx.navigateTo({
url: "/pages/form/xj/index"
})
},
fbGood:function(){
wx.navigateTo({
url: "/pages/form/good/index",
})
},
emitevent:function(){
wx.navigateTo({
url: "/pages/list/bj/index",
})
}
})
\ No newline at end of file
......@@ -2,11 +2,11 @@
<view class="home-view">
<view class="search-section">
<text class="icon iconfont iconiconxiantiaoshouji8"></text>
<input placeholder='请输入芯片型号' placeholder-class="placeholderClass" bindtap="toSearch"></input>
<input placeholder='请输入芯片型号' placeholder-class="placeholderClass" bindtap="toSearch" disabled></input>
</view>
<view class="home-content">
<view class="home-function bothSide row">
<view class="function-item column verCenter">
<view class="function-item column verCenter" bindtap="toXj">
<cover-image src="/res/images/icons/home-s-1.png" class="img"></cover-image>
<text class="text">发布询价</text>
</view>
......@@ -14,7 +14,7 @@
<cover-image src="/res/images/icons/home-s-2.png" class="img"></cover-image>
<text class="text">抢单专区</text>
</view>
<view class="function-item column verCenter">
<view class="function-item column verCenter" bindtap="fbGood">
<cover-image src="/res/images/icons/home-s-3.png" class="img"></cover-image>
<text class="text">发布商品</text>
</view>
......@@ -59,7 +59,7 @@
</view>
<view class="price-content">
<view wx:if="{{priceList&&priceList.length==0}}">暂无数据</view>
<priceItem price-list="{{priceList}}" wx:if="{{priceList&&priceList.length!==0}}" price-type="1"></priceItem>
<priceItem price-list="{{priceList}}" wx:if="{{priceList&&priceList.length!==0}}" price-type="1" bindemitevent="emitevent"></priceItem>
</view>
</view>
</view>
......
{
"usingComponents": {}
"usingComponents": {},
"navigationBarTitleText": "消息"
}
\ No newline at end of file
......@@ -32,8 +32,8 @@ Page({
* 页面的初始数据
*/
data: {
tabIndex:1,
xb:1,
tabIndex: 1,
xb: 1,
priceList: undefined,
},
......@@ -118,7 +118,7 @@ Page({
this.setData({
tabIndex: i,
priceList: [],
xb:2
xb: 2
});
}
......@@ -126,5 +126,21 @@ Page({
}
},
toXj: function () {
wx.navigateTo({
url: "/pages/form/xj/index"
})
},
emitevent:function(){
if(this.data.xb == 1){
wx.navigateTo({
url: "/pages/list/xj/index",
})
}else{
wx.navigateTo({
url: "/pages/list/bj/index",
})
}
}
})
\ No newline at end of file
<!--pages/tab/price/price.wxml-->
<view class="price-view">
<view class="searchresult-tab row">
<view class="switch-tab-com row">
<view bindtap="switchTab" class="{{tabIndex == 1&&'active'}}" data-index="1">
<text>我的询价</text>
<text class="active-bg"></text>
......@@ -13,12 +13,12 @@
<view class="price-content">
<view wx:if="{{priceList&&priceList.length==0}}" class="nodata">
<cover-image src="/res/images/imgs/noxb.png" class="img"></cover-image>
<view class="h3">暂无询报价信息</view>
<view class="h3 bold">暂无询报价信息</view>
<view class="p">您还可以发布询价。</view>
<view class="fb_btn">
<view class="fb_btn btn-com btn-com-b" bindtap="toXj">
<text>快速发布询价</text>
</view>
</view>
<priceItem price-list="{{priceList}}" wx:if="{{priceList&&priceList.length!==0}}" price-type="1" xb="{{xb}}"></priceItem>
<priceItem price-list="{{priceList}}" wx:if="{{priceList&&priceList.length!==0}}" price-type="1" xb="{{xb}}" bindemitevent="emitevent"></priceItem>
</view>
</view>
\ No newline at end of file
/* pages/tab/price/price.wxss */
.searchresult-tab {
height: 88rpx;
line-height: 88rpx;
text-align: center;
}
.searchresult-tab view {
font-size: 32rpx;
flex: 1;
font-weight: 600;
position: relative;
color: #515559;
}
.searchresult-tab view.active {
color: #0d84d1;
}
.searchresult-tab view.active .active-bg {
position: absolute;
display: block;
width: 68rpx;
height: 25rpx;
background-color: rgba(13, 132, 209, 0.1);
bottom: 15rpx;
left: 50%;
transform: translateX(-50%);
border-radius: 30rpx;
}
.nodata {
text-align: center;
}
.nodata .img {
width: 600rpx;
height: 393rpx;
margin: 0 auto;
}
.nodata .h3 {
font-weight: 600;
font-size: 48rpx;
color: #2e3033;
}
.nodata .p {
font-size: 26rpx;
color: #8a9299;
margin-top: 14rpx;
}
.nodata .fb_btn {
margin:40rpx 55rpx 0
margin-top:40rpx
}
.t-desc {
background-color: #0d84d1;
color: #fff;
font-size: 26rpx;
padding: 24rpx 24rpx 62rpx;
}
.company {
flex: 1;
}
.company .bao {
flex: 0 0 87rpx;
height: 36rpx;
text-align: center;
line-height: 36rpx;
border-radius: 2rpx;
margin-right: 24rpx;
}
.company .name {
font-size: 32rpx;
flex: 1;
}
.top .icon {
font-size: 40rpx;
}
.bottom {
flex-wrap: wrap;
}
.bottom .yes {
margin: 24rpx 24rpx 0 0;
}
.yes .icon {
color: #61a0f2;
font-size: 30rpx;
margin-right: 12rpx;
}
.xb-com-content {
top: -22rpx;
}
.xb-com-content .desc {
border: none;
}
.xb-com-content .desc .left .bjsj .t-com {
flex: 0 0 130rpx;
}
.bjsj .c-com, .bz .c-com {
color: #8a9299;
}
.desc-xj-detail view{
padding-top:16rpx;
}
.zxgt {
position: absolute;
bottom: 94rpx;
left: 0;
right: 0;
}
.zxgt .icon {
margin-right: 7rpx;
font-size: 40rpx;
vertical-align: middle;
}
.form-view {
}
.tip {
padding: 12rpx 24rpx;
background-color: #fff6e6;
}
.tip .close-icon {
color: #d8dfe6;
}
.tip .icon {
font-size: 30rpx;
}
.tip-left {
color: #eaa217;
}
.tip-left .tip-icon {
margin-right: 7rpx;
vertical-align: middle;
}
.tip-c {
font-size: 24rpx;
}
.tip-c .pc-url{
color:#61A0F2;
}
.form-item {
margin-left: 24rpx;
padding: 27rpx 0;
font-size: 28rpx;
color: #515559;
position: relative;
}
.form-item .placeholderClass {
color: #adb6bf;
font-size: 28rpx;
}
.form-item-title {
flex: 0 0 71rpx;
text-align: right;
}
.form-item-right {
flex: 1;
padding: 0 24rpx 0 117rpx;
}
.bj-item .price-type {
border-left: 1px solid #d8dfe6;
}
.price-type .price-value {
font-size: 32rpx;
color: #515559;
padding: 7rpx 11rpx 7rpx 16rpx;
}
.price-type .icon {
color: #d8dfe6;
font-size: 26rpx;
}
.qx-item {
text-align: right;
}
.qx-item radio {
margin-left: 50rpx;
}
.form-hr {
height: 10rpx;
background-color: #f5f9fc;
}
textarea {
width: 100%;
height: 150rpx;
}
.hf-btn {
margin: 60rpx 55rpx;
}
.price-ul {
position: absolute;
top: 100rpx;
right: 24rpx;
background-color: #fff;
box-shadow: 2px 2px 5px #ddd;
z-index: 2;
border-radius: 2rpx;
display: none;
}
.price-ul.show {
display: block;
}
.price-ul .price-li {
padding: 25rpx 40rpx;
text-align: center;
font-size: 32rpx;
}
.price-ul .price-li.active {
color: #0d84d1;
}
.hf-btn .icon {
margin-right: 8rpx;
font-size: 32rpx;
}
.upload-view{
margin:20rpx 0;
}
.upload-view .upload{
height:220rpx;
width:220rpx;
background-color: #F0F6FA;
color:#8A9299;
font-size: 24rpx;
}
.upload-view .upload .icon{
font-size: 80rpx;
margin-bottom:20rpx;
}
.upload-view .text{
color:#ADB6BF;
font-size: 22rpx;
margin-top:25rpx;
}
\ No newline at end of file
import StropheAll from "./libs/strophe";
let WebIM = {};
let Strophe = StropheAll.Strophe;
Strophe.log = function (level, msg) {
// console.log(ts(), level, msg);
};
let xmldom = require("./libs/xmldom/dom-parser");
// //console.log('xml',xmldom, typeof xmldom.DOMParser);
let DOMParser = xmldom.DOMParser;
let window = {};
let _version = "1.1.3";
let _code = require("./status").code;
let _utils = require("./utils").utils;
let _msg = require("./message");
let _message = _msg._msg;
let _msgHash = {};
let Queue = require("./queue").Queue;
let location = window.location || {
protocol: "https:"
};
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
if (window.XDomainRequest) {
XDomainRequest.prototype.oldsend = XDomainRequest.prototype.send;
XDomainRequest.prototype.send = function () {
XDomainRequest.prototype.oldsend.apply(this, arguments);
this.readyState = 2;
};
}
Strophe.Request.prototype._newXHR = function () {
var xhr = _utils.xmlrequest(true);
if (xhr.overrideMimeType) {
xhr.overrideMimeType("text/xml");
}
// use Function.bind() to prepend ourselves as an argument
xhr.onreadystatechange = this.func.bind(null, this);
return xhr;
};
Strophe.Websocket.prototype._onSocketClose = function (e) {
// if(e.code && e.code == 1000){
//
// }
// else{
// reOpenEntry();
// }
};
/**
*
* Strophe.Websocket has a bug while logout:
* 1.send: <presence xmlns='jabber:client' type='unavailable'/> is ok;
* 2.send: <close xmlns='urn:ietf:params:xml:ns:xmpp-framing'/> will cause a problem,log as follows:
* WebSocket connection to 'ws://im-api.easemob.com/ws/' failed: Data frame received after close_connect @ strophe.js:5292connect @ strophe.js:2491_login @ websdk-1.1.2.js:278suc @ websdk-1.1.2.js:636xhr.onreadystatechange @ websdk-1.1.2.js:2582
* 3 "Websocket error [object Event]"
* _changeConnectStatus
* onError Object {type: 7, msg: "The WebSocket connection could not be established or was disconnected.", reconnect: true}
*
* this will trigger socket.onError, therefore _doDisconnect again.
* Fix it by overide _onMessage
*/
Strophe.Websocket.prototype._onMessage = function (message) {
var elem, data;
// WebIM && WebIM.config.isDebug && //console.log(WebIM.utils.ts() + 'recv:', message.data);
try {
if (WebIM && WebIM.config.isDebug) {
console.group("%crecv # ", "color: green; font-size: large");
console.log("%c" + message.data, "color: green");
console.groupEnd();
}
} catch (e) {
// console.log('%crecv' + message.data, 'color: green');
}
// check for closing stream
// var close = '<close xmlns="urn:ietf:params:xml:ns:xmpp-framing" />';
// if (message.data === close) {
// this._conn.rawInput(close);
// this._conn.xmlInput(message);
// if (!this._conn.disconnecting) {
// this._conn._doDisconnect();
// }
// return;
//
// send and receive close xml: <close xmlns='urn:ietf:params:xml:ns:xmpp-framing'/>
// so we can't judge whether message.data equals close by === simply.
// console.log('DOMParser connection')
if (message.data.indexOf("<close ") === 0) {
elem = new DOMParser().parseFromString(message.data, "text/xml").documentElement;
let see_uri = elem.getAttribute("see-other-uri");
if (see_uri) {
this._conn._changeConnectStatus(Strophe.Status.REDIRECT, "Received see-other-uri, resetting connection");
this._conn.reset();
this._conn.service = see_uri;
this._connect();
} else {
// if (!this._conn.disconnecting) {
this._conn._doDisconnect("receive <close> from server");
// }
}
return;
} else if (message.data.search("<open ") === 0) {
// This handles stream restarts
elem = new DOMParser().parseFromString(message.data, "text/xml").documentElement;
if (!this._handleStreamStart(elem)) {
return;
}
} else {
data = this._streamWrap(message.data);
elem = new DOMParser().parseFromString(data, "text/xml").documentElement;
}
// console.log('DOMParser connection ed')
if (this._check_streamerror(elem, Strophe.Status.ERROR)) {
return;
}
// handle unavailable presence stanza before disconnecting
if (this._conn.disconnecting &&
elem.firstChild.nodeName === "presence" &&
elem.firstChild.getAttribute("type") === "unavailable"
) {
this._conn.xmlInput(elem);
this._conn.rawInput(Strophe.serialize(elem));
// if we are already disconnecting we will ignore the unavailable stanza and
// wait for the </stream:stream> tag before we close the connection
return;
}
this._conn._dataRecv(elem, message.data);
};
function _listenNetwork(onlineCallback, offlineCallback) {
if (window.addEventListener) {
window.addEventListener("online", onlineCallback);
window.addEventListener("offline", offlineCallback);
} else if (window.attachEvent) {
if (document.body) {
document.body.attachEvent("ononline", onlineCallback);
document.body.attachEvent("onoffline", offlineCallback);
} else {
window.attachEvent("load", function () {
document.body.attachEvent("ononline", onlineCallback);
document.body.attachEvent("onoffline", offlineCallback);
});
}
} else {
/* var onlineTmp = window.ononline;
var offlineTmp = window.onoffline;
window.attachEvent('ononline', function () {
try {
typeof onlineTmp === 'function' && onlineTmp();
} catch ( e ) {}
onlineCallback();
});
window.attachEvent('onoffline', function () {
try {
typeof offlineTmp === 'function' && offlineTmp();
} catch ( e ) {}
offlineCallback();
});*/
}
}
function _parseRoom(result) {
var rooms = [];
var items = result.getElementsByTagName("item");
if (items) {
for (let i = 0; i < items.length; i++) {
let item = items[i];
let roomJid = item.getAttribute("jid");
let tmp = roomJid.split("@")[0];
let room = {
jid: roomJid,
name: item.getAttribute("name"),
roomId: tmp.split("_")[1]
};
rooms.push(room);
}
}
return rooms;
}
function _parseRoomOccupants(result) {
var occupants = [];
var items = result.getElementsByTagName("item");
if (items) {
for (let i = 0; i < items.length; i++) {
let item = items[i];
let room = {
jid: item.getAttribute("jid"),
name: item.getAttribute("name")
};
occupants.push(room);
}
}
return occupants;
}
function _parseResponseMessage(msginfo) {
var parseMsgData = {
errorMsg: true,
data: []
};
// //console.log('msginfo', msginfo)
var msgBodies = msginfo.getElementsByTagName("body");
// //console.log('msginfo', msgBodies)
if (msgBodies) {
for (let i = 0; i < msgBodies.length; i++) {
let msgBody = msgBodies[i];
let childNodes = msgBody.childNodes;
if (childNodes && childNodes.length > 0) {
let childNode = msgBody.childNodes[0];
if (childNode.nodeType == Strophe.ElementType.TEXT) {
let jsondata = childNode.wholeText || childNode.nodeValue;
jsondata = jsondata.replace("\n", "<br>");
try {
let data = JSON.parse(jsondata);
parseMsgData.errorMsg = false;
parseMsgData.data = [data];
} catch (e) {}
}
}
}
let delayTags = msginfo.getElementsByTagName("delay");
if (delayTags && delayTags.length > 0) {
let delayTag = delayTags[0];
let delayMsgTime = delayTag.getAttribute("stamp");
if (delayMsgTime) {
parseMsgData.delayTimeStamp = delayMsgTime;
}
}
} else {
let childrens = msginfo.childNodes;
if (childrens && childrens.length > 0) {
let child = msginfo.childNodes[0];
if (child.nodeType == Strophe.ElementType.TEXT) {
try {
let data = eval("(" + child.nodeValue + ")");
parseMsgData.errorMsg = false;
parseMsgData.data = [data];
} catch (e) {}
}
}
}
return parseMsgData;
}
function _parseNameFromJidFn(jid, domain) {
var tempstr = jid;
var findex = tempstr.indexOf("_");
domain = domain || "";
if (findex !== -1) {
tempstr = tempstr.substring(findex + 1);
}
let atindex = tempstr.indexOf("@" + domain);
if (atindex !== -1) {
tempstr = tempstr.substring(0, atindex);
}
return tempstr;
}
function _parseFriend(queryTag, conn, from) {
var rouster = [];
var items = queryTag.getElementsByTagName("item");
if (items) {
for (let i = 0; i < items.length; i++) {
let groups = [];
let item = items[i];
let jid = item.getAttribute("jid");
if (!jid) {
continue;
}
let subscription = item.getAttribute("subscription");
let friend = {
subscription: subscription,
jid: jid
};
let ask = item.getAttribute("ask");
if (ask) {
friend.ask = ask;
}
let name = item.getAttribute("name");
if (name) {
friend.name = name;
} else {
friend.name = _parseNameFromJidFn(jid);
}
Strophe.forEachChild(item, "group", function (group) {
groups.push(Strophe.getText(group));
});
friend.groups = groups;
rouster.push(friend);
// B 同意之后 -> B 订阅 A
if (conn && (subscription == "from")) {
conn.subscribe({
toJid: jid
});
}
if (conn && (subscription == "to")) {
conn.subscribed({
toJid: jid
});
}
}
}
return rouster;
}
var _parseMessageType = function (msginfo) {
var receiveinfo = msginfo.getElementsByTagName('received'),
inviteinfo = msginfo.getElementsByTagName('invite'),
deliveryinfo = msginfo.getElementsByTagName('delivery'),
acked = msginfo.getElementsByTagName('acked'),
error = msginfo.getElementsByTagName('error'),
msgtype = 'normal';
if (receiveinfo && receiveinfo.length > 0 && receiveinfo[0].namespaceURI === 'urn:xmpp:receipts') {
msgtype = 'received';
} else if (inviteinfo && inviteinfo.length > 0) {
msgtype = 'invite';
} else if (deliveryinfo && deliveryinfo.length > 0) {
msgtype = 'delivery'; // 消息送达
} else if (acked && acked.length) {
msgtype = 'acked'; // 消息已读
} else if (error && error.length) {
var errorItem = error[0],
userMuted = errorItem.getElementsByTagName('user-muted');
if (userMuted && userMuted.length) {
msgtype = 'userMuted';
}
}
return msgtype;
};
// function _parseMessageType(msginfo) {
// var msgtype = "normal";
// var receiveinfo = msginfo.getElementsByTagName("received");
// if (receiveinfo && receiveinfo.length > 0 && receiveinfo[0].namespaceURI === "urn:xmpp:receipts") {
// msgtype = "received";
// } else {
// let inviteinfo = msginfo.getElementsByTagName("invite");
// if (inviteinfo && inviteinfo.length > 0) {
// msgtype = "invite";
// }
// }
// return msgtype;
// }
function _handleMessageQueue(conn) {
for (let i in _msgHash) {
if (Object.hasOwnProperty.call(_msgHash, i)) {
_msgHash[i].send(conn);
}
}
}
function _loginCallback(status, msg, conn) {
var error;
var conflict = msg === "conflict";
if (status == Strophe.Status.CONNFAIL) {
// client offline, ping/pong timeout, server quit, server offline
error = {
type: _code.WEBIM_CONNCTION_SERVER_CLOSE_ERROR, // 客户端网络离线
msg: msg
};
conflict && (error.conflict = true);
conn.onError(error);
} else if (status == Strophe.Status.ATTACHED || status == Strophe.Status.CONNECTED) {
conn.autoReconnectNumTotal = 0;
// client should limit the speed of sending ack messages up to 5/s
conn.intervalId = setInterval(function () {
conn.handelSendQueue();
}, 200);
let handleMessage = function (msginfo) {
var type = _parseMessageType(msginfo);
if (type === "received") {
conn.handleReceivedMessage(msginfo);
return true;
} else if (type === "invite") {
conn.handleInviteMessage(msginfo);
return true;
} else if(type === "acked") {
conn.handleReadMessage(msginfo);
return true;
}
conn.handleMessage(msginfo);
return true;
};
let handlePresence = function (msginfo) {
conn.handlePresence(msginfo);
return true;
};
// let handlePing = function(msginfo){
// conn.handlePing(msginfo);
// return true;
// };
let handleIqRoster = function (msginfo) {
conn.handleIqRoster(msginfo);
return true;
};
let handleIqPrivacy = function (msginfo) {
conn.handleIqPrivacy(msginfo);
return true;
};
let handleIq = function (msginfo) {
conn.handleIq(msginfo);
return true;
};
conn.addHandler(handleMessage, null, "message", null, null, null);
conn.addHandler(handlePresence, null, "presence", null, null, null);
// conn.addHandler(handlePing, "urn:xmpp:ping", "iq", "get", null, null);
conn.addHandler(handleIqRoster, "jabber:iq:roster", "iq", "set", null, null);
conn.addHandler(handleIqPrivacy, "jabber:iq:privacy", "iq", "set", null, null);
conn.addHandler(handleIq, null, "iq", null, null, null);
conn.context.status = _code.STATUS_OPENED;
let supportRecMessage = [
_code.WEBIM_MESSAGE_REC_TEXT,
_code.WEBIM_MESSAGE_REC_EMOJI
];
let supportSedMessage = [
_code.WEBIM_MESSAGE_SED_TEXT
];
if (_utils.isCanDownLoadFile) {
supportRecMessage.push(_code.WEBIM_MESSAGE_REC_PHOTO);
supportRecMessage.push(_code.WEBIM_MESSAGE_REC_AUDIO_FILE);
}
if (_utils.isCanUploadFile) {
supportSedMessage.push(_code.WEBIM_MESSAGE_REC_PHOTO);
supportSedMessage.push(_code.WEBIM_MESSAGE_REC_AUDIO_FILE);
}
conn.notifyVersion();
conn.retry && _handleMessageQueue(conn);
conn.heartBeat();
conn.isAutoLogin && conn.setPresence();
conn.onOpened({
canReceive: supportRecMessage,
canSend: supportSedMessage,
accessToken: conn.context.accessToken
});
conn.onSocketConnected()
} else if (status == Strophe.Status.DISCONNECTING) {
if (conn.isOpened()) {
if(conn.autoReconnectNumTotal < conn.autoReconnectNumMax){
if (conn.autoReconnectNumTotal == 0) {conn.onReconnect()}
conn.reconnect();
return;
} else if(conn.autoReconnectNumTotal == conn.autoReconnectNumMax){
console.log("Err 3")
error = {
type: _code.WEBIM_CONNCTION_DISCONNECTED
};
conn.onError(error);
conn.context.status = _code.STATUS_CLOSED;
conn.clear();
conn.onClosed();
}
conn.stopHeartBeat();
// error = {
// type: _code.WEBIM_CONNCTION_SERVER_CLOSE_ERROR,
// msg: msg
// };
// conflict && (error.conflict = true);
// conn.onError(error);
}
conn.context.status = _code.STATUS_CLOSING;
} else if (status == Strophe.Status.DISCONNECTED) {
if (conn.isOpened()) {
if(conn.autoReconnectNumTotal < conn.autoReconnectNumMax){
if (conn.autoReconnectNumTotal == 0) {conn.onReconnect()}
conn.reconnect();
return;
} else if (conn.autoReconnectNumTotal == conn.autoReconnectNumMax) {
conn.context.status = _code.STATUS_CLOSED;
conn.clear();
conn.onClosed();
conn.stopHeartBeat();
}
console.log("Err 4")
error = {
type: _code.WEBIM_CONNCTION_DISCONNECTED
};
conn.onError(error);
}
conn.context.status = _code.STATUS_CLOSED;
} else if (status == Strophe.Status.AUTHFAIL) {
error = {
type: _code.WEBIM_CONNCTION_AUTH_ERROR
};
conflict && (error.conflict = true);
conn.onError(error);
conn.clear();
conn.stopHeartBeat();
wx.closeSocket();
} else if (status == Strophe.Status.ERROR) {
conn.context.status = _code.STATUS_ERROR;
error = {
type: _code.WEBIM_CONNCTION_SERVER_ERROR
};
conflict && (error.conflict = true);
conn.onError(error);
conn.stopHeartBeat();
}
}
function _login(options, conn) {
var stropheConn = null;
var accessToken = options.access_token || "";
if (accessToken == "") {
conn.onError({
type: _code.WEBIM_CONNCTION_OPEN_USERGRID_ERROR,
data: options
});
return;
}
conn.context.accessToken = options.access_token;
conn.context.accessTokenExpires = options.expires_in;
stropheConn = new Strophe.Connection(conn.url, {
inactivity: conn.inactivity,
maxRetries: conn.maxRetries,
pollingTime: conn.pollingTime});
conn.context.stropheConn = stropheConn;
if (conn.route) {
stropheConn.connect(conn.context.jid, "$t$" + accessToken, callback, conn.wait, conn.hold, conn.route);
} else {
stropheConn.connect(conn.context.jid, "$t$" + accessToken, callback, conn.wait, conn.hold);
}
function callback(status, msg) {
console.log("connection stat change", status, msg);
_loginCallback(status, msg, conn);
}
}
function _getJid(options, conn) {
var jid = options.toJid || "";
if (jid === "") {
let appKey = conn.context.appKey || "";
let toJid = appKey + "_" + options.to + "@" + conn.domain;
if (options.resource) {
toJid = toJid + "/" + options.resource;
}
jid = toJid;
}
return jid;
}
function _getJidByName(name, conn) {
return _getJid({
to: name
}, conn);
}
function _validCheck(options, conn) {
options = options || {};
if (options.user == "") {
conn.onError({
type: _code.WEBIM_CONNCTION_USER_NOT_ASSIGN_ERROR
});
return false;
}
let user = (options.user + "") || "";
let appKey = options.appKey || "";
let devInfos = appKey.split("#");
if (devInfos.length !== 2) {
conn.onError({
type: _code.WEBIM_CONNCTION_APPKEY_NOT_ASSIGN_ERROR
});
return false;
}
let orgName = devInfos[0];
let appName = devInfos[1];
if (!orgName) {
conn.onError({
type: _code.WEBIM_CONNCTION_APPKEY_NOT_ASSIGN_ERROR
});
return false;
}
if (!appName) {
conn.onError({
type: _code.WEBIM_CONNCTION_APPKEY_NOT_ASSIGN_ERROR
});
return false;
}
let jid = appKey + "_" + user.toLowerCase() + "@" + conn.domain;
let resource = options.resource || "webim";
if (conn.isMultiLoginSessions) {
resource += user + new Date().getTime() + Math.floor(Math.random().toFixed(6) * 1000000);
}
conn.context.jid = jid + "/" + resource;
/* jid: {appkey}_{username}@domain/resource*/
conn.context.userId = user;
conn.context.appKey = appKey;
conn.context.appName = appName;
conn.context.orgName = orgName;
return true;
}
function _getXmppUrl(baseUrl, https) {
if (/^(ws|http)s?:\/\/?/.test(baseUrl)) {
return baseUrl;
}
let url = {
prefix: "http",
base: "://" + baseUrl,
suffix: "/http-bind/"
};
if (https && _utils.isSupportWss) {
url.prefix = "wss";
url.suffix = "/ws/";
} else if (https) {
url.prefix = "https";
} else if (window.WebSocket) {
url.prefix = "ws";
url.suffix = "/ws/";
}
return url.prefix + url.base + url.suffix;
}
// CLASS
function connection(options) {
if (!(this instanceof connection)) {
return new connection(options);
}
options = options || {};
this.isMultiLoginSessions = options.isMultiLoginSessions || false;
this.wait = options.wait || 30;
this.retry = options.retry || false;
this.https = options.https || location.protocol === "https:";
this.url = _getXmppUrl(options.url, this.https);
this.hold = options.hold || 1;
this.route = options.route || null;
this.domain = options.domain || "easemob.com";
this.inactivity = options.inactivity || 30;
this.heartBeatWait = options.heartBeatWait || 4500;
this.maxRetries = options.maxRetries || 5;
this.isAutoLogin = options.isAutoLogin !== false;
this.pollingTime = options.pollingTime || 800;
this.stropheConn = false;
this.autoReconnectNumMax = options.autoReconnectNumMax || 0;
this.autoReconnectNumTotal = 0;
this.autoReconnectInterval = options.autoReconnectInterval || 0;
this.context = {
status: _code.STATUS_INIT
};
this.apiUrl = options.apiUrl || "";
// todo 接收的事件,放到数组里的时候,加上g.isInBackground字段。每帧执行一个事件的时候,如果g.isInBackground=true,就pass
this.sendQueue = new Queue(); // 接收到的事件队列
this.intervalId = null;
this.orgName = "";
this.appName = "";
this.token = "";
}
connection.prototype.handelSendQueue = function () {
var options = this.sendQueue.pop();
if (options !== null) {
this.sendReceiptsMessage(options);
}
};
connection.prototype.listen = function (options) {
options.url && (this.url = _getXmppUrl(options.url, this.https));
this.onOpened = options.onOpened || _utils.emptyfn;
this.onClosed = options.onClosed || _utils.emptyfn;
this.onReconnect = options.onReconnect || _utils.emptyfn;
this.onSocketConnected = options.onSocketConnected || _utils.emptyfn;
this.onReadMessage = options.onReadMessage || _utils.emptyfn;
this.onTextMessage = options.onTextMessage || _utils.emptyfn;
this.onEmojiMessage = options.onEmojiMessage || _utils.emptyfn;
this.onPictureMessage = options.onPictureMessage || _utils.emptyfn;
this.onAudioMessage = options.onAudioMessage || _utils.emptyfn;
this.onVideoMessage = options.onVideoMessage || _utils.emptyfn;
this.onFileMessage = options.onFileMessage || _utils.emptyfn;
this.onLocationMessage = options.onLocationMessage || _utils.emptyfn;
this.onCmdMessage = options.onCmdMessage || _utils.emptyfn;
this.onPresence = options.onPresence || _utils.emptyfn;
this.onRoster = options.onRoster || _utils.emptyfn;
this.onError = options.onError || _utils.emptyfn;
this.onReceivedMessage = options.onReceivedMessage || _utils.emptyfn;
this.onInviteMessage = options.onInviteMessage || _utils.emptyfn;
this.onOffline = options.onOffline || _utils.emptyfn;
this.onOnline = options.onOnline || _utils.emptyfn;
this.onConfirmPop = options.onConfirmPop || _utils.emptyfn;
this.onCreateGroup = options.onCreateGroup || _utils.emptyfn;
// for WindowSDK
this.onUpdateMyGroupList = options.onUpdateMyGroupList || _utils.emptyfn;
this.onUpdateMyRoster = options.onUpdateMyRoster || _utils.emptyfn;
//
this.onBlacklistUpdate = options.onBlacklistUpdate || _utils.emptyfn;
_listenNetwork(this.onOnline, this.onOffline);
};
connection.prototype.heartBeatID = 0;
connection.prototype.heartBeat = function () {
var me = this;
// // IE8: strophe auto switch from ws to BOSH, need heartbeat
// var isNeed = !/^ws|wss/.test(me.url);
// // || /mobile/.test(navigator.userAgent)
// if(this.heartBeatID || !isNeed){
// return;
// }
this.stopHeartBeat();
this.heartBeatID = setInterval(function () {
me.ping({
toJid: me.domain,
type: "normal"
});
}, this.heartBeatWait);
};
connection.prototype.stopHeartBeat = function () {
clearInterval(this.heartBeatID);
};
connection.prototype.sendReceiptsMessage = function (options) {
var dom = StropheAll.$msg({
from: this.context.jid || "",
to: this.domain,
id: options.id || ""
}).c("received", {
xmlns: "urn:xmpp:receipts",
id: options.id || ""
});
this.sendCommand(dom.tree());
};
connection.prototype.cacheReceiptsMessage = function (options) {
this.sendQueue.push(options);
};
connection.prototype.open = function (options) {
let me = this;
console.log("open", this.isOpening());
// 防止重复初始化
if (this.isOpening() || this.isOpened()) {
console.log("can't open [1]");
return;
}
if (!_validCheck(options, this)) {
console.log("can't open [2]");
return;
}
if (options.accessToken) {
options.access_token = options.accessToken;
this.token = options.access_token;
_login(options, me);
} else {
let apiUrl = options.apiUrl;
let userId = options.user;
let pwd = options.pwd || "";
let appkey = options.appKey;
let str = appkey.split("#");
let orgName = str[0];
let appName = str[1];
this.orgName = orgName;
this.appName = appName;
this.context.status = _code.STATUS_DOLOGIN_USERGRID;
let loginJson = {
grant_type: "password",
username: userId,
password: pwd,
timestamp: +new Date()
};
let loginfo = _utils.stringify(loginJson);
_utils.ajax({
url: apiUrl + "/" + orgName + "/" + appName + "/token",
data: loginfo,
success: suc || _utils.emptyfn,
error: error || _utils.emptyfn
});
}
function suc(data, xhr, myName) {
me.context.status = _code.STATUS_DOLOGIN_IM;
me.context.restTokenData = data;
if (data.statusCode != "404" && data.statusCode != "400") {
// data:
// access_token,
// expires_in,
// user:
// activated,
// created,
// modified,
// nickname,
// type,
// username,
// uuid,
_login(data.data, me);
} else {
error({});
}
}
function error(res, xhr, msg) {
me.clear();
if (res.error && res.error_description) {
me.onError({
type: _code.WEBIM_CONNCTION_OPEN_USERGRID_ERROR,
data: res,
xhr: xhr
});
} else {
me.onError({
type: _code.WEBIM_CONNCTION_OPEN_ERROR,
data: res,
xhr: xhr
});
}
}
// reOpenEntry = function(){
// me.open(options);
// };
};
// attach to xmpp server for BOSH
connection.prototype.attach = function (options) {
var me = this;
var pass = _validCheck(options, this);
if (!pass) {
return;
}
options = options || {};
let accessToken = options.accessToken || "";
if (accessToken == "") {
this.onError({
type: _code.WEBIM_CONNCTION_TOKEN_NOT_ASSIGN_ERROR
});
return;
}
let sid = options.sid || "";
if (sid === "") {
this.onError({
type: _code.WEBIM_CONNCTION_SESSIONID_NOT_ASSIGN_ERROR
});
return;
}
let rid = options.rid || "";
if (rid === "") {
this.onError({
type: _code.WEBIM_CONNCTION_RID_NOT_ASSIGN_ERROR
});
return;
}
let stropheConn = new Strophe.Connection(this.url, {
inactivity: this.inactivity,
maxRetries: this.maxRetries,
pollingTime: this.pollingTime,
heartBeatWait: this.heartBeatWait
});
this.context.accessToken = accessToken;
this.context.stropheConn = stropheConn;
this.context.status = _code.STATUS_DOLOGIN_IM;
let callback = function (status, msg) {
_loginCallback(status, msg, me);
};
let jid = this.context.jid;
let wait = this.wait;
let hold = this.hold;
let wind = this.wind || 5;
stropheConn.attach(jid, sid, rid, callback, wait, hold, wind);
};
connection.prototype.close = function (reason) {
this.stopHeartBeat();
let status = this.context.status;
if (status == _code.STATUS_INIT) {
return;
}
if (this.isClosed() || this.isClosing()) {
return;
}
this.context.status = _code.STATUS_CLOSING;
this.context.stropheConn.disconnect(reason);
};
connection.prototype.addHandler = function (handler, ns, name, type, id, from, options) {
this.context.stropheConn.addHandler(handler, ns, name, type, id, from, options);
};
connection.prototype.notifyVersion = function (suc, fail) {
var dom = StropheAll.$iq({
from: this.context.jid || "",
to: this.domain,
type: "result"
})
.c("query", {
xmlns: "jabber:iq:version"
})
.c("name")
.t("easemob")
.up()
.c("version")
.t(_version)
.up()
.c("os")
.t("webim");
suc = suc || _utils.emptyfn;
let error = fail || this.onError;
let failFn = function (ele) {
error({
type: _code.WEBIM_CONNCTION_NOTIFYVERSION_ERROR,
data: ele
});
};
this.context.stropheConn.sendIQ(dom.tree(), suc, failFn);
};
// handle all types of presence message
connection.prototype.handlePresence = function (msginfo) {
if (this.isClosed()) {
return;
}
let from = msginfo.getAttribute("from") || "";
let to = msginfo.getAttribute("to") || "";
let type = msginfo.getAttribute("type") || "";
let presence_type = msginfo.getAttribute("presence_type") || "";
let fromUser = _parseNameFromJidFn(from);
let toUser = _parseNameFromJidFn(to);
let isCreate = false;
let isMemberJoin = false;
let isDecline = false;
let isApply = false;
let info = {
from: fromUser,
to: toUser,
fromJid: from,
toJid: to,
type: type,
chatroom: !!msginfo.getElementsByTagName("roomtype").length
};
let showTags = msginfo.getElementsByTagName("show");
if (showTags && showTags.length > 0) {
let showTag = showTags[0];
info.show = Strophe.getText(showTag);
}
let statusTags = msginfo.getElementsByTagName("status");
if (statusTags && statusTags.length > 0) {
let statusTag = statusTags[0];
info.status = Strophe.getText(statusTag);
info.code = statusTag.getAttribute("code");
}
let priorityTags = msginfo.getElementsByTagName("priority");
if (priorityTags && priorityTags.length > 0) {
let priorityTag = priorityTags[0];
info.priority = Strophe.getText(priorityTag);
}
let error = msginfo.getElementsByTagName("error");
if (error && error.length > 0) {
error = error[0];
info.error = {
code: error.getAttribute("code")
};
}
let destroy = msginfo.getElementsByTagName("destroy");
if (destroy && destroy.length > 0) {
destroy = destroy[0];
info.destroy = true;
let reason = destroy.getElementsByTagName("reason");
if (reason && reason.length > 0) {
info.reason = Strophe.getText(reason[0]);
}
}
let members = msginfo.getElementsByTagName("item");
if (members && members.length > 0) {
let member = members[0];
let role = member.getAttribute("role");
let jid = member.getAttribute("jid");
let affiliation = member.getAttribute("affiliation");
// dismissed by group
if (role == "none" && jid) {
let kickedMember = _parseNameFromJidFn(jid);
let actor = member.getElementsByTagName("actor")[0];
let actorNick = actor.getAttribute("nick");
info.actor = actorNick;
info.kicked = kickedMember;
}
// Service Acknowledges Room Creation `createGroupACK`
if (role == "moderator" && info.code == "201") {
if (affiliation === "owner") {
info.type = "createGroupACK";
isCreate = true;
}
// else
// info.type = 'joinPublicGroupSuccess';
}
}
let x = msginfo.getElementsByTagName("x");
if (x && x.length > 0) {
// 加群申请
let apply = x[0].getElementsByTagName("apply");
// 加群成功
let accept = x[0].getElementsByTagName("accept");
// 同意加群后用户进群通知
let item = x[0].getElementsByTagName("item");
// 加群被拒绝
let decline = x[0].getElementsByTagName("decline");
// 被设为管理员
let addAdmin = x[0].getElementsByTagName("add_admin");
// 被取消管理员
let removeAdmin = x[0].getElementsByTagName("remove_admin");
// 被禁言
let addMute = x[0].getElementsByTagName("add_mute");
// 取消禁言
let removeMute = x[0].getElementsByTagName("remove_mute");
if (apply && apply.length > 0) {
isApply = true;
info.toNick = apply[0].getAttribute("toNick");
info.type = "joinGroupNotifications";
let groupJid = apply[0].getAttribute("to");
let gid = groupJid.split("@")[0].split("_");
gid = gid[gid.length - 1];
info.gid = gid;
} else if (accept && accept.length > 0) {
info.type = "joinPublicGroupSuccess";
} else if (item && item.length > 0) {
let affiliation = item[0].getAttribute("affiliation");
let role = item[0].getAttribute("role");
if (affiliation == "member" || role == "participant") {
isMemberJoin = true;
info.mid = info.fromJid.split("/");
info.mid = info.mid[info.mid.length - 1];
info.type = "memberJoinPublicGroupSuccess";
let roomtype = msginfo.getElementsByTagName("roomtype");
if (roomtype && roomtype.length > 0) {
let type = roomtype[0].getAttribute("type");
if (type == "chatroom") {
info.type = "memberJoinChatRoomSuccess";
}
}
} else if (affiliation == "none" || role == "none") {
let roomtype = msginfo.getElementsByTagName("roomtype");
if (roomtype && roomtype.length > 0) {
let type = roomtype[0].getAttribute("type");
if (type == "chatroom") {
info.type = "memberLeaveChatRoomSuccess";
}
}
}
} else if (decline && decline.length) {
isDecline = true;
let gid = decline[0].getAttribute("fromNick");
let owner = _parseNameFromJidFn(decline[0].getAttribute("from"));
info.type = "joinPublicGroupDeclined";
info.owner = owner;
info.gid = gid;
} else if (addAdmin && addAdmin.length > 0) {
let gid = _parseNameFromJidFn(addAdmin[0].getAttribute("mucjid"));
let owner = _parseNameFromJidFn(addAdmin[0].getAttribute("from"));
info.owner = owner;
info.gid = gid;
info.type = "addAdmin";
} else if (removeAdmin && removeAdmin.length > 0) {
let gid = _parseNameFromJidFn(removeAdmin[0].getAttribute("mucjid"));
let owner = _parseNameFromJidFn(removeAdmin[0].getAttribute("from"));
info.owner = owner;
info.gid = gid;
info.type = "removeAdmin";
} else if (addMute && addMute.length > 0) {
let gid = _parseNameFromJidFn(addMute[0].getAttribute("mucjid"));
let owner = _parseNameFromJidFn(addMute[0].getAttribute("from"));
info.owner = owner;
info.gid = gid;
info.type = "addMute";
} else if (removeMute && removeMute.length > 0) {
let gid = _parseNameFromJidFn(removeMute[0].getAttribute("mucjid"));
let owner = _parseNameFromJidFn(removeMute[0].getAttribute("from"));
info.owner = owner;
info.gid = gid;
info.type = "removeMute";
}
}
if (info.chatroom) {
info.presence_type = presence_type;
info.original_type = info.type;
let reflectUser = from.slice(from.lastIndexOf("/") + 1);
if (reflectUser === this.context.userId) {
if (info.type === "" && !info.code) {
info.type = "joinChatRoomSuccess";
} else if (presence_type === "unavailable" || info.type === "unavailable") {
// logout successfully.
if (!info.status) {
info.type = "leaveChatRoom";
}
// logout or dismissied by admin
else if (info.code == 110) {
info.type = "leaveChatRoom";
}
// The chat room is full
else if (info.error && info.error.code == 406) {
info.type = "reachChatRoomCapacity";
}
}
}
} else {
info.presence_type = presence_type;
info.original_type = type;
if (/subscribe/.test(info.type)) {
// subscribe | subscribed | unsubscribe | unsubscribed
} else if (type == "" &&
!info.status &&
!info.error &&
!isCreate &&
!isApply &&
!isMemberJoin &&
!isDecline
) {
// info.type = 'joinPublicGroupSuccess';
}
// There is no roomtype when a chat room is deleted.
else if (presence_type === "unavailable" || type === "unavailable") {
// Group or Chat room Deleted.
if (info.destroy) {
info.type = "deleteGroupChat";
}
// Dismissed by group.
else if (info.code == 307 || info.code == 321) {
let nick = msginfo.getAttribute("nick");
if (!nick) {
info.type = "leaveGroup";
} else {
info.type = "removedFromGroup";
}
}
}
}
//自己加自己
if (info.type == 'subscribe' && info.from == info.to) {
return
}
this.onPresence(info, msginfo);
};
// connection.prototype.handlePing = function(e){
// if(this.isClosed()){
// return;
// }
// let id = e.getAttribute("id");
// let from = e.getAttribute("from");
// let to = e.getAttribute("to");
// let dom = $iq({
// from: to, to: from, id: id, type: "result"
// });
// this.sendCommand(dom.tree());
// };
connection.prototype.handleIq = function (iq) {
return true;
};
connection.prototype.handleIqPrivacy = function (msginfo) {
var list = msginfo.getElementsByTagName("list");
if (list.length == 0) {
return;
}
this.getBlacklist();
};
connection.prototype.handleIqRoster = function (e) {
var id = e.getAttribute("id");
var from = e.getAttribute("from") || "";
// var name = _parseNameFromJidFn(from);
var curJid = this.context.jid;
// var curUser = this.context.userId;
var iqresult = StropheAll.$iq({
type: "result",
id: id,
from: curJid
});
this.sendCommand(iqresult.tree());
let msgBodies = e.getElementsByTagName("query");
if (msgBodies && msgBodies.length > 0) {
let queryTag = msgBodies[0];
let rouster = _parseFriend(queryTag, this, from);
this.onRoster(rouster);
}
return true;
};
connection.prototype.handleMessage = function (msginfo) {
if (this.isClosed()) {
return;
}
let id = msginfo.getAttribute("id") || "";
// cache ack into sendQueue first, handelSendQueue will do the send thing with the speed of 5/s
this.cacheReceiptsMessage({
id: id
});
// console.log('handlePresence', msginfo)
let parseMsgData = _parseResponseMessage(msginfo);
// console.log('parseMsgData', parseMsgData)
if (parseMsgData.errorMsg) {
this.handlePresence(msginfo);
return;
}
// send error
let error = msginfo.getElementsByTagName("error");
let errorCode = "";
let errorText = "";
let errorBool = false;
if (error.length > 0) {
errorBool = true;
errorCode = error[0].getAttribute("code");
let textDOM = error[0].getElementsByTagName("text");
errorText = textDOM[0].textContent || textDOM[0].text;
// log("handle error", errorCode, errorText);
}
let msgDatas = parseMsgData.data;
for (let i in msgDatas) {
if (!Object.hasOwnProperty.call(msgDatas, i)) {
continue;
}
let msg = msgDatas[i];
if (!msg.from || !msg.to) {
continue;
}
let from = (msg.from + "").toLowerCase();
let too = (msg.to + "").toLowerCase();
let extmsg = msg.ext || {};
let chattype = "";
let typeEl = msginfo.getElementsByTagName("roomtype");
if (typeEl.length) {
chattype = typeEl[0].getAttribute("type") || "chat";
} else {
chattype = msginfo.getAttribute("type") || "chat";
}
let msgBodies = msg.bodies;
if (!msgBodies || msgBodies.length == 0) {
continue;
}
let msgBody = msg.bodies[0];
let type = msgBody.type;
try {
switch (type) {
case "txt":
let receiveMsg = msgBody.msg;
let emojibody = _utils.parseTextMessage(receiveMsg, WebIM.Emoji);
if (emojibody.isemoji) {
let msg = {
id: id,
type: chattype,
from: from,
to: too,
delay: parseMsgData.delayTimeStamp,
data: emojibody.body,
ext: extmsg
};
!msg.delay && delete msg.delay;
msg.error = errorBool;
msg.errorText = errorText;
msg.errorCode = errorCode;
this.onEmojiMessage(msg);
} else {
let msg = {
id: id,
type: chattype,
from: from,
to: too,
delay: parseMsgData.delayTimeStamp,
data: receiveMsg,
ext: extmsg
};
!msg.delay && delete msg.delay;
msg.error = errorBool;
msg.errorText = errorText;
msg.errorCode = errorCode;
this.onTextMessage(msg);
}
break;
case "img":
let rwidth = 0;
let rheight = 0;
if (msgBody.size) {
rwidth = msgBody.size.width;
rheight = msgBody.size.height;
}
let msg = {
id: id,
type: chattype,
from: from,
to: too,
url: msgBody.url,
secret: msgBody.secret,
filename: msgBody.filename,
thumb: msgBody.thumb,
thumb_secret: msgBody.thumb_secret,
file_length: msgBody.file_length || "",
width: rwidth,
height: rheight,
filetype: msgBody.filetype || "",
accessToken: this.context.accessToken || "",
ext: extmsg,
delay: parseMsgData.delayTimeStamp
};
!msg.delay && delete msg.delay;
msg.error = errorBool;
msg.errorText = errorText;
msg.errorCode = errorCode;
this.onPictureMessage(msg);
break;
case "audio":
msg = {
id: id,
type: chattype,
from: from,
to: too,
url: msgBody.url,
secret: msgBody.secret,
filename: msgBody.filename,
length: msgBody.length || "",
file_length: msgBody.file_length || "",
filetype: msgBody.filetype || "",
accessToken: this.context.accessToken || "",
ext: extmsg,
delay: parseMsgData.delayTimeStamp,
};
!msg.delay && delete msg.delay;
msg.error = errorBool;
msg.errorText = errorText;
msg.errorCode = errorCode;
this.onAudioMessage(msg);
break;
case "file":
msg = {
id: id,
type: chattype,
from: from,
to: too,
url: msgBody.url,
secret: msgBody.secret,
filename: msgBody.filename,
file_length: msgBody.file_length,
accessToken: this.context.accessToken || "",
ext: extmsg,
delay: parseMsgData.delayTimeStamp,
};
!msg.delay && delete msg.delay;
msg.error = errorBool;
msg.errorText = errorText;
msg.errorCode = errorCode;
this.onFileMessage(msg);
break;
case "loc":
msg = {
id: id,
type: chattype,
from: from,
to: too,
addr: msgBody.addr,
lat: msgBody.lat,
lng: msgBody.lng,
ext: extmsg,
delay: parseMsgData.delayTimeStamp,
};
!msg.delay && delete msg.delay;
msg.error = errorBool;
msg.errorText = errorText;
msg.errorCode = errorCode;
this.onLocationMessage(msg);
break;
case "video":
msg = {
id: id,
type: chattype,
from: from,
to: too,
url: msgBody.url,
secret: msgBody.secret,
filename: msgBody.filename,
file_length: msgBody.file_length,
accessToken: this.context.accessToken || "",
ext: extmsg,
delay: parseMsgData.delayTimeStamp,
};
!msg.delay && delete msg.delay;
msg.error = errorBool;
msg.errorText = errorText;
msg.errorCode = errorCode;
this.onVideoMessage(msg);
break;
case "cmd":
msg = {
id: id,
from: from,
to: too,
action: msgBody.action,
ext: extmsg,
delay: parseMsgData.delayTimeStamp,
};
!msg.delay && delete msg.delay;
msg.error = errorBool;
msg.errorText = errorText;
msg.errorCode = errorCode;
this.onCmdMessage(msg);
break;
default:
break;
}
} catch (e) {
this.onError({
type: _code.WEBIM_CONNCTION_CALLBACK_INNER_ERROR,
data: e
});
}
}
};
connection.prototype.handleReadMessage = function (message) {
let id = message.getAttribute("id") || "";
var msgBodies = message.getElementsByTagName('body');
var mid = 0;
if (msgBodies) {
let msgBody = msgBodies[0];
let childNodes = msgBody.childNodes;
if (childNodes && childNodes.length > 0) {
let childNode = msgBody.childNodes[0];
if (childNode.nodeType == Strophe.ElementType.TEXT) {
let jsondata = childNode.wholeText || childNode.nodeValue;
jsondata = jsondata.replace("\n", "<br>");
try {
let data = JSON.parse(jsondata);
mid=data
} catch (e) {
console.log(2)
}
}
}
}
var msg = {
mid: mid
};
this.onReadMessage(msg);
this.sendReceiptsMessage({
id: id
});
};
connection.prototype.handleReceivedMessage = function (message) {
try {
this.onReceivedMessage(message);
} catch (e) {
this.onError({
type: _code.WEBIM_CONNCTION_CALLBACK_INNER_ERROR,
data: e
});
}
let rcv = message.getElementsByTagName("received");
let id;
let mid;
if (rcv.length > 0) {
if (rcv[0].childNodes && rcv[0].childNodes.length > 0) {
id = rcv[0].childNodes[0].nodeValue;
} else {
id = rcv[0].innerHTML || rcv[0].innerText;
}
mid = rcv[0].getAttribute("mid");
}
if (_msgHash[id]) {
try {
_msgHash[id].msg.success instanceof Function && _msgHash[id].msg.success(id, mid);
} catch (e) {
this.onError({
type: _code.WEBIM_CONNCTION_CALLBACK_INNER_ERROR,
data: e
});
}
delete _msgHash[id];
}
};
connection.prototype.handleInviteMessage = function (message) {
var form = null;
var invitemsg = message.getElementsByTagName("invite");
var reasonDom = message.getElementsByTagName("reason")[0];
var reasonMsg = reasonDom.textContent;
var id = message.getAttribute("id") || "";
this.sendReceiptsMessage({
id: id
});
if (invitemsg && invitemsg.length > 0) {
let fromJid = invitemsg[0].getAttribute("from");
form = _parseNameFromJidFn(fromJid);
}
let xmsg = message.getElementsByTagName("x");
let roomid = null;
if (xmsg && xmsg.length > 0) {
for (let i = 0; i < xmsg.length; i++) {
if (xmsg[i].namespaceURI === "jabber:x:conference") {
let roomjid = xmsg[i].getAttribute("jid");
roomid = _parseNameFromJidFn(roomjid);
}
}
}
this.onInviteMessage({
type: "invite",
from: form,
roomid: roomid,
reason: reasonMsg
});
};
connection.prototype.sendCommand = function (dom, id) {
var me = this;
if (this.isOpened()) {
var fail = function(reason){
var data = {}
data.mid = id
data.reason = reason
me.onError({
type: 'socket_error',
data: data
})
}
this.context.stropheConn.send(dom, fail);
} else {
console.log("Err 5")
this.onError({
type: _code.WEBIM_CONNCTION_DISCONNECTED
});
}
};
connection.prototype.getUniqueId = function (prefix) {
var cdate = new Date();
var offdate = new Date(2010, 1, 1);
var offset = cdate.getTime() - offdate.getTime();
var hexd = parseInt(offset).toString(16);
if (typeof prefix === "string" || typeof prefix === "number") {
return prefix + "_" + hexd;
}
return "WEBIM_" + hexd;
};
connection.prototype.send = function (message) {
if (WebIM.config.isWindowSDK) {
WebIM.doQuery(
JSON.stringify({
type: "sendMessage",
to: message.to,
message_type: message.type,
msg: encodeURI(message.msg),
chatType: message.chatType,
}),
function (response) {
},
function (code, msg) {
}
);
} else if (Object.prototype.toString.call(message) === "[object Object]") {
let appKey = this.context.appKey || "";
let toJid = appKey + "_" + message.to + "@" + this.domain;
if (message.group) {
toJid = appKey + "_" + message.to + "@conference." + this.domain;
}
if (message.resource) {
toJid = toJid + "/" + message.resource;
}
message.toJid = toJid;
message.id = message.id || this.getUniqueId();
_msgHash[message.id] = new _message(message);
try{
_msgHash[message.id].send(this);
} catch (e) {
console.log('发送失败')
}
} else if (typeof message === "string") {
_msgHash[message] && _msgHash[message].send(this);
}
};
connection.prototype.addRoster = function (options) {
var jid = _getJid(options, this);
var name = options.name || "";
var groups = options.groups || "";
var iq = StropheAll.$iq({
type: "set"
});
iq.c("query", {
xmlns: "jabber:iq:roster"
});
iq.c("item", {
jid: jid,
name: name
});
if (groups) {
for (let i = 0; i < groups.length; i++) {
iq.c("group").t(groups[i]).up();
}
}
let suc = options.success || _utils.emptyfn;
let error = options.error || _utils.emptyfn;
this.context.stropheConn.sendIQ(iq.tree(), suc, error);
};
connection.prototype.removeRoster = function (options) {
var jid = _getJid(options, this);
var iq = StropheAll
.$iq({
type: "set"
})
.c("query", {
xmlns: "jabber:iq:roster"
})
.c("item", {
jid: jid,
subscription: "remove"
});
var suc = options.success || _utils.emptyfn;
var error = options.error || _utils.emptyfn;
this.context.stropheConn.sendIQ(iq, suc, error);
};
connection.prototype.getRoster = function (options) {
let dom = StropheAll.$iq({
type: "get"
})
.c("query", {
xmlns: "jabber:iq:roster"
});
options = options || {};
let suc = options.success || this.onRoster;
let error = options.error || this.onError;
if (this.isOpened()) {
this.context.stropheConn.sendIQ(dom.tree(), function (ele) {
var rouster = [];
var msgBodies = ele.getElementsByTagName("query");
if (msgBodies && msgBodies.length > 0) {
let queryTag = msgBodies[0];
rouster = _parseFriend(queryTag);
}
suc(rouster, ele);
}, function (ele) {
error({
type: _code.WEBIM_CONNCTION_GETROSTER_ERROR,
data: ele
});
});
} else {
error({
type: _code.WEBIM_CONNCTION_DISCONNECTED
});
}
};
connection.prototype.subscribe = function (options) {
var jid = _getJid(options, this);
var pres = StropheAll.$pres({
to: jid,
type: "subscribe"
});
if (options.message) {
pres.c("status").t(options.message).up();
}
if (options.nick) {
pres
.c("nick", {
xmlns: "http://jabber.org/protocol/nick"
})
.t(options.nick);
}
this.sendCommand(pres.tree());
};
connection.prototype.subscribed = function (options) {
var jid = _getJid(options, this);
var pres = StropheAll.$pres({
to: jid,
type: "subscribed"
});
if (options.message) {
pres.c("status").t(options.message).up();
}
this.sendCommand(pres.tree());
};
connection.prototype.unsubscribe = function (options) {
var jid = _getJid(options, this);
var pres = StropheAll.$pres({
to: jid,
type: "unsubscribe"
});
if (options.message) {
pres.c("status").t(options.message);
}
this.sendCommand(pres.tree());
};
connection.prototype.unsubscribed = function (options) {
var jid = _getJid(options, this);
var pres = StropheAll.$pres({
to: jid,
type: "unsubscribed"
});
if (options.message) {
pres.c("status").t(options.message).up();
}
this.sendCommand(pres.tree());
};
connection.prototype.createRoom = function (options) {
var suc = options.success || _utils.emptyfn;
var err = options.error || _utils.emptyfn;
var roomiq;
roomiq = StropheAll.$iq({
to: options.roomName,
type: "set"
})
.c("query", {
xmlns: Strophe.NS.MUC_OWNER
})
.c("x", {
xmlns: "jabber:x:data",
type: "submit"
});
return this.context.stropheConn.sendIQ(roomiq.tree(), suc, err);
};
// connection.prototype.joinPublicGroup = function(options){
// var roomJid = this.context.appKey + "_" + options.roomId + "@conference." + this.domain;
// var room_nick = roomJid + "/" + this.context.userId;
// var suc = options.success || _utils.emptyfn;
// var err = options.error || _utils.emptyfn;
// var errorFn = function(ele){
// err({
// type: _code.WEBIM_CONNCTION_JOINROOM_ERROR,
// data: ele
// });
// };
// var iq = $pres({
// from: this.context.jid,
// to: room_nick
// })
// .c("x", { xmlns: Strophe.NS.MUC });
// this.context.stropheConn.sendIQ(iq.tree(), suc, errorFn);
// };
connection.prototype.listRooms = function (options) {
var iq = StropheAll.$iq({
to: options.server || "conference." + this.domain,
from: this.context.jid,
type: "get"
})
.c("query", {
xmlns: Strophe.NS.DISCO_ITEMS
});
var suc = options.success || _utils.emptyfn;
var error = options.error || this.onError;
var completeFn = function (result) {
var rooms = [];
rooms = _parseRoom(result);
try {
suc(rooms);
} catch (e) {
error({
type: _code.WEBIM_CONNCTION_GETROOM_ERROR,
data: e
});
}
};
var err = options.error || _utils.emptyfn;
var errorFn = function (ele) {
err({
type: _code.WEBIM_CONNCTION_GETROOM_ERROR,
data: ele
});
};
this.context.stropheConn.sendIQ(iq.tree(), completeFn, errorFn);
};
connection.prototype.queryRoomMember = function (options) {
var members = [];
var iq = StropheAll.$iq({
to: this.context.appKey + "_" + options.roomId + "@conference." + this.domain,
type: "get"
})
.c("query", {
xmlns: Strophe.NS.MUC + "#admin"
})
.c("item", {
affiliation: "member"
});
var suc = options.success || _utils.emptyfn;
var completeFn = function (result) {
var items = result.getElementsByTagName("item");
if (items) {
for (let i = 0; i < items.length; i++) {
let item = items[i];
let mem = {
jid: item.getAttribute("jid"),
affiliation: "member"
};
members.push(mem);
}
}
suc(members);
};
var err = options.error || _utils.emptyfn;
var errorFn = function (ele) {
err({
type: _code.WEBIM_CONNCTION_GETROOMMEMBER_ERROR,
data: ele
});
};
this.context.stropheConn.sendIQ(iq.tree(), completeFn, errorFn);
};
connection.prototype.queryRoomInfo = function (options) {
var domain = this.domain;
var iq = StropheAll.$iq({
to: this.context.appKey + "_" + options.roomId + "@conference." + domain,
type: "get"
})
.c("query", {
xmlns: Strophe.NS.DISCO_INFO
});
var suc = options.success || _utils.emptyfn;
var members = [];
var completeFn = function (result) {
var settings = "";
var features = result.getElementsByTagName("feature");
if (features) {
settings = features[1].getAttribute("var") + "|" + features[3].getAttribute("var") + "|" + features[4].getAttribute("var");
}
switch (settings) {
case "muc_public|muc_membersonly|muc_notallowinvites":
settings = "PUBLIC_JOIN_APPROVAL";
break;
case "muc_public|muc_open|muc_notallowinvites":
settings = "PUBLIC_JOIN_OPEN";
break;
case "muc_hidden|muc_membersonly|muc_allowinvites":
settings = "PRIVATE_MEMBER_INVITE";
break;
case "muc_hidden|muc_membersonly|muc_notallowinvites":
settings = "PRIVATE_OWNER_INVITE";
break;
default:
break;
}
let fields = result.getElementsByTagName("field");
let fieldValues = {};
if (fields) {
for (let i = 0; i < fields.length; i++) {
let field = fields[i];
let fieldVar = field.getAttribute("var");
let fieldSimplify = fieldVar.split("_")[1];
switch (fieldVar) {
case "muc#roominfo_occupants":
case "muc#roominfo_maxusers":
case "muc#roominfo_affiliations":
case "muc#roominfo_description":
fieldValues[fieldSimplify] = (field.textContent || field.text || "");
break;
case "muc#roominfo_owner":
let mem = {
jid: (field.textContent || field.text) + "@" + domain,
affiliation: "owner"
};
members.push(mem);
fieldValues[fieldSimplify] = (field.textContent || field.text);
break;
default:
break;
}
// if (field.getAttribute('label') === 'owner') {
// var mem = {
// jid: (field.textContent || field.text) + '@' + domain
// , affiliation: 'owner'
// };
// members.push(mem);
// break;
// }
}
fieldValues.name = (result.getElementsByTagName("identity")[0]).getAttribute("name");
}
// log(settings, members, fieldValues);
suc(settings, members, fieldValues);
};
var err = options.error || _utils.emptyfn;
var errorFn = function (ele) {
err({
type: _code.WEBIM_CONNCTION_GETROOMINFO_ERROR,
data: ele
});
};
this.context.stropheConn.sendIQ(iq.tree(), completeFn, errorFn);
};
connection.prototype.queryRoomOccupants = function (options) {
var suc = options.success || _utils.emptyfn;
var completeFn = function (result) {
var occupants = [];
occupants = _parseRoomOccupants(result);
suc(occupants);
};
var err = options.error || _utils.emptyfn;
var errorFn = function (ele) {
err({
type: _code.WEBIM_CONNCTION_GETROOMOCCUPANTS_ERROR,
data: ele
});
};
var attrs = {
xmlns: Strophe.NS.DISCO_ITEMS
};
var info = StropheAll.$iq({
from: this.context.jid,
to: this.context.appKey + "_" + options.roomId + "@conference." + this.domain,
type: "get"
}).c("query", attrs);
this.context.stropheConn.sendIQ(info.tree(), completeFn, errorFn);
};
connection.prototype.setUserSig = function (desc) {
var dom = StropheAll.$pres({
xmlns: "jabber:client"
});
desc = desc || "";
dom.c("status").t(desc);
this.sendCommand(dom.tree());
};
connection.prototype.setPresence = function (type, status) {
var dom = StropheAll.$pres({
xmlns: "jabber:client"
});
if (type) {
if (status) {
dom.c("show").t(type);
dom.up().c("status").t(status);
} else {
dom.c("show").t(type);
}
}
this.sendCommand(dom.tree());
};
connection.prototype.getPresence = function () {
var dom = StropheAll.$pres({
xmlns: "jabber:client"
});
this.sendCommand(dom.tree());
};
connection.prototype.ping = function (options) {
options = options || {};
let jid = _getJid(options, this);
let dom = StropheAll.$iq({
from: this.context.jid || "",
to: jid,
type: "get"
})
.c("ping", {
xmlns: "urn:xmpp:ping"
});
let suc = options.success || _utils.emptyfn;
let error = options.error || this.onError;
let failFn = function (ele) {
error({
type: _code.WEBIM_CONNCTION_PING_ERROR,
data: ele
});
};
if (this.isOpened()) {
this.context.stropheConn.sendIQ(dom.tree(), suc, failFn);
} else {
error({
type: _code.WEBIM_CONNCTION_DISCONNECTED
});
}
};
connection.prototype.isOpened = function () {
return this.context.status == _code.STATUS_OPENED;
};
connection.prototype.isOpening = function () {
var ctxstatus = this.context.status;
return ctxstatus == _code.STATUS_DOLOGIN_USERGRID || ctxstatus == _code.STATUS_DOLOGIN_IM;
};
connection.prototype.isClosing = function () {
return this.context.status == _code.STATUS_CLOSING;
};
connection.prototype.isClosed = function () {
return this.context.status == _code.STATUS_CLOSED;
};
connection.prototype.clear = function () {
var key = this.context.appKey;
if (this.errorType != WebIM.statusCode.WEBIM_CONNCTION_DISCONNECTED) {
this.context = {
status: _code.STATUS_INIT,
appKey: key
};
}
if (this.intervalId) {
clearInterval(this.intervalId);
}
if (this.errorType == WebIM.statusCode.WEBIM_CONNCTION_CLIENT_LOGOUT || this.errorType == -1) {
}
};
connection.prototype.getChatRooms = function (options) {
let me = this;
let token = options.accessToken || this.context.accessToken;
if (token) {
let apiUrl = this.apiUrl;
let appName = this.context.appName;
let orgName = this.context.orgName;
if (!appName || !orgName) {
me.onError({
type: _code.WEBIM_CONNCTION_AUTH_ERROR
});
return;
}
let suc = function (data, xhr) {
typeof options.success === "function" && options.success(data);
};
let error = function (res, xhr, msg) {
if (res.error && res.error_description) {
me.onError({
type: _code.WEBIM_CONNCTION_LOAD_CHATROOM_ERROR,
msg: res.error_description,
data: res,
xhr: xhr
});
}
};
let pageInfo = {
pagenum: parseInt(options.pagenum) || 1,
pagesize: parseInt(options.pagesize) || 20
};
let opts = {
url: apiUrl + "/" + orgName + "/" + appName + "/chatrooms",
dataType: "json",
type: "GET",
header: {
Authorization: "Bearer " + token
},
data: pageInfo,
success: suc || _utils.emptyfn,
fail: error || _utils.emptyfn
};
wx.request(opts);
} else {
me.onError({
type: _code.WEBIM_CONNCTION_TOKEN_NOT_ASSIGN_ERROR
});
}
};
connection.prototype.joinChatRoom = function (options) {
var roomJid = this.context.appKey + "_" + options.roomId + "@conference." + this.domain;
var room_nick = roomJid + "/" + this.context.userId;
var suc = options.success || _utils.emptyfn;
var err = options.error || _utils.emptyfn;
var errorFn = function (ele) {
err({
type: _code.WEBIM_CONNCTION_JOINCHATROOM_ERROR,
data: ele
});
};
var pres = StropheAll.$pres({
from: this.context.jid,
to: room_nick
});
pres.c("x", {
xmlns: Strophe.NS.MUC + "#user"
})
.c("item", {
affiliation: "member",
role: "participant"
})
.up()
.up()
.c("roomtype", {
xmlns: "easemob:x:roomtype",
type: "chatroom"
});
this.context.stropheConn.sendIQ(pres.tree(), suc, errorFn);
};
connection.prototype.quitChatRoom = function (options) {
var roomJid = this.context.appKey + "_" + options.roomId + "@conference." + this.domain;
var room_nick = roomJid + "/" + this.context.userId;
var suc = options.success || _utils.emptyfn;
var err = options.error || _utils.emptyfn;
var errorFn = function (ele) {
err({
type: _code.WEBIM_CONNCTION_QUITCHATROOM_ERROR,
data: ele
});
};
var pres = StropheAll.$pres({
from: this.context.jid,
to: room_nick,
type: "unavailable"
});
pres
.c("x", {
xmlns: Strophe.NS.MUC + "#user"
})
.c("item", {
affiliation: "none",
role: "none"
})
.up()
.up()
.c("roomtype", {
xmlns: "easemob:x:roomtype",
type: "chatroom"
});
this.context.stropheConn.sendIQ(pres.tree(), suc, errorFn);
};
// connection.prototype._onReceiveInviteFromGroup = function(info){
// info = eval("(" + info + ")");
// let options = {
// title: "Group invitation",
// msg: info.user + " invites you to join into group:" + info.group_id,
// agree: function agree(){
// WebIM.doQuery(
// "{\"type\":\"acceptInvitationFromGroup\",\"id\":\"" + info.group_id + "\",\"user\":\"" + info.user + "\"}",
// function(response){
// },
// function(code, msg){
// IM.api.NotifyError("acceptInvitationFromGroup error:" + msg);
// }
// );
// },
// reject: function reject(){
// WebIM.doQuery(
// "{\"type\":\"declineInvitationFromGroup\",\"id\":\"" + info.group_id + "\",\"user\":\"" + info.user + "\"}",
// function(response){
// },
// function(code, msg){
// IM.api.NotifyError("declineInvitationFromGroup error:" + msg);
// }
// );
// }
// };
// this.onConfirmPop(options);
// };
// connection.prototype._onReceiveInviteAcceptionFromGroup = function(info){
// info = eval("(" + info + ")");
// let options = {
// title: "Group invitation response",
// msg: info.user + " agreed to join into group:" + info.group_id,
// agree: function agree(){
// }
// };
// this.onConfirmPop(options);
// };
// connection.prototype._onReceiveInviteDeclineFromGroup = function(info){
// info = eval("(" + info + ")");
// let options = {
// title: "Group invitation response",
// msg: info.user + " rejected to join into group:" + info.group_id,
// agree: function agree(){
// }
// };
// this.onConfirmPop(options);
// };
// connection.prototype._onAutoAcceptInvitationFromGroup = function(info){
// info = eval("(" + info + ")");
// let options = {
// title: "Group invitation",
// msg: "You had joined into the group:" + info.group_name + " automatically.Inviter:" + info.user,
// agree: function agree(){
// }
// };
// this.onConfirmPop(options);
// };
// connection.prototype._onLeaveGroup = function(info){
// info = eval("(" + info + ")");
// let options = {
// title: "Group notification",
// msg: "You have been out of the group:" + info.group_id + ".Reason:" + info.msg,
// agree: function agree(){
// }
// };
// this.onConfirmPop(options);
// };
// connection.prototype._onReceiveJoinGroupApplication = function(info){
// info = eval("(" + info + ")");
// let options = {
// title: "Group join application",
// msg: info.user + " applys to join into group:" + info.group_id,
// agree: function agree(){
// WebIM.doQuery("{\"type\":\"acceptJoinGroupApplication\",\"id\":\"" + info.group_id + "\",\"user\":\"" + info.user + "\"}", function(response){
// }, function(code, msg){
// IM.api.NotifyError("acceptJoinGroupApplication error:" + msg);
// });
// },
// reject: function reject(){
// WebIM.doQuery("{\"type\":\"declineJoinGroupApplication\",\"id\":\"" + info.group_id + "\",\"user\":\"" + info.user + "\"}", function(response){
// }, function(code, msg){
// IM.api.NotifyError("declineJoinGroupApplication error:" + msg);
// });
// }
// };
// this.onConfirmPop(options);
// };
// connection.prototype._onReceiveAcceptionFromGroup = function(info){
// info = eval("(" + info + ")");
// let options = {
// title: "Group notification",
// msg: "You had joined into the group:" + info.group_name + ".",
// agree: function agree(){
// }
// };
// this.onConfirmPop(options);
// };
// connection.prototype._onReceiveRejectionFromGroup = function(info){
// info = eval("(" + info + ")");
// let options = {
// title: "Group notification",
// msg: "You have been rejected to join into the group:" + info.group_name + ".",
// agree: function agree(){
// }
// };
// this.onConfirmPop(options);
// };
connection.prototype._onUpdateMyGroupList = function (options) {
this.onUpdateMyGroupList(options);
};
connection.prototype._onUpdateMyRoster = function (options) {
this.onUpdateMyRoster(options);
};
connection.prototype.reconnect = function(){
var me = this;
setTimeout(
function(){
_login(me.context.restTokenData&&me.context.restTokenData.data, me);
}, (
this.autoReconnectNumTotal == 0
? 0
: this.autoReconnectInterval
) * 1000
);
this.autoReconnectNumTotal++;
};
connection.prototype.closed = function(){
IM.api.init();
};
// 通过Rest列出群组的所有成员
connection.prototype.listGroupMember = function (opt) {
if (isNaN(opt.pageNum) || opt.pageNum <= 0) {
throw new Error("The parameter \"pageNum\" should be a positive number");
} else if (isNaN(opt.pageSize) || opt.pageSize <= 0) {
throw new Error("The parameter \"pageSize\" should be a positive number");
} else if (opt.groupId === null && typeof opt.groupId === "undefined") {
throw new Error("The parameter \"groupId\" should be added");
}
let requestData = [];
let groupId = opt.groupId;
requestData.pagenum = opt.pageNum;
requestData.pagesize = opt.pageSize;
let options = {
url: this.apiUrl + "/" + this.orgName + "/" + this.appName + "/chatgroups/" + groupId + "/users",
dataType: "json",
type: "GET",
data: requestData,
headers: {
Authorization: "Bearer " + this.context.accessToken,
"Content-Type": "application/json"
}
};
options.success = opt.success || _utils.emptyfn;
options.error = opt.error || _utils.emptyfn;
WebIM.utils.ajax(options);
};
// 通过 Rest 接口创建群组
connection.prototype.createGroupNew = function (opt) {
// opt.data.owner = this.user;
opt.data.invite_need_confirm = false;
let options = {
url: this.apiUrl + "/" + this.orgName + "/" + this.appName + "/chatgroups",
dataType: "json",
type: "POST",
data: JSON.stringify(opt.data),
headers: {
Authorization: "Bearer " + this.context.accessToken,
"Content-Type": "application/json"
}
};
options.success = function (respData) {
opt.success(respData);
this.onCreateGroup(respData);
}.bind(this);
options.error = opt.error || _utils.emptyfn;
WebIM.utils.ajax(options);
};
// 通过Rest根据groupid获取群组详情
connection.prototype.getGroupInfo = function (opt) {
var options = {
url: this.apiUrl + "/" + this.orgName + "/" + this.appName + "/chatgroups/" + opt.groupId,
type: "GET",
dataType: "json",
headers: {
Authorization: "Bearer " + this.context.accessToken,
"Content-Type": "application/json"
}
};
options.success = opt.success || _utils.emptyfn;
options.error = opt.error || _utils.emptyfn;
WebIM.utils.ajax(options);
};
// 通过Rest解散群组
connection.prototype.dissolveGroup = function (opt) {
var groupId = opt.groupId;
var options = {
url: this.apiUrl + "/" + this.orgName + "/" + this.appName + "/chatgroups/" + groupId + "?version=v3",
type: "DELETE",
dataType: "json",
headers: {
Authorization: "Bearer " + this.context.accessToken,
"Content-Type": "application/json"
}
};
options.success = opt.success || _utils.emptyfn;
options.error = opt.error || _utils.emptyfn;
WebIM.utils.ajax(options);
};
// used for blacklist
function _parsePrivacy(iq) {
var list = [];
var items = iq.getElementsByTagName("item");
if (items) {
for (let i = 0; i < items.length; i++) {
let item = items[i];
let jid = item.getAttribute("value");
let order = item.getAttribute("order");
let type = item.getAttribute("type");
if (!jid) {
continue;
}
let n = _parseNameFromJidFn(jid);
list[n] = {
type: type,
order: order,
jid: jid,
name: n
};
}
}
return list;
}
// used for blacklist
connection.prototype.getBlacklist = function (options) {
options = (options || {});
let iq = StropheAll.$iq({
type: "get"
});
let sucFn = options.success || _utils.emptyfn;
let errFn = options.error || _utils.emptyfn;
let me = this;
iq
.c("query", {
xmlns: "jabber:iq:privacy"
})
.c("list", {
name: "special"
});
this.context.stropheConn.sendIQ(iq.tree(), function (iq) {
me.onBlacklistUpdate(_parsePrivacy(iq));
sucFn();
}, function () {
me.onBlacklistUpdate([]);
errFn();
});
};
// used for blacklist
connection.prototype.addToBlackList = function (options) {
var iq = StropheAll.$iq({
type: "set"
});
var blacklist = options.list || {};
var sucFn = options.success || _utils.emptyfn;
var errFn = options.error || _utils.emptyfn;
var piece = iq
.c("query", {
xmlns: "jabber:iq:privacy"
})
.c("list", {
name: "special"
});
var keys = Object.keys(blacklist);
var len = keys.length;
var order = 2;
for (let i = 0; i < len; i++) {
let item = blacklist[keys[i]];
let type = item.type || "jid";
let jid = item.jid;
piece = piece
.c("item", {
action: "deny",
order: order++,
type: type,
value: jid
})
.c("message");
if (i !== len - 1) {
piece = piece.up().up();
}
}
this.context.stropheConn.sendIQ(piece.tree(), sucFn, errFn);
};
// used for blacklist
connection.prototype.removeFromBlackList = function (options) {
var iq = StropheAll.$iq({
type: "set"
});
var blacklist = options.list || {};
var sucFn = options.success || _utils.emptyfn;
var errFn = options.error || _utils.emptyfn;
var piece = iq
.c("query", {
xmlns: "jabber:iq:privacy"
})
.c("list", {
name: "special"
});
var keys = Object.keys(blacklist);
var len = keys.length;
for (let i = 0; i < len; i++) {
let item = blacklist[keys[i]];
let type = item.type || "jid";
let jid = item.jid;
let order = item.order;
piece = piece
.c("item", {
action: "deny",
order: order,
type: type,
value: jid
})
.c("message");
if (i !== len - 1) {
piece = piece.up().up();
}
}
this.context.stropheConn.sendIQ(piece.tree(), sucFn, errFn);
};
connection.prototype._getGroupJid = function (to) {
var appKey = this.context.appKey || "";
return appKey + "_" + to + "@conference." + this.domain;
};
// used for blacklist
connection.prototype.addToGroupBlackList = function (options) {
var sucFn = options.success || _utils.emptyfn;
var errFn = options.error || _utils.emptyfn;
var jid = _getJid(options, this);
var affiliation = "admin"; // options.affiliation || 'admin';
var to = this._getGroupJid(options.roomId);
var iq = StropheAll.$iq({
type: "set",
to: to
});
iq
.c("query", {
xmlns: "http://jabber.org/protocol/muc#" + affiliation
})
.c("item", {
affiliation: "outcast",
jid: jid
});
this.context.stropheConn.sendIQ(iq.tree(), sucFn, errFn);
};
// used for blacklist
connection.prototype.getGroupBlacklist = function (options) {
var sucFn = options.success || _utils.emptyfn;
var errFn = options.error || _utils.emptyfn;
// var jid = _getJid(options, this);
var affiliation = "admin"; // options.affiliation || 'admin';
var to = this._getGroupJid(options.roomId);
var iq = StropheAll.$iq({
type: "get",
to: to
});
iq
.c("query", {
xmlns: "http://jabber.org/protocol/muc#" + affiliation
})
.c("item", {
affiliation: "outcast",
});
function _parseGroupBlacklist(iq) {
var list = {};
var items = iq.getElementsByTagName("item");
if (items) {
for (let i = 0; i < items.length; i++) {
let item = items[i];
let jid = item.getAttribute("jid");
let affiliation = item.getAttribute("affiliation");
let nick = item.getAttribute("nick");
if (!jid) {
continue;
}
let n = _parseNameFromJidFn(jid);
list[n] = {
jid: jid,
affiliation: affiliation,
nick: nick,
name: n
};
}
}
return list;
}
this.context.stropheConn.sendIQ(iq.tree(), function (msginfo) {
sucFn(_parseGroupBlacklist(msginfo));
}, function () {
errFn();
});
};
// used for blacklist
connection.prototype.removeGroupMemberFromBlacklist = function (options) {
var sucFn = options.success || _utils.emptyfn;
var errFn = options.error || _utils.emptyfn;
var jid = _getJid(options, this);
var affiliation = "admin"; // options.affiliation || 'admin';
var to = this._getGroupJid(options.roomId);
var iq = StropheAll.$iq({
type: "set",
to: to
});
iq
.c("query", {
xmlns: "http://jabber.org/protocol/muc#" + affiliation
})
.c("item", {
affiliation: "member",
jid: jid
});
this.context.stropheConn.sendIQ(iq.tree(), function (msginfo) {
sucFn();
}, function () {
errFn();
});
};
/**
* changeGroupSubject 修改群名称
*
* @param options
*/
connection.prototype.changeGroupSubject = function (options) {
var sucFn = options.success || _utils.emptyfn;
var errFn = options.error || _utils.emptyfn;
// must be `owner`
var affiliation = "owner";
var to = this._getGroupJid(options.roomId);
var iq = StropheAll.$iq({
type: "set",
to: to
});
iq
.c("query", {
xmlns: "http://jabber.org/protocol/muc#" + affiliation
})
.c("x", {
type: "submit",
xmlns: "jabber:x:data"
})
.c("field", {
"var": "FORM_TYPE"
})
.c("value")
.t("http://jabber.org/protocol/muc#roomconfig")
.up()
.up()
.c("field", {
"var": "muc#roomconfig_roomname"
})
.c("value")
.t(options.subject)
.up()
.up()
.c("field", {
"var": "muc#roomconfig_roomdesc"
})
.c("value")
.t(options.description);
this.context.stropheConn.sendIQ(iq.tree(), function (msginfo) {
sucFn();
}, function () {
errFn();
});
};
/**
* destroyGroup 删除群组
*
* @param options
*/
connection.prototype.destroyGroup = function (options) {
var sucFn = options.success || _utils.emptyfn;
var errFn = options.error || _utils.emptyfn;
// must be `owner`
var affiliation = "owner";
var to = this._getGroupJid(options.roomId);
var iq = StropheAll.$iq({
type: "set",
to: to
});
iq
.c("query", {
xmlns: "http://jabber.org/protocol/muc#" + affiliation
})
.c("destroy");
this.context.stropheConn.sendIQ(iq.tree(), function (msginfo) {
sucFn();
}, function () {
errFn();
});
};
/**
* leaveGroupBySelf 主动离开群组
*
* @param options
*/
connection.prototype.leaveGroupBySelf = function (options) {
var me = this;
var sucFn = options.success || _utils.emptyfn;
var errFn = options.error || _utils.emptyfn;
// must be `owner`
var jid = _getJid(options, this);
var affiliation = "admin";
var to = this._getGroupJid(options.roomId);
var iq = StropheAll.$iq({
type: "set",
to: to
});
iq
.c("query", {
xmlns: "http://jabber.org/protocol/muc#" + affiliation
})
.c("item", {
affiliation: "none",
jid: jid
});
this.context.stropheConn.sendIQ(iq.tree(), function (msgInfo) {
sucFn(msgInfo);
let pres = StropheAll.$pres({
type: "unavailable",
to: to + "/" + me.context.userId
});
me.sendCommand(pres.tree());
}, function (errInfo) {
errFn(errInfo);
});
};
/**
* leaveGroup 被踢出群组
*
* @param options
*/
// connection.prototype.leaveGroup = function(options){
// var sucFn = options.success || _utils.emptyfn;
// var errFn = options.error || _utils.emptyfn;
// var list = options.list || [];
// var affiliation = "admin";
// var to = this._getGroupJid(options.roomId);
// var iq = $iq({ type: "set", to: to });
// var piece = iq.c("query", { xmlns: "http://jabber.org/protocol/muc#" + affiliation });
// var keys = Object.keys(list);
// var len = keys.length;
//
// for(let i = 0; i < len; i++){
// let name = list[keys[i]];
// let jid = _getJidByName(name, this);
//
// piece = piece.c("item", {
// affiliation: "none",
// jid: jid
// })
// .up()
// .c("item", {
// role: "none",
// jid: jid,
// })
// .up();
// }
//
// this.context.stropheConn.sendIQ(iq.tree(), function(msgInfo){
// sucFn(msgInfo);
// }, function(errInfo){
// errFn(errInfo);
// });
// };
/**
* addGroupMembers 添加群组成员
*
* @param options
*/
connection.prototype.addGroupMembers = function (options) {
var sucFn = options.success || _utils.emptyfn;
var errFn = options.error || _utils.emptyfn;
var list = options.list || [];
var affiliation = "admin";
var to = this._getGroupJid(options.roomId);
var iq = StropheAll.$iq({
type: "set",
to: to
});
var piece = iq.c("query", {
xmlns: "http://jabber.org/protocol/muc#" + affiliation
});
var len = list.length;
for (let i = 0; i < len; i++) {
let name = list[i];
let jid = _getJidByName(name, this);
piece = piece.c("item", {
affiliation: "member",
jid: jid
}).up();
let dom = StropheAll.$msg({
to: to
})
.c("x", {
xmlns: "http://jabber.org/protocol/muc#user"
})
.c("invite", {
to: jid
})
.c("reason")
.t(options.reason || "");
this.sendCommand(dom.tree());
}
this.context.stropheConn.sendIQ(iq.tree(), function (msgInfo) {
sucFn(msgInfo);
}, function (errInfo) {
errFn(errInfo);
});
};
/**
* acceptInviteFromGroup 接受加入申请
*
* @param options
*/
connection.prototype.acceptInviteFromGroup = function (options) {
options.success = function () {
// then send sendAcceptInviteMessage
// connection.prototype.sendAcceptInviteMessage(optoins);
};
this.addGroupMembers(options);
};
/**
* rejectInviteFromGroup 拒绝加入申请
*
* throw request for now 暂时不处理,直接丢弃
*
* @param options
*/
connection.prototype.rejectInviteFromGroup = function (options) {
};
//
// /**
// * createGroup 创建群组
// *
// * 1. 创建申请 -> 得到房主身份
// * 2. 获取房主信息 -> 得到房间form
// * 3. 完善房间form -> 创建成功
// * 4. 添加房间成员
// * 5. 消息通知成员
// * @param options
// */
// connection.prototype.createGroup = function(options){
// var roomId = +new Date();
// var toRoom = this._getGroupJid(roomId);
// var to = toRoom + "/" + this.context.userId;
//
// var pres = StropheAll.$pres({ to: to })
// .c("x", { xmlns: "http://jabber.org/protocol/muc" }).up()
// .c("create", { xmlns: "http://jabber.org/protocol/muc" }).up();
// // .c('c', {
// // hash: 'sha-1',
// // node: 'https://github.com/robbiehanson/XMPPFramework',
// // ver: 'k6gP4Ua5m4uu9YorAG0LRXM+kZY=',
// // xmlns: 'http://jabber.org/protocol/caps'
// // }).up();
//
// // createGroupACK
// this.sendCommand(pres.tree());
//
// let me = this;
// // timeout hack for create group async
// setTimeout(function(){
// var x;
// // Creating a Reserved Room
// var iq = $iq({ type: "get", to: toRoom })
// .c("query", { xmlns: "http://jabber.org/protocol/muc#owner" });
// // Strophe.info('step 1 ----------');
// // Strophe.info(options);
// me.context.stropheConn.sendIQ(iq.tree(), function(msgInfo){
// // for ie hack
// if("setAttribute" in msgInfo){
// // Strophe.info('step 3 ----------');
// x = msgInfo.getElementsByTagName("x")[0];
// x.setAttribute("type", "submit");
// }
// else{
// // Strophe.info('step 4 ----------');
// Strophe.forEachChild(msgInfo, "x", function(field){
// field.setAttribute("type", "submit");
// });
// }
// // var rcv = msgInfo.getElementsByTagName('x');
// // var v;
// // if (rcv.length > 0) {
// // if (rcv[0].childNodes && rcv[0].childNodes.length > 0) {
// // v = rcv[0].childNodes[0].nodeValue;
// // } else {
// // v = rcv[0].innerHTML || rcv[0].innerText
// // }
// // mid = rcv[0].getAttribute('mid');
// // }
// Strophe.info("step 5 ----------");
// Strophe.forEachChild(x, "field", function(field){
// var fieldVar = field.getAttribute("var");
// var valueDom = field.getElementsByTagName("value")[0];
// Strophe.info(fieldVar);
// switch(fieldVar){
// case "muc#roomconfig_roomname":
// _setText(valueDom, options.subject || "");
// break;
// case "muc#roomconfig_roomdesc":
// _setText(valueDom, options.description || "");
// break;
// case "muc#roomconfig_publicroom": // public 1
// _setText(valueDom, +options.optionsPublic);
// break;
// case "muc#roomconfig_membersonly":
// _setText(valueDom, +options.optionsMembersOnly);
// break;
// case "muc#roomconfig_moderatedroom":
// _setText(valueDom, +options.optionsModerate);
// break;
// case "muc#roomconfig_persistentroom":
// _setText(valueDom, 1);
// break;
// case "muc#roomconfig_allowinvites":
// _setText(valueDom, +options.optionsAllowInvites);
// break;
// case "muc#roomconfig_allowvisitornickchange":
// _setText(valueDom, 0);
// break;
// case "muc#roomconfig_allowvisitorstatus":
// _setText(valueDom, 0);
// break;
// case "allow_private_messages":
// _setText(valueDom, 0);
// break;
// case "allow_private_messages_from_visitors":
// _setText(valueDom, "nobody");
// break;
// default:
// break;
// }
// });
//
// let iq = $iq({ to: toRoom, type: "set" })
// .c("query", { xmlns: "http://jabber.org/protocol/muc#owner" })
// .cnode(x);
// me.context.stropheConn.sendIQ(iq.tree(), function(msgInfo){
// // sucFn(msgInfo);
// me.addGroupMembers({
// list: options.members,
// roomId: roomId
// });
// }, function(errInfo){
// // errFn(errInfo);
// });
// // sucFn(msgInfo);
// }, function(errInfo){
// // errFn(errInfo);
// });
// }, 1000);
// };
// function _setText(valueDom, v){
// if("textContent" in valueDom){
// valueDom.textContent = v;
// }
// else if("text" in valueDom){
// valueDom.text = v;
// }
// else{
// // Strophe.info('_setText 4 ----------');
// // valueDom.innerHTML = v;
// }
// }
// connection.prototype.onError = function () {
// return false;
// };
// window.WebIM = typeof WebIM !== 'undefined' ? WebIM : {};
WebIM.connection = connection;
WebIM.utils = _utils;
WebIM.statusCode = _code;
WebIM.message = _msg.message;
WebIM.doQuery = function (str, suc, fail) {
if (typeof window.cefQuery === "undefined") {
return;
}
window.cefQuery({
request: str,
persistent: false,
onSuccess: suc,
onFailure: fail
});
};
module.exports = WebIM;
if (module.hot) {
module.hot.accept();
}
\ No newline at end of file
This diff could not be displayed because it is too large.
function DOMParser(options) {
this.options = options || {locator: {}};
}
DOMParser.prototype.parseFromString = function (source, mimeType) {
var options = this.options;
var sax = new XMLReader();
var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
var errorHandler = options.errorHandler;
var locator = options.locator;
var defaultNSMap = options.xmlns || {};
var entityMap = {'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': "'"}
if (locator) {
domBuilder.setDocumentLocator(locator)
}
sax.errorHandler = buildErrorHandler(errorHandler, domBuilder, locator);
sax.domBuilder = options.domBuilder || domBuilder;
if (/\/x?html?$/.test(mimeType)) {
entityMap.nbsp = '\xa0';
entityMap.copy = '\xa9';
defaultNSMap[''] = 'http://www.w3.org/1999/xhtml';
}
defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
if (source) {
sax.parse(source, defaultNSMap, entityMap);
} else {
sax.errorHandler.error("invalid document source");
}
return domBuilder.document;
}
function buildErrorHandler(errorImpl, domBuilder, locator) {
if (!errorImpl) {
if (domBuilder instanceof DOMHandler) {
return domBuilder;
}
errorImpl = domBuilder;
}
var errorHandler = {}
var isCallback = errorImpl instanceof Function;
locator = locator || {}
function build(key) {
var fn = errorImpl[key];
if (!fn && isCallback) {
fn = errorImpl.length == 2 ? function (msg) {
errorImpl(key, msg)
} : errorImpl;
}
errorHandler[key] = fn && function (msg) {
fn('[xmldom ' + key + ']\t' + msg + _locator(locator));
} || function () {
};
}
build('warning');
build('error');
build('fatalError');
return errorHandler;
}
//console.log('#\n\n\n\n\n\n\n####')
/**
* +ContentHandler+ErrorHandler
* +LexicalHandler+EntityResolver2
* -DeclHandler-DTDHandler
*
* DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
* DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
* @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
*/
function DOMHandler() {
this.cdata = false;
}
function position(locator, node) {
node.lineNumber = locator.lineNumber;
node.columnNumber = locator.columnNumber;
}
/**
* @see org.xml.sax.ContentHandler#startDocument
* @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
*/
DOMHandler.prototype = {
startDocument: function () {
this.document = new DOMImplementation().createDocument(null, null, null);
if (this.locator) {
this.document.documentURI = this.locator.systemId;
}
},
startElement: function (namespaceURI, localName, qName, attrs) {
var doc = this.document;
var el = doc.createElementNS(namespaceURI, qName || localName);
var len = attrs.length;
appendElement(this, el);
this.currentElement = el;
this.locator && position(this.locator, el)
for (var i = 0; i < len; i++) {
var namespaceURI = attrs.getURI(i);
var value = attrs.getValue(i);
var qName = attrs.getQName(i);
var attr = doc.createAttributeNS(namespaceURI, qName);
if (attr.getOffset) {
position(attr.getOffset(1), attr)
}
attr.value = attr.nodeValue = value;
el.setAttributeNode(attr)
}
},
endElement: function (namespaceURI, localName, qName) {
var current = this.currentElement;
var tagName = current.tagName;
this.currentElement = current.parentNode;
},
startPrefixMapping: function (prefix, uri) {
},
endPrefixMapping: function (prefix) {
},
processingInstruction: function (target, data) {
var ins = this.document.createProcessingInstruction(target, data);
this.locator && position(this.locator, ins)
appendElement(this, ins);
},
ignorableWhitespace: function (ch, start, length) {
},
characters: function (chars, start, length) {
chars = _toString.apply(this, arguments)
//console.log(chars)
if (this.currentElement && chars) {
if (this.cdata) {
var charNode = this.document.createCDATASection(chars);
this.currentElement.appendChild(charNode);
} else {
var charNode = this.document.createTextNode(chars);
this.currentElement.appendChild(charNode);
}
this.locator && position(this.locator, charNode)
}
},
skippedEntity: function (name) {
},
endDocument: function () {
this.document.normalize();
},
setDocumentLocator: function (locator) {
if (this.locator = locator) {// && !('lineNumber' in locator)){
locator.lineNumber = 0;
}
},
//LexicalHandler
comment: function (chars, start, length) {
chars = _toString.apply(this, arguments)
var comm = this.document.createComment(chars);
this.locator && position(this.locator, comm)
appendElement(this, comm);
},
startCDATA: function () {
//used in characters() methods
this.cdata = true;
},
endCDATA: function () {
this.cdata = false;
},
startDTD: function (name, publicId, systemId) {
var impl = this.document.implementation;
if (impl && impl.createDocumentType) {
var dt = impl.createDocumentType(name, publicId, systemId);
this.locator && position(this.locator, dt)
appendElement(this, dt);
}
},
/**
* @see org.xml.sax.ErrorHandler
* @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
*/
warning: function (error) {
//console.warn('[xmldom warning]\t' + error, _locator(this.locator));
},
error: function (error) {
//console.error('[xmldom error]\t' + error, _locator(this.locator));
},
fatalError: function (error) {
//console.error('[xmldom fatalError]\t' + error, _locator(this.locator));
throw error;
}
}
function _locator(l) {
if (l) {
return '\n@' + (l.systemId || '') + '#[line:' + l.lineNumber + ',col:' + l.columnNumber + ']'
}
}
function _toString(chars, start, length) {
if (typeof chars == 'string') {
return chars.substr(start, length)
} else {//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
if (chars.length >= start + length || start) {
return new java.lang.String(chars, start, length) + '';
}
return chars;
}
}
/*
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
* used method of org.xml.sax.ext.LexicalHandler:
* #comment(chars, start, length)
* #startCDATA()
* #endCDATA()
* #startDTD(name, publicId, systemId)
*
*
* IGNORED method of org.xml.sax.ext.LexicalHandler:
* #endDTD()
* #startEntity(name)
* #endEntity(name)
*
*
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
* IGNORED method of org.xml.sax.ext.DeclHandler
* #attributeDecl(eName, aName, type, mode, value)
* #elementDecl(name, model)
* #externalEntityDecl(name, publicId, systemId)
* #internalEntityDecl(name, value)
* @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
* IGNORED method of org.xml.sax.EntityResolver2
* #resolveEntity(String name,String publicId,String baseURI,String systemId)
* #resolveEntity(publicId, systemId)
* #getExternalSubset(name, baseURI)
* @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
* IGNORED method of org.xml.sax.DTDHandler
* #notationDecl(name, publicId, systemId) {};
* #unparsedEntityDecl(name, publicId, systemId, notationName) {};
*/
"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g, function (key) {
DOMHandler.prototype[key] = function () {
return null
}
})
/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
function appendElement(hander, node) {
if (!hander.currentElement) {
hander.document.appendChild(node);
} else {
hander.currentElement.appendChild(node);
}
}//appendChild and setAttributeNS are preformance key
if (typeof require == 'function') {
var XMLReader = require('./sax').XMLReader;
var DOMImplementation = exports.DOMImplementation = require('./dom').DOMImplementation;
var XMLSerializer = exports.XMLSerializer = require('./dom').XMLSerializer;
exports.DOMParser = DOMParser;
var DOMParser = {
DOMImplementation: DOMImplementation,
XMLSerializer: XMLSerializer,
DOMParser: DOMParser
}
module.exports = DOMParser
}
/*
* DOM Level 2
* Object DOMException
* @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
* @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
*/
function copy(src, dest) {
for (var p in src) {
dest[p] = src[p];
}
}
/**
^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
*/
function _extends(Class, Super) {
var pt = Class.prototype;
if (Object.create) {
var ppt = Object.create(Super.prototype)
pt.__proto__ = ppt;
}
if (!(pt instanceof Super)) {
function t() {
};
t.prototype = Super.prototype;
t = new t();
copy(pt, t);
Class.prototype = pt = t;
}
if (pt.constructor != Class) {
if (typeof Class != 'function') {
//console.error("unknow Class:" + Class)
}
pt.constructor = Class
}
}
var htmlns = 'http://www.w3.org/1999/xhtml';
// Node Types
var NodeType = {}
var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
var TEXT_NODE = NodeType.TEXT_NODE = 3;
var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
// ExceptionCode
var ExceptionCode = {}
var ExceptionMessage = {};
var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1] = "Index size error"), 1);
var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2] = "DOMString size error"), 2);
var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3] = "Hierarchy request error"), 3);
var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4] = "Wrong document"), 4);
var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5] = "Invalid character"), 5);
var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6] = "No data allowed"), 6);
var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7] = "No modification allowed"), 7);
var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8] = "Not found"), 8);
var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9] = "Not supported"), 9);
var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10] = "Attribute in use"), 10);
//level2
var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11] = "Invalid state"), 11);
var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12] = "Syntax error"), 12);
var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13] = "Invalid modification"), 13);
var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14] = "Invalid namespace"), 14);
var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15] = "Invalid access"), 15);
function DOMException(code, message) {
if (message instanceof Error) {
var error = message;
} else {
error = this;
Error.call(this, ExceptionMessage[code]);
this.message = ExceptionMessage[code];
if (Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
}
error.code = code;
if (message) this.message = this.message + ": " + message;
return error;
};
DOMException.prototype = Error.prototype;
copy(ExceptionCode, DOMException)
/**
* @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
* The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live.
* The items in the NodeList are accessible via an integral index, starting from 0.
*/
function NodeList() {
};
NodeList.prototype = {
/**
* The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
* @standard level1
*/
length: 0,
/**
* Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null.
* @standard level1
* @param index unsigned long
* Index into the collection.
* @return Node
* The node at the indexth position in the NodeList, or null if that is not a valid index.
*/
item: function (index) {
return this[index] || null;
},
toString: function () {
for (var buf = [], i = 0; i < this.length; i++) {
serializeToString(this[i], buf);
}
return buf.join('');
}
};
function LiveNodeList(node, refresh) {
this._node = node;
this._refresh = refresh
_updateLiveList(this);
}
function _updateLiveList(list) {
var inc = list._node._inc || list._node.ownerDocument._inc;
if (list._inc != inc) {
var ls = list._refresh(list._node);
//console.log(ls.length)
__set__(list, 'length', ls.length);
copy(ls, list);
list._inc = inc;
}
}
LiveNodeList.prototype.item = function (i) {
_updateLiveList(this);
return this[i];
}
_extends(LiveNodeList, NodeList);
/**
*
* Objects implementing the NamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that NamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes.
* NamedNodeMap objects in the DOM are live.
* used for attributes or DocumentType entities
*/
function NamedNodeMap() {
};
function _findNodeIndex(list, node) {
var i = list.length;
while (i--) {
if (list[i] === node) {
return i
}
}
}
function _addNamedNode(el, list, newAttr, oldAttr) {
if (oldAttr) {
list[_findNodeIndex(list, oldAttr)] = newAttr;
} else {
list[list.length++] = newAttr;
}
if (el) {
newAttr.ownerElement = el;
var doc = el.ownerDocument;
if (doc) {
oldAttr && _onRemoveAttribute(doc, el, oldAttr);
_onAddAttribute(doc, el, newAttr);
}
}
}
function _removeNamedNode(el, list, attr) {
var i = _findNodeIndex(list, attr);
if (i >= 0) {
var lastIndex = list.length - 1
while (i < lastIndex) {
list[i] = list[++i]
}
list.length = lastIndex;
if (el) {
var doc = el.ownerDocument;
if (doc) {
_onRemoveAttribute(doc, el, attr);
attr.ownerElement = null;
}
}
} else {
throw DOMException(NOT_FOUND_ERR, new Error())
}
}
NamedNodeMap.prototype = {
length: 0,
item: NodeList.prototype.item,
getNamedItem: function (key) {
// if(key.indexOf(':')>0 || key == 'xmlns'){
// return null;
// }
var i = this.length;
while (i--) {
var attr = this[i];
if (attr.nodeName == key) {
return attr;
}
}
},
setNamedItem: function (attr) {
var el = attr.ownerElement;
if (el && el != this._ownerElement) {
throw new DOMException(INUSE_ATTRIBUTE_ERR);
}
var oldAttr = this.getNamedItem(attr.nodeName);
_addNamedNode(this._ownerElement, this, attr, oldAttr);
return oldAttr;
},
/* returns Node */
setNamedItemNS: function (attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
var el = attr.ownerElement, oldAttr;
if (el && el != this._ownerElement) {
throw new DOMException(INUSE_ATTRIBUTE_ERR);
}
oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName);
_addNamedNode(this._ownerElement, this, attr, oldAttr);
return oldAttr;
},
/* returns Node */
removeNamedItem: function (key) {
var attr = this.getNamedItem(key);
_removeNamedNode(this._ownerElement, this, attr);
return attr;
},// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
//for level2
removeNamedItemNS: function (namespaceURI, localName) {
var attr = this.getNamedItemNS(namespaceURI, localName);
_removeNamedNode(this._ownerElement, this, attr);
return attr;
},
getNamedItemNS: function (namespaceURI, localName) {
var i = this.length;
while (i--) {
var node = this[i];
if (node.localName == localName && node.namespaceURI == namespaceURI) {
return node;
}
}
return null;
}
};
/**
* @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
*/
function DOMImplementation(/* Object */ features) {
this._features = {};
if (features) {
for (var feature in features) {
this._features = features[feature];
}
}
};
DOMImplementation.prototype = {
hasFeature: function (/* string */ feature, /* string */ version) {
var versions = this._features[feature.toLowerCase()];
if (versions && (!version || version in versions)) {
return true;
} else {
return false;
}
},
// Introduced in DOM Level 2:
createDocument: function (namespaceURI, qualifiedName, doctype) {// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
var doc = new Document();
doc.implementation = this;
doc.childNodes = new NodeList();
doc.doctype = doctype;
if (doctype) {
doc.appendChild(doctype);
}
if (qualifiedName) {
var root = doc.createElementNS(namespaceURI, qualifiedName);
doc.appendChild(root);
}
return doc;
},
// Introduced in DOM Level 2:
createDocumentType: function (qualifiedName, publicId, systemId) {// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
var node = new DocumentType();
node.name = qualifiedName;
node.nodeName = qualifiedName;
node.publicId = publicId;
node.systemId = systemId;
// Introduced in DOM Level 2:
//readonly attribute DOMString internalSubset;
//TODO:..
// readonly attribute NamedNodeMap entities;
// readonly attribute NamedNodeMap notations;
return node;
}
};
/**
* @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
*/
function Node() {
};
Node.prototype = {
firstChild: null,
lastChild: null,
previousSibling: null,
nextSibling: null,
attributes: null,
parentNode: null,
childNodes: null,
ownerDocument: null,
nodeValue: null,
namespaceURI: null,
prefix: null,
localName: null,
// Modified in DOM Level 2:
insertBefore: function (newChild, refChild) {//raises
return _insertBefore(this, newChild, refChild);
},
replaceChild: function (newChild, oldChild) {//raises
this.insertBefore(newChild, oldChild);
if (oldChild) {
this.removeChild(oldChild);
}
},
removeChild: function (oldChild) {
return _removeChild(this, oldChild);
},
appendChild: function (newChild) {
return this.insertBefore(newChild, null);
},
hasChildNodes: function () {
return this.firstChild != null;
},
cloneNode: function (deep) {
return cloneNode(this.ownerDocument || this, this, deep);
},
// Modified in DOM Level 2:
normalize: function () {
var child = this.firstChild;
while (child) {
var next = child.nextSibling;
if (next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE) {
this.removeChild(next);
child.appendData(next.data);
} else {
child.normalize();
child = next;
}
}
},
// Introduced in DOM Level 2:
isSupported: function (feature, version) {
return this.ownerDocument.implementation.hasFeature(feature, version);
},
// Introduced in DOM Level 2:
hasAttributes: function () {
return this.attributes.length > 0;
},
lookupPrefix: function (namespaceURI) {
var el = this;
while (el) {
var map = el._nsMap;
//console.dir(map)
if (map) {
for (var n in map) {
if (map[n] == namespaceURI) {
return n;
}
}
}
el = el.nodeType == 2 ? el.ownerDocument : el.parentNode;
}
return null;
},
// Introduced in DOM Level 3:
lookupNamespaceURI: function (prefix) {
var el = this;
while (el) {
var map = el._nsMap;
//console.dir(map)
if (map) {
if (prefix in map) {
return map[prefix];
}
}
el = el.nodeType == 2 ? el.ownerDocument : el.parentNode;
}
return null;
},
// Introduced in DOM Level 3:
isDefaultNamespace: function (namespaceURI) {
var prefix = this.lookupPrefix(namespaceURI);
return prefix == null;
}
};
function _xmlEncoder(c) {
return c == '<' && '&lt;' ||
c == '>' && '&gt;' ||
c == '&' && '&amp;' ||
c == '"' && '&quot;' ||
'&#' + c.charCodeAt() + ';'
}
copy(NodeType, Node);
copy(NodeType, Node.prototype);
/**
* @param callback return true for continue,false for break
* @return boolean true: break visit;
*/
function _visitNode(node, callback) {
if (callback(node)) {
return true;
}
if (node = node.firstChild) {
do {
if (_visitNode(node, callback)) {
return true
}
} while (node = node.nextSibling)
}
}
function Document() {
}
function _onAddAttribute(doc, el, newAttr) {
doc && doc._inc++;
var ns = newAttr.namespaceURI;
if (ns == 'http://www.w3.org/2000/xmlns/') {
//update namespace
el._nsMap[newAttr.prefix ? newAttr.localName : ''] = newAttr.value
}
}
function _onRemoveAttribute(doc, el, newAttr, remove) {
doc && doc._inc++;
var ns = newAttr.namespaceURI;
if (ns == 'http://www.w3.org/2000/xmlns/') {
//update namespace
delete el._nsMap[newAttr.prefix ? newAttr.localName : '']
}
}
function _onUpdateChild(doc, el, newChild) {
if (doc && doc._inc) {
doc._inc++;
//update childNodes
var cs = el.childNodes;
if (newChild) {
cs[cs.length++] = newChild;
} else {
//console.log(1)
var child = el.firstChild;
var i = 0;
while (child) {
cs[i++] = child;
child = child.nextSibling;
}
cs.length = i;
}
}
}
/**
* attributes;
* children;
*
* writeable properties:
* nodeValue,Attr:value,CharacterData:data
* prefix
*/
function _removeChild(parentNode, child) {
var previous = child.previousSibling;
var next = child.nextSibling;
if (previous) {
previous.nextSibling = next;
} else {
parentNode.firstChild = next
}
if (next) {
next.previousSibling = previous;
} else {
parentNode.lastChild = previous;
}
_onUpdateChild(parentNode.ownerDocument, parentNode);
return child;
}
/**
* preformance key(refChild == null)
*/
function _insertBefore(parentNode, newChild, nextChild) {
var cp = newChild.parentNode;
if (cp) {
cp.removeChild(newChild);//remove and update
}
if (newChild.nodeType === DOCUMENT_FRAGMENT_NODE) {
var newFirst = newChild.firstChild;
if (newFirst == null) {
return newChild;
}
var newLast = newChild.lastChild;
} else {
newFirst = newLast = newChild;
}
var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
newFirst.previousSibling = pre;
newLast.nextSibling = nextChild;
if (pre) {
pre.nextSibling = newFirst;
} else {
parentNode.firstChild = newFirst;
}
if (nextChild == null) {
parentNode.lastChild = newLast;
} else {
nextChild.previousSibling = newLast;
}
do {
newFirst.parentNode = parentNode;
} while (newFirst !== newLast && (newFirst = newFirst.nextSibling))
_onUpdateChild(parentNode.ownerDocument || parentNode, parentNode);
//console.log(parentNode.lastChild.nextSibling == null)
if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
newChild.firstChild = newChild.lastChild = null;
}
return newChild;
}
function _appendSingleChild(parentNode, newChild) {
var cp = newChild.parentNode;
if (cp) {
var pre = parentNode.lastChild;
cp.removeChild(newChild);//remove and update
var pre = parentNode.lastChild;
}
var pre = parentNode.lastChild;
newChild.parentNode = parentNode;
newChild.previousSibling = pre;
newChild.nextSibling = null;
if (pre) {
pre.nextSibling = newChild;
} else {
parentNode.firstChild = newChild;
}
parentNode.lastChild = newChild;
_onUpdateChild(parentNode.ownerDocument, parentNode, newChild);
return newChild;
//console.log("__aa",parentNode.lastChild.nextSibling == null)
}
Document.prototype = {
//implementation : null,
nodeName: '#document',
nodeType: DOCUMENT_NODE,
doctype: null,
documentElement: null,
_inc: 1,
insertBefore: function (newChild, refChild) {//raises
if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
var child = newChild.firstChild;
while (child) {
var next = child.nextSibling;
this.insertBefore(child, refChild);
child = next;
}
return newChild;
}
if (this.documentElement == null && newChild.nodeType == 1) {
this.documentElement = newChild;
}
return _insertBefore(this, newChild, refChild), (newChild.ownerDocument = this), newChild;
},
removeChild: function (oldChild) {
if (this.documentElement == oldChild) {
this.documentElement = null;
}
return _removeChild(this, oldChild);
},
// Introduced in DOM Level 2:
importNode: function (importedNode, deep) {
return importNode(this, importedNode, deep);
},
// Introduced in DOM Level 2:
getElementById: function (id) {
var rtv = null;
_visitNode(this.documentElement, function (node) {
if (node.nodeType == 1) {
if (node.getAttribute('id') == id) {
rtv = node;
return true;
}
}
})
return rtv;
},
//document factory method:
createElement: function (tagName) {
var node = new Element();
node.ownerDocument = this;
node.nodeName = tagName;
node.tagName = tagName;
node.childNodes = new NodeList();
var attrs = node.attributes = new NamedNodeMap();
attrs._ownerElement = node;
return node;
},
createDocumentFragment: function () {
var node = new DocumentFragment();
node.ownerDocument = this;
node.childNodes = new NodeList();
return node;
},
createTextNode: function (data) {
var node = new Text();
node.ownerDocument = this;
node.appendData(data)
return node;
},
createComment: function (data) {
var node = new Comment();
node.ownerDocument = this;
node.appendData(data)
return node;
},
createCDATASection: function (data) {
var node = new CDATASection();
node.ownerDocument = this;
node.appendData(data)
return node;
},
createProcessingInstruction: function (target, data) {
var node = new ProcessingInstruction();
node.ownerDocument = this;
node.tagName = node.target = target;
node.nodeValue = node.data = data;
return node;
},
createAttribute: function (name) {
var node = new Attr();
node.ownerDocument = this;
node.name = name;
node.nodeName = name;
node.localName = name;
node.specified = true;
return node;
},
createEntityReference: function (name) {
var node = new EntityReference();
node.ownerDocument = this;
node.nodeName = name;
return node;
},
// Introduced in DOM Level 2:
createElementNS: function (namespaceURI, qualifiedName) {
var node = new Element();
var pl = qualifiedName.split(':');
var attrs = node.attributes = new NamedNodeMap();
node.childNodes = new NodeList();
node.ownerDocument = this;
node.nodeName = qualifiedName;
node.tagName = qualifiedName;
node.namespaceURI = namespaceURI;
if (pl.length == 2) {
node.prefix = pl[0];
node.localName = pl[1];
} else {
//el.prefix = null;
node.localName = qualifiedName;
}
attrs._ownerElement = node;
return node;
},
// Introduced in DOM Level 2:
createAttributeNS: function (namespaceURI, qualifiedName) {
var node = new Attr();
var pl = qualifiedName.split(':');
node.ownerDocument = this;
node.nodeName = qualifiedName;
node.name = qualifiedName;
node.namespaceURI = namespaceURI;
node.specified = true;
if (pl.length == 2) {
node.prefix = pl[0];
node.localName = pl[1];
} else {
//el.prefix = null;
node.localName = qualifiedName;
}
return node;
}
};
_extends(Document, Node);
function Element() {
this._nsMap = {};
};
Element.prototype = {
nodeType: ELEMENT_NODE,
hasAttribute: function (name) {
return this.getAttributeNode(name) != null;
},
getAttribute: function (name) {
var attr = this.getAttributeNode(name);
return attr && attr.value || '';
},
getAttributeNode: function (name) {
return this.attributes.getNamedItem(name);
},
setAttribute: function (name, value) {
var attr = this.ownerDocument.createAttribute(name);
attr.value = attr.nodeValue = "" + value;
this.setAttributeNode(attr)
},
removeAttribute: function (name) {
var attr = this.getAttributeNode(name)
attr && this.removeAttributeNode(attr);
},
//four real opeartion method
appendChild: function (newChild) {
if (newChild.nodeType === DOCUMENT_FRAGMENT_NODE) {
return this.insertBefore(newChild, null);
} else {
return _appendSingleChild(this, newChild);
}
},
setAttributeNode: function (newAttr) {
return this.attributes.setNamedItem(newAttr);
},
setAttributeNodeNS: function (newAttr) {
return this.attributes.setNamedItemNS(newAttr);
},
removeAttributeNode: function (oldAttr) {
return this.attributes.removeNamedItem(oldAttr.nodeName);
},
//get real attribute name,and remove it by removeAttributeNode
removeAttributeNS: function (namespaceURI, localName) {
var old = this.getAttributeNodeNS(namespaceURI, localName);
old && this.removeAttributeNode(old);
},
hasAttributeNS: function (namespaceURI, localName) {
return this.getAttributeNodeNS(namespaceURI, localName) != null;
},
getAttributeNS: function (namespaceURI, localName) {
var attr = this.getAttributeNodeNS(namespaceURI, localName);
return attr && attr.value || '';
},
setAttributeNS: function (namespaceURI, qualifiedName, value) {
var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
attr.value = attr.nodeValue = "" + value;
this.setAttributeNode(attr)
},
getAttributeNodeNS: function (namespaceURI, localName) {
return this.attributes.getNamedItemNS(namespaceURI, localName);
},
getElementsByTagName: function (tagName) {
return new LiveNodeList(this, function (base) {
var ls = [];
_visitNode(base, function (node) {
if (node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)) {
ls.push(node);
}
});
return ls;
});
},
getElementsByTagNameNS: function (namespaceURI, localName) {
return new LiveNodeList(this, function (base) {
var ls = [];
_visitNode(base, function (node) {
if (node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)) {
ls.push(node);
}
});
return ls;
});
}
};
Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
_extends(Element, Node);
function Attr() {
};
Attr.prototype.nodeType = ATTRIBUTE_NODE;
_extends(Attr, Node);
function CharacterData() {
};
CharacterData.prototype = {
data: '',
substringData: function (offset, count) {
return this.data.substring(offset, offset + count);
},
appendData: function (text) {
text = this.data + text;
this.nodeValue = this.data = text;
this.length = text.length;
},
insertData: function (offset, text) {
this.replaceData(offset, 0, text);
},
appendChild: function (newChild) {
//if(!(newChild instanceof CharacterData)){
throw new Error(ExceptionMessage[3])
//}
return Node.prototype.appendChild.apply(this, arguments)
},
deleteData: function (offset, count) {
this.replaceData(offset, count, "");
},
replaceData: function (offset, count, text) {
var start = this.data.substring(0, offset);
var end = this.data.substring(offset + count);
text = start + text + end;
this.nodeValue = this.data = text;
this.length = text.length;
}
}
_extends(CharacterData, Node);
function Text() {
};
Text.prototype = {
nodeName: "#text",
nodeType: TEXT_NODE,
splitText: function (offset) {
var text = this.data;
var newText = text.substring(offset);
text = text.substring(0, offset);
this.data = this.nodeValue = text;
this.length = text.length;
var newNode = this.ownerDocument.createTextNode(newText);
if (this.parentNode) {
this.parentNode.insertBefore(newNode, this.nextSibling);
}
return newNode;
}
}
_extends(Text, CharacterData);
function Comment() {
};
Comment.prototype = {
nodeName: "#comment",
nodeType: COMMENT_NODE
}
_extends(Comment, CharacterData);
function CDATASection() {
};
CDATASection.prototype = {
nodeName: "#cdata-section",
nodeType: CDATA_SECTION_NODE
}
_extends(CDATASection, CharacterData);
function DocumentType() {
};
DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
_extends(DocumentType, Node);
function Notation() {
};
Notation.prototype.nodeType = NOTATION_NODE;
_extends(Notation, Node);
function Entity() {
};
Entity.prototype.nodeType = ENTITY_NODE;
_extends(Entity, Node);
function EntityReference() {
};
EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
_extends(EntityReference, Node);
function DocumentFragment() {
};
DocumentFragment.prototype.nodeName = "#document-fragment";
DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
_extends(DocumentFragment, Node);
function ProcessingInstruction() {
}
ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
_extends(ProcessingInstruction, Node);
function XMLSerializer() {
}
XMLSerializer.prototype.serializeToString = function (node, attributeSorter) {
return node.toString(attributeSorter);
}
Node.prototype.toString = function (attributeSorter) {
var buf = [];
serializeToString(this, buf, attributeSorter);
return buf.join('');
}
function serializeToString(node, buf, attributeSorter, isHTML) {
switch (node.nodeType) {
case ELEMENT_NODE:
var attrs = node.attributes;
var len = attrs.length;
var child = node.firstChild;
var nodeName = node.tagName;
isHTML = (htmlns === node.namespaceURI) || isHTML
buf.push('<', nodeName);
if (attributeSorter) {
buf.sort.apply(attrs, attributeSorter);
}
for (var i = 0; i < len; i++) {
serializeToString(attrs.item(i), buf, attributeSorter, isHTML);
}
if (child || isHTML && !/^(?:meta|link|img|br|hr|input|button)$/i.test(nodeName)) {
buf.push('>');
//if is cdata child node
if (isHTML && /^script$/i.test(nodeName)) {
if (child) {
buf.push(child.data);
}
} else {
while (child) {
serializeToString(child, buf, attributeSorter, isHTML);
child = child.nextSibling;
}
}
buf.push('</', nodeName, '>');
} else {
buf.push('/>');
}
return;
case DOCUMENT_NODE:
case DOCUMENT_FRAGMENT_NODE:
var child = node.firstChild;
while (child) {
serializeToString(child, buf, attributeSorter, isHTML);
child = child.nextSibling;
}
return;
case ATTRIBUTE_NODE:
return buf.push(' ', node.name, '="', node.value.replace(/[<&"]/g, _xmlEncoder), '"');
case TEXT_NODE:
return buf.push(node.data.replace(/[<&]/g, _xmlEncoder));
case CDATA_SECTION_NODE:
return buf.push('<![CDATA[', node.data, ']]>');
case COMMENT_NODE:
return buf.push("<!--", node.data, "-->");
case DOCUMENT_TYPE_NODE:
var pubid = node.publicId;
var sysid = node.systemId;
buf.push('<!DOCTYPE ', node.name);
if (pubid) {
buf.push(' PUBLIC "', pubid);
if (sysid && sysid != '.') {
buf.push('" "', sysid);
}
buf.push('">');
} else if (sysid && sysid != '.') {
buf.push(' SYSTEM "', sysid, '">');
} else {
var sub = node.internalSubset;
if (sub) {
buf.push(" [", sub, "]");
}
buf.push(">");
}
return;
case PROCESSING_INSTRUCTION_NODE:
return buf.push("<?", node.target, " ", node.data, "?>");
case ENTITY_REFERENCE_NODE:
return buf.push('&', node.nodeName, ';');
//case ENTITY_NODE:
//case NOTATION_NODE:
default:
buf.push('??', node.nodeName);
}
}
function importNode(doc, node, deep) {
var node2;
switch (node.nodeType) {
case ELEMENT_NODE:
node2 = node.cloneNode(false);
node2.ownerDocument = doc;
//var attrs = node2.attributes;
//var len = attrs.length;
//for(var i=0;i<len;i++){
//node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
//}
case DOCUMENT_FRAGMENT_NODE:
break;
case ATTRIBUTE_NODE:
deep = true;
break;
//case ENTITY_REFERENCE_NODE:
//case PROCESSING_INSTRUCTION_NODE:
////case TEXT_NODE:
//case CDATA_SECTION_NODE:
//case COMMENT_NODE:
// deep = false;
// break;
//case DOCUMENT_NODE:
//case DOCUMENT_TYPE_NODE:
//cannot be imported.
//case ENTITY_NODE:
//case NOTATION_NODE:
//can not hit in level3
//default:throw e;
}
if (!node2) {
node2 = node.cloneNode(false);//false
}
node2.ownerDocument = doc;
node2.parentNode = null;
if (deep) {
var child = node.firstChild;
while (child) {
node2.appendChild(importNode(doc, child, deep));
child = child.nextSibling;
}
}
return node2;
}
//
//var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
// attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
function cloneNode(doc, node, deep) {
var node2 = new node.constructor();
for (var n in node) {
var v = node[n];
if (typeof v != 'object') {
if (v != node2[n]) {
node2[n] = v;
}
}
}
if (node.childNodes) {
node2.childNodes = new NodeList();
}
node2.ownerDocument = doc;
switch (node2.nodeType) {
case ELEMENT_NODE:
var attrs = node.attributes;
var attrs2 = node2.attributes = new NamedNodeMap();
var len = attrs.length
attrs2._ownerElement = node2;
for (var i = 0; i < len; i++) {
node2.setAttributeNode(cloneNode(doc, attrs.item(i), true));
}
break;
;
case ATTRIBUTE_NODE:
deep = true;
}
if (deep) {
var child = node.firstChild;
while (child) {
node2.appendChild(cloneNode(doc, child, deep));
child = child.nextSibling;
}
}
return node2;
}
function __set__(object, key, value) {
object[key] = value
}
//do dynamic
try {
if (Object.defineProperty) {
Object.defineProperty(LiveNodeList.prototype, 'length', {
get: function () {
_updateLiveList(this);
return this.$$length;
}
});
Object.defineProperty(Node.prototype, 'textContent', {
get: function () {
return getTextContent(this);
},
set: function (data) {
switch (this.nodeType) {
case 1:
case 11:
while (this.firstChild) {
this.removeChild(this.firstChild);
}
if (data || String(data)) {
this.appendChild(this.ownerDocument.createTextNode(data));
}
break;
default:
//TODO:
this.data = data;
this.value = value;
this.nodeValue = data;
}
}
})
function getTextContent(node) {
switch (node.nodeType) {
case 1:
case 11:
var buf = [];
node = node.firstChild;
while (node) {
if (node.nodeType !== 7 && node.nodeType !== 8) {
buf.push(getTextContent(node));
}
node = node.nextSibling;
}
return buf.join('');
default:
return node.nodeValue;
}
}
__set__ = function (object, key, value) {
//console.log(value)
object['$$' + key] = value
}
}
} catch (e) {//ie8
}
if (typeof require == 'function') {
exports.DOMImplementation = DOMImplementation;
exports.XMLSerializer = XMLSerializer;
}
//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
//[5] Name ::= NameStartChar (NameChar)*
var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF
var nameChar = new RegExp("[\\-\\.0-9" + nameStartChar.source.slice(1, -1) + "\u00B7\u0300-\u036F\\u203F-\u2040]");
var tagNamePattern = new RegExp('^' + nameStartChar.source + nameChar.source + '*(?:\:' + nameStartChar.source + nameChar.source + '*)?$');
//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',')
//S_TAG, S_ATTR, S_EQ, S_V
//S_ATTR_S, S_E, S_S, S_C
var S_TAG = 0;//tag name offerring
var S_ATTR = 1;//attr name offerring
var S_ATTR_S = 2;//attr name end and space offer
var S_EQ = 3;//=space?
var S_V = 4;//attr value(no quot value only)
var S_E = 5;//attr value end and no space(quot end)
var S_S = 6;//(attr value end || tag end ) && (space offer)
var S_C = 7;//closed el<el />
function XMLReader() {
}
XMLReader.prototype = {
parse: function (source, defaultNSMap, entityMap) {
var domBuilder = this.domBuilder;
domBuilder.startDocument();
_copy(defaultNSMap, defaultNSMap = {})
parse(source, defaultNSMap, entityMap,
domBuilder, this.errorHandler);
domBuilder.endDocument();
}
}
function parse(source, defaultNSMapCopy, entityMap, domBuilder, errorHandler) {
function fixedFromCharCode(code) {
// String.prototype.fromCharCode does not supports
// > 2 bytes unicode chars directly
if (code > 0xffff) {
code -= 0x10000;
var surrogate1 = 0xd800 + (code >> 10)
, surrogate2 = 0xdc00 + (code & 0x3ff);
return String.fromCharCode(surrogate1, surrogate2);
} else {
return String.fromCharCode(code);
}
}
function entityReplacer(a) {
var k = a.slice(1, -1);
if (k in entityMap) {
return entityMap[k];
} else if (k.charAt(0) === '#') {
return fixedFromCharCode(parseInt(k.substr(1).replace('x', '0x')))
} else {
errorHandler.error('entity not found:' + a);
return a;
}
}
function appendText(end) {//has some bugs
if (end > start) {
var xt = source.substring(start, end).replace(/&#?\w+;/g, entityReplacer);
locator && position(start);
domBuilder.characters(xt, 0, end - start);
start = end
}
}
function position(p, m) {
while (p >= lineEnd && (m = linePattern.exec(source))) {
lineStart = m.index;
lineEnd = lineStart + m[0].length;
locator.lineNumber++;
////console.log('line++:',locator,startPos,endPos)
}
locator.columnNumber = p - lineStart + 1;
}
var lineStart = 0;
var lineEnd = 0;
var linePattern = /.+(?:\r\n?|\n)|.*$/g
var locator = domBuilder.locator;
var parseStack = [{currentNSMap: defaultNSMapCopy}]
var closeMap = {};
var start = 0;
while (true) {
try {
var tagStart = source.indexOf('<', start);
if (tagStart < 0) {
if (!source.substr(start).match(/^\s*$/)) {
var doc = domBuilder.document;
var text = doc.createTextNode(source.substr(start));
doc.appendChild(text);
domBuilder.currentElement = text;
}
return;
}
if (tagStart > start) {
appendText(tagStart);
}
switch (source.charAt(tagStart + 1)) {
case '/':
var end = source.indexOf('>', tagStart + 3);
var tagName = source.substring(tagStart + 2, end);
var config = parseStack.pop();
var localNSMap = config.localNSMap;
if (config.tagName != tagName) {
errorHandler.fatalError("end tag name: " + tagName + ' is not match the current start tagName:' + config.tagName);
}
domBuilder.endElement(config.uri, config.localName, tagName);
if (localNSMap) {
for (var prefix in localNSMap) {
domBuilder.endPrefixMapping(prefix);
}
}
end++;
break;
// end elment
case '?':// <?...?>
locator && position(tagStart);
end = parseInstruction(source, tagStart, domBuilder);
break;
case '!':// <!doctype,<![CDATA,<!--
locator && position(tagStart);
end = parseDCC(source, tagStart, domBuilder, errorHandler);
break;
default:
//console.log('locator', locator)
locator && position(tagStart);
var el = new ElementAttributes();
//elStartEnd
var end = parseElementStartPart(source, tagStart, el, entityReplacer, errorHandler);
//console.log('end', end)
var len = el.length;
if (locator) {
if (len) {
//attribute position fixed
for (var i = 0; i < len; i++) {
var a = el[i];
position(a.offset);
a.offset = copyLocator(locator, {});
}
}
position(end);
}
//console.log('el', el)
if (!el.closed && fixSelfClosed(source, end, el.tagName, closeMap)) {
el.closed = true;
if (!entityMap.nbsp) {
errorHandler.warning('unclosed xml attribute');
}
}
//console.log('parseStack', parseStack)
appendElement(el, domBuilder, parseStack);
//console.log('el', el, parseStack)
if (el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed) {
end = parseHtmlSpecialContent(source, end, el.tagName, entityReplacer, domBuilder)
} else {
end++;
}
}
} catch (e) {
errorHandler.error('element parse error: ' + e);
//console.log('element parse error: ', e)
end = -1;
}
//console.log('out', end, start)
if (end > start) {
start = end;
} else {
//TODO: 这里有可能sax回退,有位置错误风险
appendText(Math.max(tagStart, start) + 1);
}
}
}
function copyLocator(f, t) {
t.lineNumber = f.lineNumber;
t.columnNumber = f.columnNumber;
return t;
}
/**
* @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
* @return end of the elementStartPart(end of elementEndPart for selfClosed el)
*/
function parseElementStartPart(source, start, el, entityReplacer, errorHandler) {
var attrName;
var value;
var p = ++start;
var s = S_TAG;//status
while (true) {
var c = source.charAt(p);
switch (c) {
case '=':
if (s === S_ATTR) {//attrName
attrName = source.slice(start, p);
s = S_EQ;
} else if (s === S_ATTR_S) {
s = S_EQ;
} else {
//fatalError: equal must after attrName or space after attrName
throw new Error('attribute equal must after attrName');
}
break;
case '\'':
case '"':
if (s === S_EQ) {//equal
start = p + 1;
p = source.indexOf(c, start)
if (p > 0) {
value = source.slice(start, p).replace(/&#?\w+;/g, entityReplacer);
el.add(attrName, value, start - 1);
s = S_E;
} else {
//fatalError: no end quot match
throw new Error('attribute value no end \'' + c + '\' match');
}
} else if (s == S_V) {
value = source.slice(start, p).replace(/&#?\w+;/g, entityReplacer);
////console.log(attrName,value,start,p)
el.add(attrName, value, start);
//console.dir(el)
errorHandler.warning('attribute "' + attrName + '" missed start quot(' + c + ')!!');
start = p + 1;
s = S_E
} else {
//fatalError: no equal before
throw new Error('attribute value must after "="');
}
break;
case '/':
switch (s) {
case S_TAG:
el.setTagName(source.slice(start, p));
case S_E:
case S_S:
case S_C:
s = S_C;
el.closed = true;
case S_V:
case S_ATTR:
case S_ATTR_S:
break;
//case S_EQ:
default:
throw new Error("attribute invalid close char('/')")
}
break;
case ''://end document
//throw new Error('unexpected end of input')
errorHandler.error('unexpected end of input');
case '>':
switch (s) {
case S_TAG:
el.setTagName(source.slice(start, p));
case S_E:
case S_S:
case S_C:
break;//normal
case S_V://Compatible state
case S_ATTR:
value = source.slice(start, p);
if (value.slice(-1) === '/') {
el.closed = true;
value = value.slice(0, -1)
}
case S_ATTR_S:
if (s === S_ATTR_S) {
value = attrName;
}
if (s == S_V) {
errorHandler.warning('attribute "' + value + '" missed quot(")!!');
el.add(attrName, value.replace(/&#?\w+;/g, entityReplacer), start)
} else {
errorHandler.warning('attribute "' + value + '" missed value!! "' + value + '" instead!!')
el.add(value, value, start)
}
break;
case S_EQ:
throw new Error('attribute value missed!!');
}
// //console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
return p;
/*xml space '\x20' | #x9 | #xD | #xA; */
case '\u0080':
c = ' ';
default:
if (c <= ' ') {//space
switch (s) {
case S_TAG:
el.setTagName(source.slice(start, p));//tagName
s = S_S;
break;
case S_ATTR:
attrName = source.slice(start, p)
s = S_ATTR_S;
break;
case S_V:
var value = source.slice(start, p).replace(/&#?\w+;/g, entityReplacer);
errorHandler.warning('attribute "' + value + '" missed quot(")!!');
el.add(attrName, value, start)
case S_E:
s = S_S;
break;
//case S_S:
//case S_EQ:
//case S_ATTR_S:
// void();break;
//case S_C:
//ignore warning
}
} else {//not space
//S_TAG, S_ATTR, S_EQ, S_V
//S_ATTR_S, S_E, S_S, S_C
switch (s) {
//case S_TAG:void();break;
//case S_ATTR:void();break;
//case S_V:void();break;
case S_ATTR_S:
errorHandler.warning('attribute "' + attrName + '" missed value!! "' + attrName + '" instead!!')
el.add(attrName, attrName, start);
start = p;
s = S_ATTR;
break;
case S_E:
errorHandler.warning('attribute space is required"' + attrName + '"!!')
case S_S:
s = S_ATTR;
start = p;
break;
case S_EQ:
s = S_V;
start = p;
break;
case S_C:
throw new Error("elements closed character '/' and '>' must be connected to");
}
}
}
p++;
}
}
/**
* @return end of the elementStartPart(end of elementEndPart for selfClosed el)
*/
function appendElement(el, domBuilder, parseStack) {
var tagName = el.tagName;
var localNSMap = null;
var currentNSMap = parseStack[parseStack.length - 1].currentNSMap;
var i = el.length;
while (i--) {
var a = el[i];
var qName = a.qName;
var value = a.value;
var nsp = qName.indexOf(':');
if (nsp > 0) {
var prefix = a.prefix = qName.slice(0, nsp);
var localName = qName.slice(nsp + 1);
var nsPrefix = prefix === 'xmlns' && localName
} else {
localName = qName;
prefix = null
nsPrefix = qName === 'xmlns' && ''
}
//can not set prefix,because prefix !== ''
a.localName = localName;
//prefix == null for no ns prefix attribute
if (nsPrefix !== false) {//hack!!
if (localNSMap == null) {
localNSMap = {}
////console.log(currentNSMap,0)
_copy(currentNSMap, currentNSMap = {})
////console.log(currentNSMap,1)
}
currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
a.uri = 'http://www.w3.org/2000/xmlns/'
domBuilder.startPrefixMapping(nsPrefix, value)
}
}
var i = el.length;
while (i--) {
a = el[i];
var prefix = a.prefix;
if (prefix) {//no prefix attribute has no namespace
if (prefix === 'xml') {
a.uri = 'http://www.w3.org/XML/1998/namespace';
}
if (prefix !== 'xmlns') {
a.uri = currentNSMap[prefix]
//{//console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
}
}
}
var nsp = tagName.indexOf(':');
if (nsp > 0) {
prefix = el.prefix = tagName.slice(0, nsp);
localName = el.localName = tagName.slice(nsp + 1);
} else {
prefix = null;//important!!
localName = el.localName = tagName;
}
//no prefix element has default namespace
var ns = el.uri = currentNSMap[prefix || ''];
domBuilder.startElement(ns, localName, tagName, el);
//endPrefixMapping and startPrefixMapping have not any help for dom builder
//localNSMap = null
if (el.closed) {
domBuilder.endElement(ns, localName, tagName);
if (localNSMap) {
for (prefix in localNSMap) {
domBuilder.endPrefixMapping(prefix)
}
}
} else {
el.currentNSMap = currentNSMap;
el.localNSMap = localNSMap;
parseStack.push(el);
}
}
function parseHtmlSpecialContent(source, elStartEnd, tagName, entityReplacer, domBuilder) {
if (/^(?:script|textarea)$/i.test(tagName)) {
var elEndStart = source.indexOf('</' + tagName + '>', elStartEnd);
var text = source.substring(elStartEnd + 1, elEndStart);
if (/[&<]/.test(text)) {
if (/^script$/i.test(tagName)) {
//if(!/\]\]>/.test(text)){
//lexHandler.startCDATA();
domBuilder.characters(text, 0, text.length);
//lexHandler.endCDATA();
return elEndStart;
//}
}//}else{//text area
text = text.replace(/&#?\w+;/g, entityReplacer);
domBuilder.characters(text, 0, text.length);
return elEndStart;
//}
}
}
return elStartEnd + 1;
}
function fixSelfClosed(source, elStartEnd, tagName, closeMap) {
//if(tagName in closeMap){
var pos = closeMap[tagName];
if (pos == null) {
////console.log(tagName)
pos = closeMap[tagName] = source.lastIndexOf('</' + tagName + '>')
}
return pos < elStartEnd;
//}
}
function _copy(source, target) {
for (var n in source) {
target[n] = source[n]
}
}
function parseDCC(source, start, domBuilder, errorHandler) {//sure start with '<!'
var next = source.charAt(start + 2)
switch (next) {
case '-':
if (source.charAt(start + 3) === '-') {
var end = source.indexOf('-->', start + 4);
//append comment source.substring(4,end)//<!--
if (end > start) {
domBuilder.comment(source, start + 4, end - start - 4);
return end + 3;
} else {
errorHandler.error("Unclosed comment");
return -1;
}
} else {
//error
return -1;
}
default:
if (source.substr(start + 3, 6) == 'CDATA[') {
var end = source.indexOf(']]>', start + 9);
domBuilder.startCDATA();
domBuilder.characters(source, start + 9, end - start - 9);
domBuilder.endCDATA()
return end + 3;
}
//<!DOCTYPE
//startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
var matchs = split(source, start);
var len = matchs.length;
if (len > 1 && /!doctype/i.test(matchs[0][0])) {
var name = matchs[1][0];
var pubid = len > 3 && /^public$/i.test(matchs[2][0]) && matchs[3][0]
var sysid = len > 4 && matchs[4][0];
var lastMatch = matchs[len - 1]
domBuilder.startDTD(name, pubid && pubid.replace(/^(['"])(.*?)\1$/, '$2'),
sysid && sysid.replace(/^(['"])(.*?)\1$/, '$2'));
domBuilder.endDTD();
return lastMatch.index + lastMatch[0].length
}
}
return -1;
}
function parseInstruction(source, start, domBuilder) {
var end = source.indexOf('?>', start);
if (end) {
var match = source.substring(start, end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
if (match) {
var len = match[0].length;
domBuilder.processingInstruction(match[1], match[2]);
return end + 2;
} else {//error
return -1;
}
}
return -1;
}
/**
* @param source
*/
function ElementAttributes(source) {
}
ElementAttributes.prototype = {
setTagName: function (tagName) {
if (!tagNamePattern.test(tagName)) {
throw new Error('invalid tagName:' + tagName)
}
this.tagName = tagName
},
add: function (qName, value, offset) {
if (!tagNamePattern.test(qName)) {
throw new Error('invalid attribute:' + qName)
}
this[this.length++] = {qName: qName, value: value, offset: offset}
},
length: 0,
getLocalName: function (i) {
return this[i].localName
},
getOffset: function (i) {
return this[i].offset
},
getQName: function (i) {
return this[i].qName
},
getURI: function (i) {
return this[i].uri
},
getValue: function (i) {
return this[i].value
}
// ,getIndex:function(uri, localName)){
// if(localName){
//
// }else{
// var qName = uri
// }
// },
// getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
// getType:function(uri,localName){}
// getType:function(i){},
}
function _set_proto_(thiz, parent) {
thiz.__proto__ = parent;
return thiz;
}
if (!(_set_proto_({}, _set_proto_.prototype) instanceof _set_proto_)) {
_set_proto_ = function (thiz, parent) {
function p() {
};
p.prototype = parent;
p = new p();
for (parent in thiz) {
p[parent] = thiz[parent];
}
return p;
}
}
function split(source, start) {
var match;
var buf = [];
var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
reg.lastIndex = start;
reg.exec(source);//skip <
while (match = reg.exec(source)) {
buf.push(match);
if (match[1])return buf;
}
}
if (typeof require == 'function') {
exports.XMLReader = XMLReader;
}
var StropheAll = require("./libs/strophe");
(function(){
var _utils = require("./utils").utils;
var Message = function(type, id){
if(!(this instanceof Message)){
return new Message(type);
}
this._msg = {};
if(typeof Message[type] === "function"){
Message[type].prototype.setGroup = this.setGroup;
this._msg = new Message[type](id);
}
return this._msg;
};
Message.prototype.setGroup = function(group){
this.body.group = group;
};
/*
* Read Message
*/
Message.read = function(id){
this.id = id;
this.type = "read";
};
Message.read.prototype.set = function(opt){
this.body = {
ackId: opt.id
, to: opt.to
};
};
/*
* text message
*/
Message.txt = function(id){
this.id = id;
this.type = "txt";
this.body = {};
};
Message.txt.prototype.set = function(opt){
this.value = opt.msg;
this.body = {
id: this.id,
from: opt.from,
to: opt.to,
msg: this.value,
type: this.type,
roomType: opt.roomType,
chatType: opt.chatType,
ext: opt.ext || {},
success: opt.success,
fail: opt.fail
};
!opt.roomType && delete this.body.roomType;
};
/*
* cmd message
*/
Message.cmd = function(id){
this.id = id;
this.type = "cmd";
this.body = {};
};
Message.cmd.prototype.set = function(opt){
this.value = "";
this.body = {
to: opt.to,
from: opt.from,
action: opt.action,
msg: this.value,
type: this.type,
roomType: opt.roomType,
ext: opt.ext || {}
};
!opt.roomType && delete this.body.roomType;
};
/*
* loc message
*/
Message.location = function(id){
this.id = id;
this.type = "loc";
this.body = {};
};
Message.location.prototype.set = function(opt){
this.body = {
to: opt.to,
from: opt.from,
type: this.type,
roomType: opt.roomType,
addr: opt.addr,
lat: opt.lat,
lng: opt.lng,
chatType: opt.chatType,
ext: opt.ext || {}
};
};
/*
* img message
*/
Message.img = function(id){
this.id = id;
this.type = "img";
this.body = {};
};
Message.img.prototype.set = function(opt){
// opt.file = opt.file || _utils.getFileUrl(opt.fileInputId);
// //console.log(opt)
this.value = opt.file;
this.body = {
id: this.id,
file: this.value,
apiUrl: opt.apiUrl,
to: opt.to,
from: opt.from,
type: this.type,
ext: opt.ext || {},
roomType: opt.roomType,
onFileUploadError: opt.onFileUploadError,
onFileUploadComplete: opt.onFileUploadComplete,
success: opt.success,
fail: opt.fail,
flashUpload: opt.flashUpload,
width: opt.width,
height: opt.height,
body: opt.body
};
!opt.roomType && delete this.body.roomType;
};
/*
* audio message
*/
Message.audio = function(id){
this.id = id;
this.type = "audio";
this.body = {};
};
Message.audio.prototype.set = function(opt){
opt.file = opt.file || _utils.getFileUrl(opt.fileInputId);
this.value = opt.file;
this.filename = opt.filename || this.value.filename;
this.body = {
id: this.id,
file: this.value,
filename: this.filename,
apiUrl: opt.apiUrl,
accessToken: opt.accessToken,
to: opt.to,
from: opt.from,
type: this.type,
ext: opt.ext || {},
length: opt.length || 0,
roomType: opt.roomType,
file_length: opt.file_length,
onFileUploadError: opt.onFileUploadError,
onFileUploadComplete: opt.onFileUploadComplete,
success: opt.success,
fail: opt.fail,
flashUpload: opt.flashUpload,
body: opt.body
};
!opt.roomType && delete this.body.roomType;
};
/*
* file message
*/
Message.file = function(id){
this.id = id;
this.type = "file";
this.body = {};
};
Message.file.prototype.set = function(opt){
opt.file = opt.file || _utils.getFileUrl(opt.fileInputId);
this.value = opt.file;
this.filename = opt.filename || this.value.filename;
this.body = {
id: this.id,
file: this.value,
filename: this.filename,
apiUrl: opt.apiUrl,
to: opt.to,
from: opt.from,
type: this.type,
ext: opt.ext || {},
roomType: opt.roomType,
onFileUploadError: opt.onFileUploadError,
onFileUploadComplete: opt.onFileUploadComplete,
success: opt.success,
fail: opt.fail,
flashUpload: opt.flashUpload,
body: opt.body
};
!opt.roomType && delete this.body.roomType;
};
/*
* video message
*/
Message.video = function(id){
this.id = id;
this.type = "file";
this.body = {};
};
Message.video.prototype.set = function(opt){
opt.file = opt.file || _utils.getFileUrl(opt.fileInputId);
this.value = opt.file;
this.filename = opt.filename || this.value.filename;
this.body = {
id: this.id,
file: this.value,
filename: this.filename,
apiUrl: opt.apiUrl,
to: opt.to,
from: opt.from,
type: this.type,
ext: opt.ext || {},
roomType: opt.roomType,
onFileUploadError: opt.onFileUploadError,
onFileUploadComplete: opt.onFileUploadComplete,
success: opt.success,
fail: opt.fail,
flashUpload: opt.flashUpload,
body: opt.body
};
!opt.roomType && delete this.body.roomType;
};
function _Message(message){
if(!(this instanceof _Message)){
return new _Message(message);
}
this.msg = message;
}
_Message.prototype.send = function(conn){
var me = this;
var _send = function(message){
message.ext = message.ext || {};
message.ext.weichat = message.ext.weichat || {};
message.ext.weichat.originType = message.ext.weichat.originType || "webim";
let json = {
from: conn.context.userId || "",
to: message.to,
bodies: [message.body],
ext: message.ext || {},
};
let jsonstr = _utils.stringify(json);
let dom = StropheAll
.$msg({
type: message.group || "chat",
to: message.toJid,
id: message.id,
xmlns: "jabber:client",
})
.c("body")
.t(jsonstr);
if(message.roomType){
dom
.up()
.c("roomtype", {
xmlns: "easemob:x:roomtype",
type: "chatroom"
});
}
if(message.bodyId){
dom = StropheAll
.$msg({
from: conn.context.jid || "",
to: message.toJid,
id: message.id,
xmlns: "jabber:client"
})
.c("body")
.t(message.bodyId);
let delivery = {
xmlns: "urn:xmpp:receipts",
id: message.bodyId
};
dom.up().c("delivery", delivery);
}
if(message.ackId){
if(conn.context.jid.indexOf(message.toJid) >= 0){
return;
}
dom = StropheAll.$msg({
from: conn.context.jid || ""
, to: message.toJid
, id: message.id
, xmlns: "jabber:client"
}).c("body").t(message.ackId);
let read = {
xmlns: "urn:xmpp:receipts"
, id: message.ackId
};
dom.up().c("acked", read);
}
// setTimeout(function(){
// if(typeof _msgHash !== "undefined" && _msgHash[message.id]){
// _msgHash[message.id].msg.fail instanceof Function
// && _msgHash[message.id].msg.fail(message.id);
// }
// }, 60000);
conn.sendCommand(dom.tree(), message.id);
};
if(me.msg.file){
if(me.msg.body && me.msg.body.url){// Only send msg
_send(me.msg);
return;
}
let _tmpComplete = me.msg.onFileUploadComplete;
let _complete = function(data){
if(data.entities[0]["file-metadata"]){
let file_len = data.entities[0]["file-metadata"]["content-length"];
me.msg.file_length = file_len;
me.msg.filetype = data.entities[0]["file-metadata"]["content-type"];
if(file_len > 204800){
me.msg.thumbnail = true;
}
}
me.msg.body = {
type: me.msg.type || "file",
url: data.uri + "/" + data.entities[0].uuid,
secret: data.entities[0]["share-secret"],
filename: me.msg.file.filename || me.msg.filename,
size: {
width: me.msg.width || 0
, height: me.msg.height || 0
},
length: me.msg.length || 0,
file_length: me.msg.file_length || 0,
filetype: me.msg.filetype,
};
_send(me.msg);
_tmpComplete instanceof Function && _tmpComplete(data, me.msg.id);
};
me.msg.onFileUploadComplete = _complete;
_utils.uploadFile.call(conn, me.msg);
}
else if(me.msg.type === "img"){ // 添加img判断规则 wjy
_send(me.msg);
}
else{
me.msg.body = {
type: me.msg.type === "chat" ? "txt" : me.msg.type
, msg: me.msg.msg
};
if(me.msg.type === "cmd"){
me.msg.body.action = me.msg.action;
}
else if(me.msg.type === "loc"){
me.msg.body.addr = me.msg.addr;
me.msg.body.lat = me.msg.lat;
me.msg.body.lng = me.msg.lng;
}
_send(me.msg);
}
};
exports._msg = _Message;
exports.message = Message;
}());
This diff could not be displayed because it is too large.
const fs = require('fs');
const path = require('path');
fs.readFile(path.join(__dirname, './build/output/connection.js'), 'utf8', function (err, data) {
var newContent = "var " + data;
fs.writeFile(path.join(__dirname, './build/output/connection.js'), newContent, 'utf8', (err) => {
if (err) {
console.log(err);
}
console.log('success done');
});
})
{
"name": "sdk",
"version": "1.0.0",
"description": "",
"main": "connection.js",
"scripts": {
"build": "parcel build connection.js NODE_ENV=production -d build/output; node package.buildxcx.js"
},
"keywords": [
"sdk"
],
"author": "",
"license": "ISC",
"devDependencies": {
"parcel-bundler": "^1.12.0",
"rollup-plugin-commonjs": "^9.2.1",
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
}
}
(function(){
function Array_h(length){
this.array = length === undefined ? [] : new Array(length);
}
Array_h.prototype = {
/**
* 返回数组长度
*
* @return {Number} length [数组长度]
*/
length: function(){
return this.array.length;
},
at: function(index){
return this.array[index];
},
set: function(index, obj){
this.array[index] = obj;
},
/**
* 向数组的末尾添加一个或多个元素,并返回新的长度。
*
* @param {*} obj [description]
* @return {Number} length [新数组的长度]
*/
push: function(obj){
return this.array.push(obj);
},
/**
* 返回数组中选定的元素
*
* @param {Number} start [开始索引值]
* @param {Number} end [结束索引值]
* @return {Array} newArray [新的数组]
*/
slice: function(start, end){
this.array = this.array.slice(start, end);
return this.array;
},
concat: function(array){
this.array = this.array.concat(array);
},
remove: function(index, count){
count = count === undefined ? 1 : count;
this.array.splice(index, count);
},
join: function(separator){
return this.array.join(separator);
},
clear: function(){
this.array.length = 0;
}
};
/**
* 先进先出队列 (First Input First Output)
*
* 一种先进先出的数据缓存器
*/
let Queue = function(){
this._array_h = new Array_h();
};
Queue.prototype = {
_index: 0,
/**
* 排队
*
* @param {Object} obj [description]
* @return {[type]} [description]
*/
push: function(obj){
this._array_h.push(obj);
},
/**
* 出队
*
* @return {Object} [description]
*/
pop: function(){
var ret = null;
if(this._array_h.length()){
ret = this._array_h.at(this._index);
if(++this._index * 2 >= this._array_h.length()){
this._array_h.slice(this._index);
this._index = 0;
}
}
return ret;
},
/**
* 返回队列中头部(即最新添加的)的动态对象
*
* @return {Object} [description]
*/
head: function(){
var ret = null, len = this._array_h.length();
if(len){
ret = this._array_h.at(len - 1);
}
return ret;
},
/**
* 返回队列中尾部(即最早添加的)的动态对象
*
* @return {Object} [description]
*/
tail: function(){
var ret = null, len = this._array_h.length();
if(len){
ret = this._array_h.at(this._index);
}
return ret;
},
/**
* 返回数据队列长度
*
* @return {Number} [description]
*/
length: function(){
return this._array_h.length() - this._index;
},
/**
* 队列是否为空
*
* @return {Boolean} [description]
*/
empty: function(){
return (this._array_h.length() === 0);
},
clear: function(){
this._array_h.clear();
}
};
exports.Queue = Queue;
}());
(function(){
var connIndex = 0;
exports.code = {
WEBIM_CONNCTION_USER_NOT_ASSIGN_ERROR: connIndex++,
WEBIM_CONNCTION_OPEN_ERROR: connIndex++,
WEBIM_CONNCTION_AUTH_ERROR: connIndex++,
WEBIM_CONNCTION_OPEN_USERGRID_ERROR: connIndex++,
WEBIM_CONNCTION_ATTACH_ERROR: connIndex++,
WEBIM_CONNCTION_ATTACH_USERGRID_ERROR: connIndex++,
WEBIM_CONNCTION_REOPEN_ERROR: connIndex++,
WEBIM_CONNCTION_SERVER_CLOSE_ERROR: connIndex++, // 7: client-side network offline (net::ERR_INTERNET_DISCONNECTED)
WEBIM_CONNCTION_SERVER_ERROR: connIndex++, // 8: offline by multi login
WEBIM_CONNCTION_IQ_ERROR: connIndex++,
WEBIM_CONNCTION_PING_ERROR: connIndex++,
WEBIM_CONNCTION_NOTIFYVERSION_ERROR: connIndex++,
WEBIM_CONNCTION_GETROSTER_ERROR: connIndex++,
WEBIM_CONNCTION_CROSSDOMAIN_ERROR: connIndex++,
WEBIM_CONNCTION_LISTENING_OUTOF_MAXRETRIES: connIndex++,
WEBIM_CONNCTION_RECEIVEMSG_CONTENTERROR: connIndex++,
WEBIM_CONNCTION_DISCONNECTED: connIndex++, // 16: server-side close the websocket connection
WEBIM_CONNCTION_AJAX_ERROR: connIndex++,
WEBIM_CONNCTION_JOINROOM_ERROR: connIndex++,
WEBIM_CONNCTION_GETROOM_ERROR: connIndex++,
WEBIM_CONNCTION_GETROOMINFO_ERROR: connIndex++,
WEBIM_CONNCTION_GETROOMMEMBER_ERROR: connIndex++,
WEBIM_CONNCTION_GETROOMOCCUPANTS_ERROR: connIndex++,
WEBIM_CONNCTION_LOAD_CHATROOM_ERROR: connIndex++,
WEBIM_CONNCTION_NOT_SUPPORT_CHATROOM_ERROR: connIndex++,
WEBIM_CONNCTION_JOINCHATROOM_ERROR: connIndex++,
WEBIM_CONNCTION_QUITCHATROOM_ERROR: connIndex++,
WEBIM_CONNCTION_APPKEY_NOT_ASSIGN_ERROR: connIndex++,
WEBIM_CONNCTION_TOKEN_NOT_ASSIGN_ERROR: connIndex++,
WEBIM_CONNCTION_SESSIONID_NOT_ASSIGN_ERROR: connIndex++,
WEBIM_CONNCTION_RID_NOT_ASSIGN_ERROR: connIndex++,
WEBIM_CONNCTION_CALLBACK_INNER_ERROR: connIndex++,
WEBIM_CONNCTION_CLIENT_OFFLINE: connIndex++, // 32: client offline
WEBIM_CONNCTION_CLIENT_LOGOUT: connIndex++, // 33: client logout
WEBIM_UPLOADFILE_BROWSER_ERROR: 100,
WEBIM_UPLOADFILE_ERROR: 101,
WEBIM_UPLOADFILE_NO_LOGIN: 102,
WEBIM_UPLOADFILE_NO_FILE: 103,
WEBIM_DOWNLOADFILE_ERROR: 200,
WEBIM_DOWNLOADFILE_NO_LOGIN: 201,
WEBIM_DOWNLOADFILE_BROWSER_ERROR: 202,
WEBIM_MESSAGE_REC_TEXT: 300,
WEBIM_MESSAGE_REC_TEXT_ERROR: 301,
WEBIM_MESSAGE_REC_EMOTION: 302,
WEBIM_MESSAGE_REC_PHOTO: 303,
WEBIM_MESSAGE_REC_AUDIO: 304,
WEBIM_MESSAGE_REC_AUDIO_FILE: 305,
WEBIM_MESSAGE_REC_VEDIO: 306,
WEBIM_MESSAGE_REC_VEDIO_FILE: 307,
WEBIM_MESSAGE_REC_FILE: 308,
WEBIM_MESSAGE_SED_TEXT: 309,
WEBIM_MESSAGE_SED_EMOTION: 310,
WEBIM_MESSAGE_SED_PHOTO: 311,
WEBIM_MESSAGE_SED_AUDIO: 312,
WEBIM_MESSAGE_SED_AUDIO_FILE: 313,
WEBIM_MESSAGE_SED_VEDIO: 314,
WEBIM_MESSAGE_SED_VEDIO_FILE: 315,
WEBIM_MESSAGE_SED_FILE: 316,
STATUS_INIT: 400,
STATUS_DOLOGIN_USERGRID: 401,
STATUS_DOLOGIN_IM: 402,
STATUS_OPENED: 403,
STATUS_CLOSING: 404,
STATUS_CLOSED: 405,
STATUS_ERROR: 406,
};
}());
(function(){
var EMPTYFN = function(){};
var _code = require("./status").code;
var WEBIM_FILESIZE_LIMIT = 10485760;
var _tmpUtilXHR = false;
var _hasFormData = typeof FormData !== "undefined";
var _hasBlob = typeof Blob !== "undefined";
var _isCanSetRequestHeader = _tmpUtilXHR.setRequestHeader || false;
var _hasOverrideMimeType = _tmpUtilXHR.overrideMimeType || false;
var _isCanUploadFileAsync = _isCanSetRequestHeader && _hasFormData;
var _isCanUploadFile = _isCanUploadFileAsync || false;
var _isCanDownLoadFile = _isCanSetRequestHeader && (_hasBlob || _hasOverrideMimeType);
if(!Object.keys){
Object.keys = (function(){
var hasOwnProperty = Object.prototype.hasOwnProperty;
var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable("toString");
var dontEnums = [
"toString",
"toLocaleString",
"valueOf",
"hasOwnProperty",
"isPrototypeOf",
"propertyIsEnumerable",
"constructor"
];
var dontEnumsLength = dontEnums.length;
return function(obj){
if(typeof obj !== "object" && (typeof obj !== "function" || obj === null)){
throw new TypeError("Object.keys called on non-object");
}
let result = [];
let prop;
let i;
for(prop in obj){
if(hasOwnProperty.call(obj, prop)){
result.push(prop);
}
}
if(hasDontEnumBug){
for(i = 0; i < dontEnumsLength; i++){
if(hasOwnProperty.call(obj, dontEnums[i])){
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
let utils = {
hasFormData: _hasFormData,
hasBlob: _hasBlob,
emptyfn: EMPTYFN,
isCanSetRequestHeader: _isCanSetRequestHeader,
hasOverrideMimeType: _hasOverrideMimeType,
isCanUploadFileAsync: _isCanUploadFileAsync,
isCanUploadFile: _isCanUploadFile,
isCanDownLoadFile: _isCanDownLoadFile,
isSupportWss: true,
hasFlash: false,
xmlrequest: false,
stringify: function(json){
if(typeof JSON !== "undefined" && JSON.stringify){
return JSON.stringify(json);
}
let s = "";
let arr = [];
return iterate(json);
function iterate(json){
var isArr = false;
if(Object.prototype.toString.call(json) === "[object Array]"){
arr.push("]", "[");
isArr = true;
}
else if(Object.prototype.toString.call(json) === "[object Object]"){
arr.push("}", "{");
}
for(let o in json){
if(Object.prototype.toString.call(json[o]) === "[object Null]"){
json[o] = "null";
}
else if(Object.prototype.toString.call(json[o]) === "[object Undefined]"){
json[o] = "undefined";
}
if(json[o] && typeof json[o] === "object"){
s += "," + (isArr ? "" : "\"" + o + "\":" + (isArr ? "\"" : "")) + iterate(json[o]) + "";
}
else{
s += ",\"" + (isArr ? "" : o + "\":\"") + json[o] + "\"";
}
}
if(s != ""){
s = s.slice(1);
}
return arr.pop() + s + arr.pop();
}
},
registerUser: function(options){
var orgName = options.orgName || "";
var appName = options.appName || "";
var appKey = options.appKey || "";
var suc = options.success || EMPTYFN;
var err = options.error || EMPTYFN;
if(!orgName && !appName && appKey){
let devInfos = appKey.split("#");
if(devInfos.length === 2){
orgName = devInfos[0];
appName = devInfos[1];
}
}
if(!orgName && !appName){
err({
type: _code.WEBIM_CONNCTION_APPKEY_NOT_ASSIGN_ERROR
});
return false;
}
let apiUrl = options.apiUrl;
let restUrl = apiUrl + "/" + orgName + "/" + appName + "/users";
let userjson = {
username: options.username,
password: options.password,
nickname: options.nickname || ""
};
let userinfo = utils.stringify(userjson);
options = {
url: restUrl,
data: userinfo,
success: suc,
error: err
};
return utils.ajax(options);
},
login: function(options){
options = options || {};
let suc = options.success || EMPTYFN;
let err = options.error || EMPTYFN;
let appKey = options.appKey || "";
let devInfos = appKey.split("#");
if(devInfos.length !== 2){
err({
type: _code.WEBIM_CONNCTION_APPKEY_NOT_ASSIGN_ERROR
});
return false;
}
let orgName = devInfos[0];
let appName = devInfos[1];
let user = options.user || "";
let pwd = options.pwd || "";
let apiUrl = options.apiUrl;
let loginJson = {
grant_type: "password",
username: user,
password: pwd,
timestamp: +new Date()
};
let loginfo = utils.stringify(loginJson);
options = {
url: apiUrl + "/" + orgName + "/" + appName + "/token",
data: loginfo,
success: suc,
error: err
};
return utils.ajax(options);
},
getFileUrl: function(fileInputId){
var uri = {
url: "",
filename: "",
filetype: "",
data: ""
};
var fileObj = typeof fileInputId === "string"
? document.getElementById(fileInputId)
: fileInputId;
if(!utils.isCanUploadFileAsync || !fileObj){
return uri;
}
try{
if(window.URL.createObjectURL){
let fileItems = fileObj.files; // 一个对象,文件列表
if(fileItems.length > 0){
let u = fileItems.item(0); // 有关选取文件的信息
uri.data = u;
uri.url = window.URL.createObjectURL(u); // 指向该文件的URL
uri.filename = u.name || "";
}
}
let index = uri.filename.lastIndexOf(".");
if(index != -1){
uri.filetype = uri.filename.substring(index + 1).toLowerCase();
}
return uri;
}
catch(e){
throw e;
}
},
getFileSize: function(fileInputId){
let file = document.getElementById(fileInputId);
let fileSize = 0;
if(file){
if(file.files){
if(file.files.length > 0){
fileSize = file.files[0].size;
}
}
}
return fileSize;
},
trim: function(str){
str = typeof str === "string" ? str : "";
return str.trim
? str.trim()
: str.replace(/^\s|\s$/g, "");
},
parseEmoji: function(msg){
if(typeof WebIM.Emoji === "undefined" || typeof WebIM.Emoji.map === "undefined"){
return msg;
}
let emoji = WebIM.Emoji;
for(let face in emoji.map){
if(emoji.map.hasOwnProperty(face)){
while(msg.indexOf(face) > -1){
msg = msg.replace(face, "<image class=\"emoji\" src=\"" + emoji.path + emoji.map[face] + "\" /></image>");
}
}
}
return msg;
},
parseLink: function(msg){
var reg = /(https?:\/\/|www\.)([a-zA-Z0-9-]+(\.[a-zA-Z0-9]+)+)(:[0-9]{2,4})?\/?((\.[:_0-9a-zA-Z-]+)|[:_0-9a-zA-Z-]*\/?)*\??[:_#@*&%0-9a-zA-Z-/=]*/gm;
msg = msg.replace(reg, function(v){
var prefix = /^https?/gm.test(v);
return "<a href='" + (prefix ? v : "//" + v) + "' target='_blank'>" + v + "</a>";
});
return msg;
},
parseJSON: function(data){
if(window.JSON && window.JSON.parse){
return window.JSON.parse(data + "");
}
let requireNonComma;
let depth = null;
let str = utils.trim(data + "");
return str && !utils.trim(
str.replace(
/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g,
function(token, comma, open, close){
if(requireNonComma && comma){
depth = 0;
}
if(depth === 0){
return token;
}
requireNonComma = open || comma;
depth += !close - !open;
return "";
})
)
? (Function("return " + str))()
: (Function("Invalid JSON: " + data))();
},
parseUploadResponse: function(response){
return response.indexOf("callback") > -1
// lte ie9
? response.slice(9, -1)
: response;
},
parseDownloadResponse: function(response){
return (
(response && response.type && response.type === "application/json") ||
Object.prototype.toString.call(response).indexOf("Blob") < 0
)
? this.url + "?token="
: window.URL.createObjectURL(response);
},
uploadFile: function(options){
options = options || {};
options.onFileUploadProgress = options.onFileUploadProgress || EMPTYFN;
options.onFileUploadComplete = options.onFileUploadComplete || EMPTYFN;
options.onFileUploadError = options.onFileUploadError || EMPTYFN;
options.onFileUploadCanceled = options.onFileUploadCanceled || EMPTYFN;
let acc = options.accessToken || this.context.accessToken;
if(!acc){
options.onFileUploadError({
type: _code.WEBIM_UPLOADFILE_NO_LOGIN,
id: options.id
});
return;
}
let orgName, appName, devInfos;
let appKey = options.appKey || this.context.appKey || "";
if(appKey){
devInfos = appKey.split("#");
orgName = devInfos[0];
appName = devInfos[1];
}
if(!orgName && !appName){
options.onFileUploadError({
type: _code.WEBIM_UPLOADFILE_ERROR
, id: options.id
});
return;
}
let apiUrl = options.apiUrl;
let uploadUrl = apiUrl + "/" + orgName + "/" + appName + "/chatfiles";
if(!utils.isCanUploadFileAsync){
if(utils.hasFlash && typeof options.flashUpload === "function"){
options.flashUpload && options.flashUpload(uploadUrl, options);
}
else{
options.onFileUploadError({
type: _code.WEBIM_UPLOADFILE_BROWSER_ERROR
, id: options.id
});
}
return;
}
let fileSize = options.file.data ? options.file.data.size : undefined;
if(fileSize > WEBIM_FILESIZE_LIMIT){
options.onFileUploadError({
type: _code.WEBIM_UPLOADFILE_ERROR,
id: options.id
});
return;
}
else if(fileSize <= 0){
options.onFileUploadError({
type: _code.WEBIM_UPLOADFILE_ERROR,
id: options.id
});
return;
}
let xhr = utils.xmlrequest();
let onError = function(e){
options.onFileUploadError({
type: _code.WEBIM_UPLOADFILE_ERROR,
id: options.id,
xhr: xhr
});
};
if(xhr.upload){
xhr.upload.addEventListener("progress", options.onFileUploadProgress, false);
}
if(xhr.addEventListener){
xhr.addEventListener("abort", options.onFileUploadCanceled, false);
xhr.addEventListener("load", function(e){
try{
let json = utils.parseJSON(xhr.responseText);
try{
options.onFileUploadComplete(json);
}
catch(e){
options.onFileUploadError({
type: _code.WEBIM_CONNCTION_CALLBACK_INNER_ERROR
, data: e
});
}
}
catch(e){
options.onFileUploadError({
type: _code.WEBIM_UPLOADFILE_ERROR,
data: xhr.responseText,
id: options.id,
xhr: xhr
});
}
}, false);
xhr.addEventListener("error", onError, false);
}
else if(xhr.onreadystatechange){
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(ajax.status === 200){
try{
let json = utils.parseJSON(xhr.responseText);
options.onFileUploadComplete(json);
}
catch(e){
options.onFileUploadError({
type: _code.WEBIM_UPLOADFILE_ERROR,
data: xhr.responseText,
id: options.id,
xhr: xhr
});
}
}
else{
options.onFileUploadError({
type: _code.WEBIM_UPLOADFILE_ERROR,
data: xhr.responseText,
id: options.id,
xhr: xhr
});
}
}
else{
xhr.abort();
options.onFileUploadCanceled();
}
};
}
xhr.open("POST", uploadUrl);
xhr.setRequestHeader("restrict-access", "true");
xhr.setRequestHeader("Accept", "*/*"); // Android QQ browser has some problem with this attribute.
xhr.setRequestHeader("Authorization", "Bearer " + acc);
let formData = new FormData();
formData.append("file", options.file.data);
xhr.send(formData);
},
download: function(options){
options.onFileDownloadComplete = options.onFileDownloadComplete || EMPTYFN;
options.onFileDownloadError = options.onFileDownloadError || EMPTYFN;
let accessToken = options.accessToken || this.context.accessToken;
let xhr = utils.xmlrequest();
if(!accessToken){
options.onFileDownloadError({
type: _code.WEBIM_DOWNLOADFILE_NO_LOGIN,
id: options.id
});
return;
}
let onError = function(e){
options.onFileDownloadError({
type: _code.WEBIM_DOWNLOADFILE_ERROR,
id: options.id,
xhr: xhr
});
};
if(!utils.isCanDownLoadFile){
options.onFileDownloadComplete();
return;
}
if("addEventListener" in xhr){
xhr.addEventListener("load", function(e){
options.onFileDownloadComplete(xhr.response, xhr);
}, false);
xhr.addEventListener("error", onError, false);
}
else if("onreadystatechange" in xhr){
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(ajax.status === 200){
options.onFileDownloadComplete(xhr.response, xhr);
}
else{
options.onFileDownloadError({
type: _code.WEBIM_DOWNLOADFILE_ERROR,
id: options.id,
xhr: xhr
});
}
}
else{
xhr.abort();
options.onFileDownloadError({
type: _code.WEBIM_DOWNLOADFILE_ERROR,
id: options.id,
xhr: xhr
});
}
};
}
let method = options.method || "GET";
let resType = options.responseType || "blob";
let mimeType = options.mimeType || "text/plain; charset=x-user-defined";
xhr.open(method, options.url);
if(typeof Blob !== "undefined"){
xhr.responseType = resType;
}
else{
xhr.overrideMimeType(mimeType);
}
let innerHeaer = {
"X-Requested-With": "XMLHttpRequest",
Accept: "application/octet-stream",
"share-secret": options.secret,
Authorization: "Bearer " + accessToken
};
let headers = options.headers || {};
for(let key in headers){
innerHeaer[key] = headers[key];
}
for(let key in innerHeaer){
if(innerHeaer[key]){
xhr.setRequestHeader(key, innerHeaer[key]);
}
}
xhr.send(null);
},
parseTextMessage: function(message, faces){
if(typeof message !== "string"){
return false;
}
if(Object.prototype.toString.call(faces) !== "[object Object]"){
return {
isemoji: false,
body: [
{
type: "txt",
data: message
}
]
};
}
let receiveMsg = message;
let emessage = [];
let expr = /\[[^[\]]{2,3}\]/mg;
let emoji = receiveMsg.match(expr);
if(!emoji || emoji.length < 1){
return {
isemoji: false,
body: [
{
type: "txt",
data: message
}
]
};
}
let isemoji = false;
for(let i = 0; i < emoji.length; i++){
let tmsg = receiveMsg.substring(0, receiveMsg.indexOf(emoji[i]));
let existEmoji = faces.map[emoji[i]];
if(tmsg){
emessage.push({
type: "txt",
data: tmsg
});
}
if(!existEmoji){
emessage.push({
type: "txt",
data: emoji[i]
});
continue;
}
let emojiStr = faces.map ? existEmoji : null;
if(emojiStr){
isemoji = true;
emessage.push({
type: "emoji",
data: emojiStr
});
}
else{
emessage.push({
type: "txt",
data: emoji[i]
});
}
let restMsgIndex = receiveMsg.indexOf(emoji[i]) + emoji[i].length;
receiveMsg = receiveMsg.substring(restMsgIndex);
}
if(receiveMsg){
emessage.push({
type: "txt",
data: receiveMsg
});
}
if(isemoji){
return {
isemoji: isemoji,
body: emessage
};
}
return {
isemoji: false,
body: [
{
type: "txt",
data: message
}
]
};
},
ajax: function(options){
var suc = options.success || EMPTYFN;
var error = options.error || EMPTYFN;
var type = options.type || "POST",
data = options.data || null,
tempData = "";
if(type.toLowerCase() === "get" && data){
for(let o in data){
if(data.hasOwnProperty(o)){
tempData += o + "=" + data[o] + "&";
}
}
tempData = tempData ? tempData.slice(0, -1) : tempData;
options.url += (options.url.indexOf("?") > 0 ? "&" : "?") + (tempData ? tempData + "&" : tempData) + "_v=" + new Date().getTime();
data = null;
tempData = null;
}
console.log("wx.request", options.url);
wx.request({
url: options.url,
data: options.data,
header: options.headers,
method: type,
success: function(res){
console.log("wx.request.success", arguments);
if(res.statusCode == "200"){
suc(res);
}
else{
error(res);
}
},
complete(){
console.log("wx.request.complete", arguments);
},
fail(){
console.log("wx.request.fail", arguments);
}
});
},
ts: function(){
var d = new Date();
var Hours = d.getHours(); // 获取当前小时数(0-23)
var Minutes = d.getMinutes(); // 获取当前分钟数(0-59)
var Seconds = d.getSeconds(); // 获取当前秒数(0-59)
var Milliseconds = d.getMilliseconds(); // 获取当前毫秒
return (Hours < 10 ? "0" + Hours : Hours) + ":" +
(Minutes < 10 ? "0" + Minutes : Minutes) + ":" +
(Seconds < 10 ? "0" + Seconds : Seconds) + ":" +
Milliseconds + " ";
},
getObjectKey: function(obj, val){
for(let key in obj){
if(obj[key] == val){
return key;
}
}
return "";
}
};
exports.utils = utils;
}());
var dispCbs = [];
var dispIns = [];
function Dispatcher(){
dispIns.push(this);
dispCbs.push({});
}
Dispatcher.prototype = {
on(type, cb){
let cbtypes = dispCbs[dispIns.indexOf(this)];
let cbs = cbtypes[type] = (cbtypes[type] || []);
if(!~cbs.indexOf(cb)){
cbs.push(cb);
}
},
off(type, cb){
let cbtypes = dispCbs[dispIns.indexOf(this)];
let cbs = cbtypes[type] = (cbtypes[type] || []);
let curTypeCbIdx = cbs.indexOf(cb);
if(~curTypeCbIdx){
cbs.splice(curTypeCbIdx, 1);
}
},
fire(type, ...args){
let cbtypes = dispCbs[dispIns.indexOf(this)];
let cbs = cbtypes[type] = (cbtypes[type] || []);
for(let i = 0; i < cbs.length; i++){
cbs[i].apply(null, args);
}
}
};
module.exports = Dispatcher;
var obsCbs = obsCbs || [];
var obsObjs = obsObjs || [];
var cloneObjs = cloneObjs || [];
function newOne(obj){
obsObjs.push(obj);
obsCbs.push([]);
cloneObjs.push(Object.assign({}, obj));
}
module.exports = {
del(obj, cb){
let curObjIdx = obsObjs.indexOf(obj);
if(~curObjIdx){
let cbs = obsCbs[curObjIdx];
let curCbIdx = cbs.indexOf(cb);
if(~curCbIdx){
cbs.splice(curCbIdx, 1);
if(!cbs.length){
obsObjs.splice(curObjIdx, 1);
}
}
}
},
add(obj, cb){
let curIdx = obsObjs.indexOf(obj);
if(!~curIdx){
curIdx = obsObjs.length;
newOne(obj);
}
let cbs = obsCbs[curIdx];
cbs.push(cb);
for(let key in obj){
Object.defineProperty(obj, key, {
set: function(val){
cloneObjs[curIdx][key] = val;
for(let i = 0; i < cbs.length; i++){
cbs[i].apply(obj, [val, key]);
}
},
get: function(){
return cloneObjs[curIdx][key];
}
});
}
return obj;
},
};
import Strophe from "../sdk/libs/strophe";
//import xmldom from "../sdk/libs/xmldom/dom-parser";
import websdk from "../sdk/connection";
import config from "./WebIMConfig";
console.group = console.group || {};
console.groupEnd = console.groupEnd || {};
var window = {};
let WebIM = window.WebIM = websdk;
window.WebIM.config = config;
//var DOMParser = window.DOMParser = xmldom.DOMParser;
//let document = window.document = new DOMParser().parseFromString("<?xml version='1.0'?>\n", "text/xml");
WebIM.isDebug = function(option){
if (option) {
WebIM.config.isDebug = option.isDebug
openDebug(WebIM.config.isDebug)
}
function openDebug(value){
function ts(){
var d = new Date();
var Hours = d.getHours(); // 获取当前小时数(0-23)
var Minutes = d.getMinutes(); // 获取当前分钟数(0-59)
var Seconds = d.getSeconds(); // 获取当前秒数(0-59)
return (Hours < 10 ? "0" + Hours : Hours) + ":" + (Minutes < 10 ? "0" + Minutes : Minutes) + ":" + (Seconds < 10 ? "0" + Seconds : Seconds) + " ";
}
Strophe.Strophe.log = function(level, msg){
// console.log(ts(), level, msg);
};
if (value) {
Strophe.Strophe.Connection.prototype.rawOutput = function(data){
try{
console.group("%csend # " + ts(), "color: blue; font-size: large");
console.log("%c" + data, "color: blue");
console.groupEnd();
}
catch(e){
console.log(e);
}
};
}else{
Strophe.Strophe.Connection.prototype.rawOutput = function(){};
}
}
}
/**
* Set autoSignIn as true (autoSignInName and autoSignInPwd are configured below),
* You can auto signed in each time when you refresh the page in dev model.
*/
WebIM.config.autoSignIn = false;
if(WebIM.config.autoSignIn){
WebIM.config.autoSignInName = "lwz2";
WebIM.config.autoSignInPwd = "1";
}
// var stropheConn = new window.Strophe.Connection("ws://im-api.easemob.com/ws/", {
// inactivity: 30,
// maxRetries: 5,
// pollingTime: 4500
// });
//
// stropheConn.connect(
// '$t$' + 'YWMtmbQEBKKIEeaGmMtXyg5n1wAAAVlkQvGO2WOJGlMCEJKM4VV9GCMnb_XLCXU',
// function() {
// console.log(arguments, 'ggogogo');
// }, stropheConn.wait, stropheConn.hold);
WebIM.parseEmoji = function(msg){
if(typeof WebIM.Emoji === "undefined" || typeof WebIM.Emoji.map === "undefined"){
return msg;
}
var emoji = WebIM.Emoji,
reg = null;
var msgList = [];
var objList = [];
for(var face in emoji.map){
if(emoji.map.hasOwnProperty(face)){
while(msg.indexOf(face) > -1){
msg = msg.replace(face, "^" + emoji.map[face] + "^");
}
}
}
var ary = msg.split("^");
var reg = /^e.*g$/;
for(var i = 0; i < ary.length; i++){
if(ary[i] != ""){
msgList.push(ary[i]);
}
}
for(var i = 0; i < msgList.length; i++){
if(reg.test(msgList[i])){
var obj = {};
obj.data = msgList[i];
obj.type = "emoji";
objList.push(obj);
}
else{
var obj = {};
obj.data = msgList[i];
obj.type = "txt";
objList.push(obj);
}
}
return objList;
};
WebIM.time = function(){
var date = new Date();
var Hours = date.getHours();
var Minutes = date.getMinutes();
var Seconds = date.getSeconds();
var time = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " "
+ (Hours < 10 ? "0" + Hours : Hours) + ":" + (Minutes < 10 ? "0" + Minutes : Minutes) + ":" + (Seconds < 10 ? "0" + Seconds : Seconds);
return time;
};
WebIM.Emoji = {
path: "../../../../../images/faces/",
map: {
"[):]": "ee_1.png",
"[:D]": "ee_2.png",
"[;)]": "ee_3.png",
"[:-o]": "ee_4.png",
"[:p]": "ee_5.png",
"[(H)]": "ee_6.png",
"[:@]": "ee_7.png",
"[:s]": "ee_8.png",
"[:$]": "ee_9.png",
"[:(]": "ee_10.png",
"[:'(]": "ee_11.png",
"[<o)]": "ee_12.png",
"[(a)]": "ee_13.png",
"[8o|]": "ee_14.png",
"[8-|]": "ee_15.png",
"[+o(]": "ee_16.png",
"[|-)]": "ee_17.png",
"[:|]": "ee_18.png",
"[*-)]": "ee_19.png",
"[:-#]": "ee_20.png",
"[^o)]": "ee_21.png",
"[:-*]": "ee_22.png",
"[8-)]": "ee_23.png",
"[del]": "btn_del.png",
"[(|)]": "ee_24.png",
"[(u)]": "ee_25.png",
"[(S)]": "ee_26.png",
"[(*)]": "ee_27.png",
"[(#)]": "ee_28.png",
"[(R)]": "ee_29.png",
"[({)]": "ee_30.png",
"[(})]": "ee_31.png",
"[(k)]": "ee_32.png",
"[(F)]": "ee_33.png",
"[(W)]": "ee_34.png",
"[(D)]": "ee_35.png"
}
};
WebIM.EmojiObj = {
// 相对 emoji.js 路径
path: "../../../../../images/faces/",
map1: {
"[):]": "ee_1.png",
"[:D]": "ee_2.png",
"[;)]": "ee_3.png",
"[:-o]": "ee_4.png",
"[:p]": "ee_5.png",
"[(H)]": "ee_6.png",
"[:@]": "ee_7.png"
},
map2: {
"[:s]": "ee_8.png",
"[:$]": "ee_9.png",
"[:(]": "ee_10.png",
"[:'(]": "ee_11.png",
"[<o)]": "ee_12.png",
"[(a)]": "ee_13.png",
"[8o|]": "ee_14.png"
},
map3: {
"[8-|]": "ee_15.png",
"[+o(]": "ee_16.png",
"[|-)]": "ee_17.png",
"[:|]": "ee_18.png",
"[*-)]": "ee_19.png",
"[:-#]": "ee_20.png",
"[del]": "del.png"
},
map4: {
"[^o)]": "ee_21.png",
"[:-*]": "ee_22.png",
"[8-)]": "ee_23.png",
"[(|)]": "ee_24.png",
"[(u)]": "ee_25.png",
"[(S)]": "ee_26.png",
"[(*)]": "ee_27.png"
},
map5: {
"[(#)]": "ee_28.png",
"[(R)]": "ee_29.png",
"[({)]": "ee_30.png",
"[(})]": "ee_31.png",
"[(k)]": "ee_32.png",
"[(F)]": "ee_33.png",
"[(W)]": "ee_34.png",
"[(D)]": "ee_35.png"
},
map6: {
"[del]": "del.png"
}
};
// wx.connectSocket({url: WebIM.config.xmppURL, method: "GET"})
WebIM.conn = new WebIM.connection({
isMultiLoginSessions: WebIM.config.isMultiLoginSessions,
https: typeof WebIM.config.https === "boolean" ? WebIM.config.https : location.protocol === "https:",
url: WebIM.config.xmppURL,
apiUrl: WebIM.config.apiURL,
isAutoLogin: false,
heartBeatWait: WebIM.config.heartBeatWait,
autoReconnectNumMax: WebIM.config.autoReconnectNumMax,
autoReconnectInterval: WebIM.config.autoReconnectInterval
});
// async response
// WebIM.conn.listen({
// onOpened: () => dispatch({type: Types.ON_OPEND})
// })
// export default WebIM;
module.exports = {
"default": WebIM
};
/**
* git do not control webim.config.js
* everyone should copy webim.config.js to webim.config.js
* and have their own configs.
* In this way , others won't be influenced by this config while git pull.
*
*/
// for react native
let location = {
protocol: "https"
};
let config = {
/*
* XMPP server
*/
xmppURL: "wss://im-api.easemob.com/ws/",
// xmppURL: '172.17.3.122:5280',
/*
* Backend REST API URL
*/
// apiURL: (location.protocol === 'https:' ? 'https:' : 'http:') + '//a1.easemob.com',
// ios must be https!!! by lwz
apiURL: "https://a1.easemob.com",
// apiURL: (location.protocol === 'https:' ? 'https:' : 'http:') + '//172.17.3.155:8080',
/*
* Application AppKey
*/
appkey: "easemob-demo#chatdemoui",
/*
* Whether to use HTTPS '1177161227178308#xcx'
* @parameter {Boolean} true or false
*/
https: false,
/*
* isMultiLoginSessions
* true: A visitor can sign in to multiple webpages and receive messages at all the webpages.
* false: A visitor can sign in to only one webpage and receive messages at the webpage.
*/
isMultiLoginSessions: false,
/**
* Whether to use window.doQuery()
* @parameter {Boolean} true or false
*/
isWindowSDK: false,
/**
* isSandBox=true: xmppURL: 'im-api.sandbox.easemob.com', apiURL: '//a1.sdb.easemob.com',
* isSandBox=false: xmppURL: 'im-api.easemob.com', apiURL: '//a1.easemob.com',
* @parameter {Boolean} true or false
*/
isSandBox: false,
/**
* Whether to console.log in strophe.log()
* @parameter {Boolean} true or false
*/
isDebug: false,
/**
* will auto connect the xmpp server autoReconnectNumMax times in background when client is offline.
* won't auto connect if autoReconnectNumMax=0.
*/
autoReconnectNumMax: 15,
/**
* the interval secons between each atuo reconnectting.
* works only if autoReconnectMaxNum >= 2.
*/
autoReconnectInterval: 2,
/**
* webrtc supports WebKit and https only
*/
isWebRTC: false,
/*
* Set to auto sign-in
*/
isAutoLogin: true
};
export default config;
var Dispatcher = require("./Dispatcher");
module.exports = new Dispatcher();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment