Browse Source

消息转义优化

master
xsx 9 months ago
parent
commit
4625f84d4b
  1. 14
      im-uniapp/common/str.js
  2. 7
      im-uniapp/components/chat-item/chat-item.vue
  3. 3
      im-uniapp/components/chat-message-item/chat-message-item.vue
  4. 66
      im-uniapp/main.js
  5. 12
      im-uniapp/pages/chat/chat-box.vue
  6. 14
      im-web/src/api/str.js
  7. 12
      im-web/src/components/chat/ChatInput.vue
  8. 2
      im-web/src/components/chat/ChatItem.vue
  9. 3
      im-web/src/components/chat/ChatMessageItem.vue
  10. 2
      im-web/src/main.js

14
im-uniapp/common/str.js

@ -0,0 +1,14 @@
let html2Escape = (strText) => {
return strText.replace(/[<>&"]/g, function(c) {
return {
'<': '&lt;',
'>': '&gt;',
'&': '&amp;',
'"': '&quot;'
} [c];
});
}
export default {
html2Escape
}

7
im-uniapp/components/chat-item/chat-item.vue

@ -16,8 +16,7 @@
<view class="chat-at-text">{{ atText }}</view> <view class="chat-at-text">{{ atText }}</view>
<view class="chat-send-name" v-if="isShowSendName">{{ chat.sendNickName + ':&nbsp;' }}</view> <view class="chat-send-name" v-if="isShowSendName">{{ chat.sendNickName + ':&nbsp;' }}</view>
<view v-if="!isTextMessage" class="chat-content-text">{{chat.lastContent}}</view> <view v-if="!isTextMessage" class="chat-content-text">{{chat.lastContent}}</view>
<rich-text v-else class="chat-content-text" <rich-text v-else class="chat-content-text" :nodes="nodesText"></rich-text>
:nodes="$emo.transform(chat.lastContent,'emoji-small')"></rich-text>
<view v-if="chat.isDnd" class="icon iconfont icon-dnd"></view> <view v-if="chat.isDnd" class="icon iconfont icon-dnd"></view>
<uni-badge v-else-if="chat.unreadCount > 0" :max-num="99" :text="chat.unreadCount" /> <uni-badge v-else-if="chat.unreadCount > 0" :max-num="99" :text="chat.unreadCount" />
</view> </view>
@ -84,6 +83,10 @@ export default {
let messageType = this.chat.messages[idx].type; let messageType = this.chat.messages[idx].type;
return messageType == this.$enums.MESSAGE_TYPE.TEXT; return messageType == this.$enums.MESSAGE_TYPE.TEXT;
}, },
nodesText() {
let text = this.$str.html2Escape(this.chat.lastContent);
return this.$emo.transform(text, 'emoji-small')
}
} }
} }
</script> </script>

3
im-uniapp/components/chat-message-item/chat-message-item.vue

@ -236,7 +236,8 @@ export default {
}, },
nodesText() { nodesText() {
let color = this.msgInfo.selfSend ? 'white' : ''; let color = this.msgInfo.selfSend ? 'white' : '';
let text = this.$url.replaceURLWithHTMLLinks(this.msgInfo.content, color) let text = this.$str.html2Escape(this.msgInfo.content)
text = this.$url.replaceURLWithHTMLLinks(text, color)
return this.$emo.transform(text, 'emoji-normal') return this.$emo.transform(text, 'emoji-normal')
} }
} }

66
im-uniapp/main.js

@ -2,7 +2,8 @@ import App from './App'
import request from './common/request'; import request from './common/request';
import emotion from './common/emotion.js'; import emotion from './common/emotion.js';
import url from './common/url.js'; import url from './common/url.js';
import * as enums from './common/enums.js'; import str from './common/str.js';
import * as enums from './common/enums.js';
import * as date from './common/date'; import * as date from './common/date';
import * as socketApi from './common/wssocket'; import * as socketApi from './common/wssocket';
import * as messageType from './common/messageType'; import * as messageType from './common/messageType';
@ -21,10 +22,10 @@ import switchBar from '@/components/bar/switch-bar'
// #ifdef H5 // #ifdef H5
import * as recorder from './common/recorder-h5'; import * as recorder from './common/recorder-h5';
import ImageResize from "quill-image-resize-mp"; import ImageResize from "quill-image-resize-mp";
import Quill from "quill"; import Quill from "quill";
// 以下组件用于兼容部分手机聊天边框无法输入的问题 // 以下组件用于兼容部分手机聊天边框无法输入的问题
window.Quill = Quill; window.Quill = Quill;
window.ImageResize = { default: ImageResize }; window.ImageResize = { default: ImageResize };
// 调试器 // 调试器
// import VConsole from 'vconsole' // import VConsole from 'vconsole'
// new VConsole(); // new VConsole();
@ -33,31 +34,32 @@ window.ImageResize = { default: ImageResize };
import * as recorder from './common/recorder-app'; import * as recorder from './common/recorder-app';
// #endif // #endif
export function createApp() { export function createApp() {
const app = createSSRApp(App) const app = createSSRApp(App)
app.use(uviewPlus); app.use(uviewPlus);
app.use(pinia.createPinia()); app.use(pinia.createPinia());
app.component('bar-group', barGroup); app.component('bar-group', barGroup);
app.component('arrow-bar', arrowBar); app.component('arrow-bar', arrowBar);
app.component('btn-bar', btnBar); app.component('btn-bar', btnBar);
app.component('switch-bar', switchBar); app.component('switch-bar', switchBar);
app.config.globalProperties.$http = request; app.config.globalProperties.$http = request;
app.config.globalProperties.$wsApi = socketApi; app.config.globalProperties.$wsApi = socketApi;
app.config.globalProperties.$msgType = messageType; app.config.globalProperties.$msgType = messageType;
app.config.globalProperties.$emo = emotion; app.config.globalProperties.$emo = emotion;
app.config.globalProperties.$url = url; app.config.globalProperties.$url = url;
app.config.globalProperties.$enums = enums; app.config.globalProperties.$str = str;
app.config.globalProperties.$date = date; app.config.globalProperties.$enums = enums;
app.config.globalProperties.$rc = recorder; app.config.globalProperties.$date = date;
// 初始化时再挂载store对象 app.config.globalProperties.$rc = recorder;
app.config.globalProperties.$mountStore = () => { // 初始化时再挂载store对象
app.config.globalProperties.chatStore = useChatStore(); app.config.globalProperties.$mountStore = () => {
app.config.globalProperties.friendStore = useFriendStore(); app.config.globalProperties.chatStore = useChatStore();
app.config.globalProperties.groupStore = useGroupStore(); app.config.globalProperties.friendStore = useFriendStore();
app.config.globalProperties.configStore = useConfigStore(); app.config.globalProperties.groupStore = useGroupStore();
app.config.globalProperties.userStore = useUserStore(); app.config.globalProperties.configStore = useConfigStore();
} app.config.globalProperties.userStore = useUserStore();
return { }
app, return {
pinia app,
} pinia
} }
}

12
im-uniapp/pages/chat/chat-box.vue

@ -299,7 +299,7 @@ export default {
let receiptText = this.isReceipt ? "【回执消息】" : ""; let receiptText = this.isReceipt ? "【回执消息】" : "";
let atText = this.createAtText(); let atText = this.createAtText();
let msgInfo = { let msgInfo = {
content: receiptText + this.html2Escape(sendText) + atText, content: receiptText + sendText + atText,
atUserIds: this.atUserIds, atUserIds: this.atUserIds,
receipt: this.isReceipt, receipt: this.isReceipt,
type: 0 type: 0
@ -735,16 +735,6 @@ export default {
let px = info.windowWidth * rpx / 750; let px = info.windowWidth * rpx / 750;
return Math.floor(rpx); return Math.floor(rpx);
}, },
html2Escape(strHtml) {
return strHtml.replace(/[<>&"]/g, function(c) {
return {
'<': '&lt;',
'>': '&gt;',
'&': '&amp;',
'"': '&quot;'
} [c];
});
},
sendMessageRequest(msgInfo) { sendMessageRequest(msgInfo) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// "" // ""

14
im-web/src/api/str.js

@ -0,0 +1,14 @@
let html2Escape = (strText) => {
return strText.replace(/[<>&"]/g, function(c) {
return {
'<': '&lt;',
'>': '&gt;',
'&': '&amp;',
'"': '&quot;'
} [c];
});
}
export default {
html2Escape
}

12
im-web/src/components/chat/ChatInput.vue

@ -367,16 +367,6 @@ export default {
// //
this.updateRange(); this.updateRange();
}, },
html2Escape(strHtml) {
return strHtml.replace(/[<>&"]/g, function(c) {
return {
'<': '&lt;',
'>': '&gt;',
'&': '&amp;',
'"': '&quot;'
} [c];
});
},
submit() { submit() {
let nodes = this.$refs.content.childNodes; let nodes = this.$refs.content.childNodes;
let fullList = []; let fullList = [];
@ -389,7 +379,7 @@ export default {
continue; continue;
} }
if (node.nodeType === 3) { if (node.nodeType === 3) {
tempText += this.html2Escape(node.textContent); tempText += node.textContent;
continue; continue;
} }
let nodeName = node.nodeName.toLowerCase(); let nodeName = node.nodeName.toLowerCase();

2
im-web/src/components/chat/ChatItem.vue

@ -16,7 +16,7 @@
<div class="chat-content"> <div class="chat-content">
<div class="chat-at-text">{{ atText }}</div> <div class="chat-at-text">{{ atText }}</div>
<div class="chat-send-name" v-show="isShowSendName">{{ chat.sendNickName + ':&nbsp;' }}</div> <div class="chat-send-name" v-show="isShowSendName">{{ chat.sendNickName + ':&nbsp;' }}</div>
<div class="chat-content-text" v-html="$emo.transform(chat.lastContent, 'emoji-small')"></div> <div class="chat-content-text" v-html="$emo.transform($str.html2Escape(chat.lastContent), 'emoji-small')"></div>
<div class="icon iconfont icon-dnd" v-if="chat.isDnd"></div> <div class="icon iconfont icon-dnd" v-if="chat.isDnd"></div>
</div> </div>
</div> </div>

3
im-web/src/components/chat/ChatMessageItem.vue

@ -193,7 +193,8 @@ export default {
}, },
htmlText() { htmlText() {
let color = this.msgInfo.selfSend ? 'white' : ''; let color = this.msgInfo.selfSend ? 'white' : '';
let text = this.$url.replaceURLWithHTMLLinks(this.msgInfo.content, color) let text = this.$str.html2Escape(this.msgInfo.content)
text = this.$url.replaceURLWithHTMLLinks(text, color)
return this.$emo.transform(text, 'emoji-normal') return this.$emo.transform(text, 'emoji-normal')
} }
} }

2
im-web/src/main.js

@ -10,6 +10,7 @@ import * as socketApi from './api/wssocket';
import * as messageType from './api/messageType'; import * as messageType from './api/messageType';
import emotion from './api/emotion.js'; import emotion from './api/emotion.js';
import url from './api/url.js'; import url from './api/url.js';
import str from './api/str.js';
import element from './api/element.js'; import element from './api/element.js';
import * as enums from './api/enums.js'; import * as enums from './api/enums.js';
import * as date from './api/date.js'; import * as date from './api/date.js';
@ -31,6 +32,7 @@ Vue.prototype.$date = date;
Vue.prototype.$http = httpRequest // http请求方法 Vue.prototype.$http = httpRequest // http请求方法
Vue.prototype.$emo = emotion; // emo表情 Vue.prototype.$emo = emotion; // emo表情
Vue.prototype.$url = url; // url转换 Vue.prototype.$url = url; // url转换
Vue.prototype.$str = str; // 字符串相关
Vue.prototype.$elm = element; // 元素操作 Vue.prototype.$elm = element; // 元素操作
Vue.prototype.$enums = enums; // 枚举 Vue.prototype.$enums = enums; // 枚举
Vue.prototype.$eventBus = new Vue(); // 全局事件 Vue.prototype.$eventBus = new Vue(); // 全局事件

Loading…
Cancel
Save