diff --git a/src/blog/blog.js b/src/blog/blog.js index a0721e706a0035690b7f0e7aae2b6d664fe08fe6..8a061530e5f9fe7ac495d845f45e074441433bc2 100644 --- a/src/blog/blog.js +++ b/src/blog/blog.js @@ -44,8 +44,8 @@ export class Blog { // var socket = new SockJS('http://localhost:8080/ws'); let socket = new SockJS('/ws'); window.stompClient = Stomp.over(socket); - // window.stompClient.debug = () => {}; - stompClient.debug = (msg) => { console.log(msg) }; + window.stompClient.debug = () => {}; + // stompClient.debug = (msg) => { console.log(msg) }; window.stompClient.connect({}, (frame) => { // 注册发送消息 stompClient.subscribe('/blog/update', (msg) => { diff --git a/src/chat/chat.js b/src/chat/chat.js index a86993965d78ba97123fb4318c4b38bcb687f3b8..43d9e8b3fb9513dbc770553e896743312eeb873d 100644 --- a/src/chat/chat.js +++ b/src/chat/chat.js @@ -60,8 +60,8 @@ export class Chat { // var socket = new SockJS('http://localhost:8080/ws'); let socket = new SockJS('/ws'); window.stompClient = Stomp.over(socket); - // window.stompClient.debug = () => {}; - stompClient.debug = (msg) => { console.log(msg) }; + window.stompClient.debug = () => {}; + // stompClient.debug = (msg) => { console.log(msg) }; window.stompClient.connect({}, (frame) => { // 同步在线用户 this.getOnlineUsers(); @@ -1084,7 +1084,7 @@ export class Chat { scrollToAfterImgLoaded(to) { _.defer(() => { - new ImagesLoaded(this.commentsRef).always(() => { + this.commentsRef && new ImagesLoaded(this.commentsRef).always(() => { this._scrollTo(to); }); diff --git a/src/common/common-imgs-loaded.js b/src/common/common-imgs-loaded.js index 47a67fcfecd85dd2258260e5ca64b221038011cc..536131bf4e1e202cb9d3f3e2c03a61198f2638ec 100644 --- a/src/common/common-imgs-loaded.js +++ b/src/common/common-imgs-loaded.js @@ -132,9 +132,9 @@ function listener(element, eventName, handler, remove) { var events = eventName.split(' '); for (var i = 0, l = events.length; i < l; i++) { - if (element.addEventListener) { + if (element && element.addEventListener) { element[remove ? 'removeEventListener' : 'addEventListener'](events[i], handler, false); - } else if (element.attachEvent) { + } else if (element && element.attachEvent) { element[remove ? 'detachEvent' : 'attachEvent']('on' + events[i], handler); } } diff --git a/src/main.js b/src/main.js index 68083779bad86c11adc759fca8618e6eb14906a6..dc46de4b3aab25b2e67b7decf0afd4a78d1f7cc2 100644 --- a/src/main.js +++ b/src/main.js @@ -8,6 +8,8 @@ Promise.config({ } }); +// window.__debug = true; + export function configure(aurelia) { aurelia.use .standardConfiguration() diff --git a/src/resources/attributes/attr-attr.js b/src/resources/attributes/attr-attr.js index 537cbe6a6fc2edf9d50e469dc7cfe3dcc81cf919..7db9ef25f7a63f9378c0500e27002810af5df64a 100644 --- a/src/resources/attributes/attr-attr.js +++ b/src/resources/attributes/attr-attr.js @@ -30,5 +30,7 @@ export class AttrAttr { this.valueChanged(this.value); } - unbind() {} + unbind() { + this.element = null; + } } diff --git a/src/resources/attributes/attr-autosize.js b/src/resources/attributes/attr-autosize.js index 45afcf22590f37c78742ae192e9e459425458fad..c7e5a101883faa75d3b761b0128788c191b03232 100644 --- a/src/resources/attributes/attr-autosize.js +++ b/src/resources/attributes/attr-autosize.js @@ -21,6 +21,8 @@ export class AttrAutosize { * 当数据绑定引擎从视图解除绑定时被调用 */ unbind() { - autosize.destroy(this.elements) + window.__debug && console.log('AttrAutosize--unbind'); + autosize.destroy(this.element); + this.element = null; } } diff --git a/src/resources/attributes/attr-c2c.js b/src/resources/attributes/attr-c2c.js index c829f4728e8cf7d372c9cca39b4505babed2b3b2..92debfb37372c8dd6229ac5f025bd88e792fd9dc 100644 --- a/src/resources/attributes/attr-c2c.js +++ b/src/resources/attributes/attr-c2c.js @@ -37,6 +37,9 @@ export class AttrC2cCustomAttribute { } unbind() { + window.__debug && console.log('AttrC2cCustomAttribute--unbind'); this.clipboard && this.clipboard.destroy(); + this.clipboard = null; + this.element = null; } } diff --git a/src/resources/attributes/attr-dimmer.js b/src/resources/attributes/attr-dimmer.js index 0e1076ff30323542ae76b83882cdcc1292bc2a9d..565b754ff1393cf652bfabddd5029134617faafa 100644 --- a/src/resources/attributes/attr-dimmer.js +++ b/src/resources/attributes/attr-dimmer.js @@ -23,4 +23,11 @@ export class AttrDimmer { this.valueChanged(this.value); } + unbind() { + window.__debug && console.log('AttrDimmer--unbind'); + this.$dimmer && this.$dimmer.remove(); + this.$dimmer = null; + this.element = null; + } + } diff --git a/src/resources/attributes/attr-dropzone.js b/src/resources/attributes/attr-dropzone.js index a9242d1240d202d60bf99a91257c56e0be5dee97..f79cb2ac8aa2bd874a1711f46349a7e414c37678 100644 --- a/src/resources/attributes/attr-dropzone.js +++ b/src/resources/attributes/attr-dropzone.js @@ -105,6 +105,7 @@ export class AttrDropzone { * 当数据绑定引擎从视图解除绑定时被调用 */ unbind() { + window.__debug && console.log('AttrDropzone--unbind'); try { $.each(this.dropzones, (i, dropzone) => { dropzone.destroy(); @@ -112,5 +113,10 @@ export class AttrDropzone { } catch (e) { console.log(e); } + this.target = null; + this.dropzones = []; + this.eventAggregator = null; + this.subscribe.dispose(); + // Dropzone = null; } } diff --git a/src/resources/attributes/attr-fancybox.js b/src/resources/attributes/attr-fancybox.js index 040e6f682b6a98afe73e8198f993f967ba66e6c9..9f01a6deddcaad1a6a3aa8cb5714b2e09eef000b 100644 --- a/src/resources/attributes/attr-fancybox.js +++ b/src/resources/attributes/attr-fancybox.js @@ -11,7 +11,8 @@ export class AttrFancyboxCustomAttribute { } valueChanged(newValue, oldValue) { - $(this.element).on('click', 'img', (event) => { + + this.imgHandler = (event) => { event.preventDefault(); let $img = $(event.target); var imgs = []; @@ -23,6 +24,7 @@ export class AttrFancyboxCustomAttribute { } }); + // https://fancyapps.com/fancybox/3/docs/#api $.fancybox.open(imgs, { i18n: { 'zh': { @@ -56,10 +58,21 @@ export class AttrFancyboxCustomAttribute { ], }, initialIndexOnArray); - }); + }; + + $(this.element).on('click', 'img', this.imgHandler); } bind(bindingContext) { this.valueChanged(this.value); } + + unbind() { + window.__debug && console.log('AttrFancyboxCustomAttribute--unbind'); + $(this.element).off('click', 'img', this.imgHandler); + this.imgHandler = null; + this.element = null; + + $.fancybox.destroy(); + } } diff --git a/src/resources/attributes/attr-modaal.js b/src/resources/attributes/attr-modaal.js index 417772afc74be52e528762d60828a7bd94951031..cfc92ab21a04dff9836aadf303d74fb6885c831e 100644 --- a/src/resources/attributes/attr-modaal.js +++ b/src/resources/attributes/attr-modaal.js @@ -44,4 +44,10 @@ export class AttrModaalCustomAttribute { }); } + + unbind() { + window.__debug && console.log('AttrModaalCustomAttribute--unbind'); + $(this.element).modaal('close'); + this.element = null; + } } diff --git a/src/resources/attributes/attr-pastable.js b/src/resources/attributes/attr-pastable.js index f3e91a30246b0abd505c9b1820f9fba8a27b80db..5bd91914767f731d170a18c0c7a4cc0494c7630b 100644 --- a/src/resources/attributes/attr-pastable.js +++ b/src/resources/attributes/attr-pastable.js @@ -12,8 +12,8 @@ export class AttrPastable { } valueChanged(newValue, oldValue) { - // clipboard paste image - $(this.element).pastableTextarea().on('pasteImage', (ev, data) => { + + this.pasteHandler = (ev, data) => { $.post('/admin/file/base64', { dataURL: data.dataURL, @@ -29,12 +29,27 @@ export class AttrPastable { .replace(/\{uuidName\}/g, data.data.uuidName)); } }); - }).on('pasteImageError', (ev, data) => { + }; + + this.errHandler = (ev, data) => { toastr.error(data.message, '剪贴板粘贴图片错误!'); - }); + }; + + // https://github.com/layerssss/paste.js + // clipboard paste image + $(this.element).pastableTextarea().on('pasteImage', this.pasteHandler).on('pasteImageError', this.errHandler); } bind(bindingContext) { this.valueChanged(this.value); } + + unbind() { + window.__debug && console.log('AttrPastable--unbind'); + $(this.element).pastableTextarea().off('pasteImage', this.pasteHandler).off('pasteImageError', this.errHandler); + this.element = null; + this.pasteHandler = null; + this.errHandler = null; + + } } diff --git a/src/resources/attributes/attr-scrollbar.js b/src/resources/attributes/attr-scrollbar.js index 700a1326a28069e51fc207c4b09dfd11320fc1a1..4fd20a6dd14f37ac99b5628a2aae80b2e1a078cd 100644 --- a/src/resources/attributes/attr-scrollbar.js +++ b/src/resources/attributes/attr-scrollbar.js @@ -29,8 +29,12 @@ export class AttrScrollbarCustomAttribute { * 当数据绑定引擎从视图解除绑定时被调用 */ unbind() { + + window.__debug && console.log('AttrScrollbarCustomAttribute--unbind'); try { jQuery(this.element).removeClass(this.cls).scrollbar('destroy'); } catch (err) {} + + this.element = null; } } diff --git a/src/resources/attributes/attr-tablesort.js b/src/resources/attributes/attr-tablesort.js index d7fb29076a1b79f1a09a51ac4a7f4fda4f274c0a..1b78015536dc34b774ff7d1389ae9ec40638d3e5 100644 --- a/src/resources/attributes/attr-tablesort.js +++ b/src/resources/attributes/attr-tablesort.js @@ -14,13 +14,26 @@ export class AttrTablesortCustomAttribute { _init() { if ($(this.element).is('table')) { + // https://github.com/kylefox/jquery-tablesort $(this.element).addClass('sortable').tablesort(); + this.tablesort = $(this.element).data('tablesort'); } else { - console.warn('tablesort element is not table tag!'); + console.warn('tablesort element is not table tag!'); } } bind() { - this._init(); + this._init(); + } + + unbind() { + + window.__debug && console.log('AttrTablesortCustomAttribute--unbind'); + + this.tablesort && this.tablesort.destroy(); + + this.element = null; + this.tablesort = null; + } } diff --git a/src/resources/attributes/attr-task.js b/src/resources/attributes/attr-task.js index 7ab7464abec1baf85af7c18406bbf69ec057b34c..c1100aa2fe23005f0253f9cfd929ec49e124e95d 100644 --- a/src/resources/attributes/attr-task.js +++ b/src/resources/attributes/attr-task.js @@ -32,6 +32,7 @@ export class AttrTask { } unbind() { + window.__debug && console.log('AttrTask--unbind'); this.element = null; this.task = null; this.bindingCtx = null; diff --git a/src/resources/attributes/attr-textcomplete.js b/src/resources/attributes/attr-textcomplete.js index 5cf58b92f2c19793759d0620e5bc8d033ca5d171..fefba2423ef9323a663a74b6492639126337a8bc 100644 --- a/src/resources/attributes/attr-textcomplete.js +++ b/src/resources/attributes/attr-textcomplete.js @@ -26,9 +26,12 @@ export class AttrTextcompleteCustomAttribute { } valueChanged() { + if (this.value) { this.members = this.value.users; this.channel = this.value.channel; + + // https://github.com/yuku/jquery-textcomplete $(this.element).textcomplete([{ // chat msg help match: /(|\b)(\/.*)$/, search: (term, callback) => { @@ -120,8 +123,12 @@ export class AttrTextcompleteCustomAttribute { initHotkeys() { + this.keydowns = []; + _.each(_.filter(_.values(tips), 'key'), (value) => { - $(this.element).bind('keydown', value.key, (evt) => { + + let key = value.key; + let handler = (evt) => { evt.preventDefault(); $(this.element).insertAtCaret(value.value); let cr = utils.getCursortPosition(this.element); @@ -130,14 +137,34 @@ export class AttrTextcompleteCustomAttribute { _.defer(() => { autosize.update(this.element); }); + }; + + this.keydowns.push({ + key: key, + handler: handler }); + + $(this.element).bind('keydown', key, handler); }); } unbind() { + + window.__debug && console.log('AttrTextcompleteCustomAttribute--unbind'); + try { $(this.element).textcomplete('destroy'); } catch (err) {} + + + _.each(this.keydowns, (item) => { + $(this.element).unbind('keydown', item.handler); + }); + + this.members = null; + this.channel = null; + this.element = null; + this.keydowns = []; } } diff --git a/src/resources/attributes/attr-ui-checkbox.js b/src/resources/attributes/attr-ui-checkbox.js index f9ad7eda07bf6ca1adc80a131ba00f21d5404a0b..ca03d5af62157088b842244914f2fc28242d4b0f 100644 --- a/src/resources/attributes/attr-ui-checkbox.js +++ b/src/resources/attributes/attr-ui-checkbox.js @@ -12,4 +12,8 @@ export class AttrUiCheckboxCustomAttribute { valueChanged(newValue, oldValue) { $(this.element).checkbox(); } + + unbind() { + this.element = null; + } } diff --git a/src/resources/attributes/attr-ui-dropdown-action.js b/src/resources/attributes/attr-ui-dropdown-action.js index c8c9aca3856ea1180689edab535774ad54cbecc9..7e4aabeec795a66aad74c8b5ca171dcfb7cc58c9 100644 --- a/src/resources/attributes/attr-ui-dropdown-action.js +++ b/src/resources/attributes/attr-ui-dropdown-action.js @@ -24,4 +24,8 @@ export class AttrUiDropdownActionCustomAttribute { bind() { this._init(this.value ? this.value : window); } + + unbind() { + this.element = null; + } } diff --git a/src/resources/attributes/attr-ui-dropdown-hover-action.js b/src/resources/attributes/attr-ui-dropdown-hover-action.js index fee6b5f02591c37c16516e96e7b8ecb4c9259f2c..5c757a249de312490d78f8f84af34e81ff978dd2 100644 --- a/src/resources/attributes/attr-ui-dropdown-hover-action.js +++ b/src/resources/attributes/attr-ui-dropdown-hover-action.js @@ -25,4 +25,8 @@ export class AttrUiDropdownHoverActionCustomAttribute { bind() { this._init(this.value ? this.value : window); } + + unbind() { + this.element = null; + } } diff --git a/src/resources/attributes/attr-ui-dropdown-hover.js b/src/resources/attributes/attr-ui-dropdown-hover.js index 4ffdf22ea6f2e04c9557692b64d217f27d5ad3db..ea2f0b32e67fec576123379542e912b6a9b5950c 100644 --- a/src/resources/attributes/attr-ui-dropdown-hover.js +++ b/src/resources/attributes/attr-ui-dropdown-hover.js @@ -24,4 +24,8 @@ export class AttrUiDropdownHoverCustomAttribute { bind() { this._init(this.value ? this.value : 'hide'); } + + unbind() { + this.element = null; + } } diff --git a/src/resources/attributes/attr-ui-dropdown.js b/src/resources/attributes/attr-ui-dropdown.js index 1592b20eece7acab46fc3363362f942275e977cb..193abb4fd64bc2518e0fa37c5b3b5dfd5938ba2e 100644 --- a/src/resources/attributes/attr-ui-dropdown.js +++ b/src/resources/attributes/attr-ui-dropdown.js @@ -23,4 +23,8 @@ export class AttrUiDropdownCustomAttribute { bind() { this._init(this.value ? this.value : 'hide'); } + + unbind() { + this.element = null; + } } diff --git a/src/resources/attributes/attr-ui-popup.js b/src/resources/attributes/attr-ui-popup.js index 6f1513c10dadfe831b5b0f47b6cd64a97b82a13c..f788a429644620bb60ecaeb77c69ef43f2efd519 100644 --- a/src/resources/attributes/attr-ui-popup.js +++ b/src/resources/attributes/attr-ui-popup.js @@ -32,4 +32,9 @@ export class AttrUiPopupCustomAttribute { }); } + + unbind() { + $(this.element).popup('destroy'); + this.element = null; + } } diff --git a/src/resources/attributes/attr-ui-pp.js b/src/resources/attributes/attr-ui-pp.js index fbc5a64edaed6be76192952ddc9a235566715dc9..e7cff890f44a05038b580fccb455657f32690cd1 100644 --- a/src/resources/attributes/attr-ui-pp.js +++ b/src/resources/attributes/attr-ui-pp.js @@ -17,4 +17,9 @@ export class AttrUiPpCustomAttribute { }); } -} \ No newline at end of file + + unbind() { + $(this.element).popup('destroy'); + this.element = null; + } +} diff --git a/src/resources/attributes/attr-ui-tab.js b/src/resources/attributes/attr-ui-tab.js index a30a132585e58e851cd3a0186b3726b2d380aad8..fbb6c9343ea979c9eaa94ae8cc5fcd8c1d38933b 100644 --- a/src/resources/attributes/attr-ui-tab.js +++ b/src/resources/attributes/attr-ui-tab.js @@ -21,4 +21,8 @@ export class AttrUiTabCustomAttribute { bind() { this._init(); } + + unbind() { + this.element = null; + } } diff --git a/src/resources/elements/em-blog-comment.js b/src/resources/elements/em-blog-comment.js index a98050047cc2ea8a2a08470210028d0196e386f3..127927d41e96fbd984f7499e7125cb9d0735211c 100644 --- a/src/resources/elements/em-blog-comment.js +++ b/src/resources/elements/em-blog-comment.js @@ -18,7 +18,7 @@ export class EmBlogComment { offset = 0; isSuper = nsCtx.isSuper; loginUser = nsCtx.loginUser; - users = nsCtx.users; + users; @bindable blog; @@ -26,6 +26,77 @@ export class EmBlogComment { this._refresh(); } + bind() { + this.users = nsCtx.users; + } + + detached() { + window.__debug && console.log('EmBlogComment--detached'); + + this.comments = null; + this.users = null; + this.blog = null; + this.focusedComment = null; + + // 消息popup + $('.em-blog-comment .comments').off('mouseenter', '.markdown-body a[href*="#/blog/"]:not(.pp-not)', this.blogCommentMeHandler); + $('.em-blog-comment .comments').off('mouseleave', '.markdown-body a[href*="#/blog/"]:not(.pp-not)', this.blogCommentMlHandler); + this.blogCommentMeHandler = null; + this.blogCommentMlHandler = null; + + $('.em-blog-comment .comments').off('dblclick', '.comment', this.commentsDblHandler); + $('.em-blog-comment .comments').off('click', '.comment', this.commentsClHandler); + this.commentsDblHandler = null; + this.commentsClHandler = null; + + $(document).unbind('keydown', this.kdRHandler).unbind('keydown', this.kdAltUpHandler).unbind('keydown', this.kdAltDownHandler); + this.kdRHandler = null; + this.kdAltUpHandler = null; + this.kdAltDownHandler = null; + + if (this.$paste) { + this.$paste.off('pasteImage', this.pasteHandler).off('pasteImageError', this.errHandler); + this.pasteHandler = null; + this.errHandler = null; + + this.$paste = null; + } + + $('.CodeMirror-wrap', this.markdownRef).each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + + $('.editor-toolbar .fa.fa-upload', this.markdownRef).each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + + $('.editor-toolbar .fa.fa-file-excel-o', this.markdownRef).each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + this.markdownRef = null; + + try { + + if (this.simplemde) { + this.simplemde.codemirror.off('keyup', this.editKeyHandler); + this.editKeyHandler = null; + + // https://github.com/sparksuite/simplemde-markdown-editor + this.simplemde.toTextArea(); + this.simplemde = null; + } + + $(this.$chatMsgInputRef).textcomplete('destroy'); + this.$chatMsgInputRef = null; + } catch (err) { + console.error(err); + } + + } + /** * 构造函数 */ @@ -174,8 +245,7 @@ export class EmBlogComment { attached() { this._init(); - // 消息popup - $('.em-blog-comment .comments').on('mouseenter', '.markdown-body a[href*="#/blog/"]:not(.pp-not)', (event) => { + this.blogCommentMeHandler = (event) => { event.preventDefault(); let target = event.currentTarget; @@ -199,10 +269,9 @@ export class EmBlogComment { this.hoverTimeoutRef = null; }, 500); - }); + }; - // 消息popup - $('.em-blog-comment .comments').on('mouseleave', '.markdown-body a[href*="#/blog/"]:not(.pp-not)', (event) => { + this.blogCommentMlHandler = (event) => { event.preventDefault(); if (this.hoverTimeoutRef) { if (this.hoverUserTarget === event.currentTarget) { @@ -210,9 +279,13 @@ export class EmBlogComment { this.hoverTimeoutRef = null; } } - }); + }; - $('.em-blog-comment .comments').on('dblclick', '.comment', (event) => { + // 消息popup + $('.em-blog-comment .comments').on('mouseenter', '.markdown-body a[href*="#/blog/"]:not(.pp-not)', this.blogCommentMeHandler); + $('.em-blog-comment .comments').on('mouseleave', '.markdown-body a[href*="#/blog/"]:not(.pp-not)', this.blogCommentMlHandler); + + this.commentsDblHandler = (event) => { if (event.ctrlKey && event.shiftKey) { let cid = $(event.currentTarget).attr('data-id'); let $t = $(event.currentTarget).find('.content > textarea'); @@ -221,33 +294,43 @@ export class EmBlogComment { this.editHandler(item, $t); } } - }); + }; - $('.em-blog-comment .comments').on('click', '.comment', (event) => { + this.commentsClHandler = (event) => { this.focusedComment = $(event.currentTarget); - }); + }; + + $('.em-blog-comment .comments').on('dblclick', '.comment', this.commentsDblHandler); + $('.em-blog-comment .comments').on('click', '.comment', this.commentsClHandler); this.initHotkeys(); } initHotkeys() { - $(document).bind('keydown', 'r', (evt) => { // reply + + this.kdRHandler = (evt) => { // reply evt.preventDefault(); $('.em-blog-content').scrollTo(`max`, 120, { offset: 0 }); this.simplemde.codemirror.focus(); - }).bind('keydown', 'alt+up', (evt) => { // comment pre + }; + + this.kdAltUpHandler = (evt) => { // comment pre evt.preventDefault(); $('.em-blog-content').scrollTo(this.getScrollTargetComment(true), 120, { offset: 0 }); - }).bind('keydown', 'alt+down', (evt) => { // comment next + }; + + this.kdAltDownHandler = (evt) => { // comment next evt.preventDefault(); $('.em-blog-content').scrollTo(this.getScrollTargetComment(), 120, { offset: 0 }); - }); + }; + + $(document).bind('keydown', 'r', this.kdRHandler).bind('keydown', 'alt+up', this.kdAltUpHandler).bind('keydown', 'alt+down', this.kdAltDownHandler); } @@ -412,13 +495,15 @@ export class EmBlogComment { }, }); - this.simplemde.codemirror.on('keyup', (cm, e) => { + this.editKeyHandler = (cm, e) => { if (e.ctrlKey && e.keyCode == 13) { // Ctrl+Enter this.addHandler(); } else if (e.keyCode == 27) { // Esc this.simplemde.value(''); } - }); + }; + + this.simplemde.codemirror.on('keyup', this.editKeyHandler); this.$chatMsgInputRef = $(this.markdownRef).find('.CodeMirror textarea'); if (this.$chatMsgInputRef.size() === 0) { @@ -607,9 +692,12 @@ export class EmBlogComment { _reset() { this.blog = null; - this.simplemde.value(''); - this.simplemde.toTextArea(); - this.simplemde = null; + + if (this.simplemde) { + this.simplemde.value(''); + this.simplemde.toTextArea(); + this.simplemde = null; + } } /** @@ -698,31 +786,38 @@ export class EmBlogComment { initPaste() { - let $paste; if (this.$chatMsgInputRef.is('textarea')) { - $paste = $(this.$chatMsgInputRef).pastableTextarea(); + this.$paste = $(this.$chatMsgInputRef).pastableTextarea(); } else { - $paste = $(this.$chatMsgInputRef).pastableContenteditable(); + this.$paste = $(this.$chatMsgInputRef).pastableContenteditable(); } - $paste && ($paste.on('pasteImage', (ev, data) => { - - $.post('/admin/file/base64', { - dataURL: data.dataURL, - type: data.blob.type, - toType: 'Blog' - }, (data, textStatus, xhr) => { - if (data.success) { - this.insertContent('![{name}]({baseURL}{path}{uuidName})' - .replace(/\{name\}/g, data.data.name) - .replace(/\{baseURL\}/g, utils.getBaseUrl() + '/') - .replace(/\{path\}/g, data.data.path) - .replace(/\{uuidName\}/g, data.data.uuidName)); - } - }); - }).on('pasteImageError', (ev, data) => { - toastr.error(data.message, '剪贴板粘贴图片错误!'); - })); + if (this.$paste) { + + this.pasteHandler = (ev, data) => { + + $.post('/admin/file/base64', { + dataURL: data.dataURL, + type: data.blob.type, + toType: 'Blog' + }, (data, textStatus, xhr) => { + if (data.success) { + this.insertContent('![{name}]({baseURL}{path}{uuidName})' + .replace(/\{name\}/g, data.data.name) + .replace(/\{baseURL\}/g, utils.getBaseUrl() + '/') + .replace(/\{path\}/g, data.data.path) + .replace(/\{uuidName\}/g, data.data.uuidName)); + } + }); + }; + + this.errHandler = (ev, data) => { + toastr.error(data.message, '剪贴板粘贴图片错误!'); + }; + + this.$paste.on('pasteImage', this.pasteHandler).on('pasteImageError', this.errHandler); + + } } initUploadDropzone(domRef, getInputTargetCb, clickable) { @@ -785,7 +880,7 @@ export class EmBlogComment { scrollToAfterImgLoaded(to) { _.defer(() => { - new ImagesLoaded($('.em-blog-content')[0]).always(() => { + ($('.em-blog-content').length > 0) && new ImagesLoaded($('.em-blog-content')[0]).always(() => { this._scrollTo(to); }); diff --git a/src/resources/elements/em-blog-content.js b/src/resources/elements/em-blog-content.js index a600df4913528be9c674972ce0984d31ad74afb9..71c415349b1f4cc5b617fe3d15a399af3aa5593b 100644 --- a/src/resources/elements/em-blog-content.js +++ b/src/resources/elements/em-blog-content.js @@ -13,9 +13,15 @@ export class EmBlogContent { blog; - loginUser = nsCtx.loginUser; - isSuper = nsCtx.isSuper; - isAdmin = nsCtx.isAdmin; + loginUser; + isSuper; + isAdmin; + + bind() { + this.loginUser = nsCtx.loginUser; + this.isSuper = nsCtx.isSuper; + this.isAdmin = nsCtx.isAdmin; + } /** * 构造函数 @@ -289,6 +295,59 @@ export class EmBlogContent { this.subscribe7.dispose(); } + detached() { + window.__debug && console.log('EmBlogContent--detached'); + + this.blog = null; + this.loginUser = null; + this.isSuper = null; + this.isAdmin = null; + + $('.em-blog-content').off('click', 'code[data-code]', this.codeClHandler); + $('.em-blog-content').off('click', '.pre-code-wrapper', this.preCodeClHandler); + $('.em-blog-right-sidebar').off('click', '.panel-blog-dir .wiki-dir-item', this.wikiDirClHandler); + $(this.mkbodyRef).off('dblclick', this.mkDblHandler); + $('.em-blog-content').off('scroll', this.blogContentScrollHandler); + $(this.feedRef).off('mouseenter', '.event a[href*="#/blog/"]:not(.pp-not)', this.feedMeHandler); + $(this.feedRef).off('mouseleave', '.event a[href*="#/blog/"]:not(.pp-not)', this.feedMlHandler); + $('.tms-blog').off('mouseenter', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', this.userInfoMeHandler); + $('.tms-blog').off('mouseleave', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', this.userInfoMlHandler); + + window.removeEventListener && window.removeEventListener('message', this.messageHandler, false); + + this.codeClHandler = null; + this.preCodeClHandler = null; + this.wikiDirClHandler = null; + this.mkDblHandler = null; + this.blogContentScrollHandler = null; + this.feedMeHandler = null; + this.feedMlHandler = null; + this.userInfoMeHandler = null; + this.userInfoMlHandler = null; + this.messageHandler = null; + + try { + $(document).unbind('keyup', this.docKuEHandler) + .unbind('keyup', this.docKuWHandler) + .unbind('keydown', this.docKuDHandler) + .unbind('keydown', this.docKuSHandler) + .unbind('keydown', this.docKuFHandler) + .unbind('keydown', this.docKuTHandler) + .unbind('keydown', this.docKuBHandler) + .unbind('keydown', this.docKuAltRHandler) + .unbind('keydown', this.docKuAltHHandler) + .unbind('keydown', this.docKuAltLHandler) + .unbind('keydown', this.docKuAltSHandler) + .unbind('keydown', this.docKuAltCHandler) + .unbind('keydown', this.docKuAltMHandler) + .unbind('keydown', this.docKuAltOHandler) + .unbind('keydown', this.docKuAltTHandler) + .unbind('keydown', this.docKuAltEHandler) + .unbind('keydown', this.docKuAltCtrlDHandler); + } catch (err) { console.log(err); } + + } + /** * 当视图被附加到DOM中时被调用 */ @@ -302,7 +361,7 @@ export class EmBlogContent { toastr.error('复制到剪贴板失败!'); }); - $('.em-blog-content').on('click', 'code[data-code]', function(event) { + this.codeClHandler = function(event) { if (event.ctrlKey || event.metaKey) { event.stopImmediatePropagation(); event.preventDefault(); @@ -311,9 +370,9 @@ export class EmBlogContent { (err) => { toastr.error('复制到剪贴板失败!'); } ); } - }); + }; - $('.em-blog-content').on('click', '.pre-code-wrapper', function(event) { + this.preCodeClHandler = function(event) { if (event.ctrlKey || event.metaKey) { event.stopImmediatePropagation(); event.preventDefault(); @@ -322,9 +381,12 @@ export class EmBlogContent { (err) => { toastr.error('复制到剪贴板失败!'); } ); } - }); + }; - $('.em-blog-right-sidebar').on('click', '.panel-blog-dir .wiki-dir-item', (event) => { + $('.em-blog-content').on('click', 'code[data-code]', this.codeClHandler); + $('.em-blog-content').on('click', '.pre-code-wrapper', this.preCodeClHandler); + + this.wikiDirClHandler = (event) => { event.preventDefault(); if ($(window).width() <= 768) { ea.publish(nsCons.EVENT_BLOG_RIGHT_SIDEBAR_TOGGLE, { isHide: true }); @@ -332,17 +394,21 @@ export class EmBlogContent { $('.em-blog-content').scrollTo(`#${$(event.currentTarget).attr('data-id')}`, 200, { offset: 0 }); - }); + }; - $(this.mkbodyRef).on('dblclick', (event) => { + $('.em-blog-right-sidebar').on('click', '.panel-blog-dir .wiki-dir-item', this.wikiDirClHandler); + + this.mkDblHandler = (event) => { if (event.ctrlKey && event.shiftKey) { if (this.blog.openEdit || this.isSuper || this.blog.creator.username == this.loginUser.username) { this.editHandler(); } } - }); + }; - $('.em-blog-content').scroll(_.throttle((event) => { + $(this.mkbodyRef).on('dblclick', this.mkDblHandler); + + this.blogContentScrollHandler = _.throttle((event) => { try { let sHeight = $('.em-blog-content')[0].scrollHeight; let sTop = $('.em-blog-content')[0].scrollTop; @@ -354,10 +420,11 @@ export class EmBlogContent { } catch (err) { this.progressWidth = 0; } - }, 10)); + }, 10); - // 消息popup - $(this.feedRef).on('mouseenter', '.event a[href*="#/blog/"]:not(.pp-not)', (event) => { + $('.em-blog-content').scroll(this.blogContentScrollHandler); + + this.feedMeHandler = (event) => { event.preventDefault(); let target = event.currentTarget; let cid = utils.urlQuery('cid', $(target).attr('href')); @@ -379,10 +446,9 @@ export class EmBlogContent { }); this.hoverTimeoutRef = null; }, 500); - }); + }; - // 消息popup - $(this.feedRef).on('mouseleave', '.event a[href*="#/blog/"]:not(.pp-not)', (event) => { + this.feedMlHandler = (event) => { event.preventDefault(); if (this.hoverTimeoutRef) { if (this.hoverUserTarget === event.currentTarget) { @@ -390,10 +456,13 @@ export class EmBlogContent { this.hoverTimeoutRef = null; } } - }); + }; - // 用户信息popup - $('.tms-blog').on('mouseenter', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', (event) => { + // 消息popup + $(this.feedRef).on('mouseenter', '.event a[href*="#/blog/"]:not(.pp-not)', this.feedMeHandler); + $(this.feedRef).on('mouseleave', '.event a[href*="#/blog/"]:not(.pp-not)', this.feedMlHandler); + + this.userInfoMeHandler = (event) => { event.preventDefault(); let target = event.currentTarget; @@ -416,10 +485,9 @@ export class EmBlogContent { }); this.hoverTimeoutRef = null; }, 500); - }); + }; - // 用户信息popup - $('.tms-blog').on('mouseleave', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', (event) => { + this.userInfoMlHandler = (event) => { event.preventDefault(); if (this.hoverTimeoutRef) { if (this.hoverUserTarget === event.currentTarget) { @@ -427,11 +495,14 @@ export class EmBlogContent { this.hoverTimeoutRef = null; } } - }); + }; + // 用户信息popup + $('.tms-blog').on('mouseenter', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', this.userInfoMeHandler); + $('.tms-blog').on('mouseleave', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', this.userInfoMlHandler); this.initHotkeys(); - window.addEventListener && window.addEventListener('message', function(ev) { + this.messageHandler = function(ev) { // console.info('message from parent:', ev.data); if (ev.origin != window.location.origin) return; @@ -444,7 +515,9 @@ export class EmBlogContent { ev.data.from = 'html'; ea.publish(nsCons.EVENT_BLOG_CHANGED, ev.data); - }, false); + }; + + window.addEventListener && window.addEventListener('message', this.messageHandler, false); } fixDirItem() { @@ -478,67 +551,103 @@ export class EmBlogContent { } initHotkeys() { - try { - $(document).bind('keyup', 'e', (evt) => { // edit - evt.preventDefault(); - if (this.blog.openEdit || this.isSuper || this.blog.creator.username == this.loginUser.username) { - this.throttleEditHandler(); - } - }).bind('keyup', 'w', (evt) => { // create - evt.preventDefault(); - this.throttleCreateHandler(); - }).bind('keydown', 'd', (evt) => { // dir - evt.preventDefault(); - if (this.dir) { - this.catalogHandler(); - } - }).bind('keydown', 's', (evt) => { // share - evt.preventDefault(); - this.blogShareVm.show(); - }).bind('keydown', 'f', (evt) => { // follow - evt.preventDefault(); - this.followerHandler(); - }).bind('keydown', 't', (event) => { // scroll top - event.preventDefault(); - $('.em-blog-content').scrollTo(0, 200, { - offset: 0 - }); - }).bind('keydown', 'b', (event) => { // scroll bottom - event.preventDefault(); - $('.em-blog-content').scrollTo(`max`, 200, { - offset: 0 - }); - }).bind('keydown', 'alt+r', (event) => { // refresh - event.preventDefault(); - this.refreshHandler(); - }).bind('keydown', 'alt+h', (event) => { // history - event.preventDefault(); - this.historyHandler(); - }).bind('keydown', 'alt+l', (event) => { // history - event.preventDefault(); - this.authHandler(); - }).bind('keydown', 'alt+s', (event) => { // stow - event.preventDefault(); - this.stowHandler(); - }).bind('keydown', 'alt+c', (event) => { // copy - event.preventDefault(); - this.throttleCopyHandler(); - }).bind('keydown', 'alt+m', (event) => { // move space - event.preventDefault(); - this.updateSpaceHandler(); - }).bind('keydown', 'alt+o', (event) => { // open edit - event.preventDefault(); - this.openEditHandler(); - }).bind('keydown', 'alt+t', (event) => { // tpl edit - event.preventDefault(); - this.tplEditHandler(); - }).bind('keydown', 'alt+e', (event) => { // change editor - event.preventDefault(); - this.changeEditorHandler(); - }).bind('keydown', 'alt+ctrl+d', (event) => { // delete - event.preventDefault(); - this.deleteHandler(); + + + this.docKuEHandler = (evt) => { // edit + evt.preventDefault(); + if (this.blog.openEdit || this.isSuper || this.blog.creator.username == this.loginUser.username) { + this.throttleEditHandler(); + } + }; + this.docKuWHandler = (evt) => { // create + evt.preventDefault(); + this.throttleCreateHandler(); + }; + this.docKuDHandler = (evt) => { // dir + evt.preventDefault(); + if (this.dir) { + this.catalogHandler(); + } + }; + this.docKuSHandler = (evt) => { // share + evt.preventDefault(); + this.blogShareVm.show(); + }; + this.docKuFHandler = (evt) => { // follow + evt.preventDefault(); + this.followerHandler(); + }; + this.docKuTHandler = (event) => { // scroll top + event.preventDefault(); + $('.em-blog-content').scrollTo(0, 200, { + offset: 0 + }); + }; + this.docKuBHandler = (event) => { // scroll bottom + event.preventDefault(); + $('.em-blog-content').scrollTo(`max`, 200, { + offset: 0 }); + }; + this.docKuAltRHandler = (event) => { // refresh + event.preventDefault(); + this.refreshHandler(); + }; + this.docKuAltHHandler = (event) => { // history + event.preventDefault(); + this.historyHandler(); + }; + this.docKuAltLHandler = (event) => { // auth + event.preventDefault(); + this.authHandler(); + }; + this.docKuAltSHandler = (event) => { // stow + event.preventDefault(); + this.stowHandler(); + }; + this.docKuAltCHandler = (event) => { // copy + event.preventDefault(); + this.throttleCopyHandler(); + }; + this.docKuAltMHandler = (event) => { // move space + event.preventDefault(); + this.updateSpaceHandler(); + }; + this.docKuAltOHandler = (event) => { // open edit + event.preventDefault(); + this.openEditHandler(); + }; + this.docKuAltTHandler = (event) => { // tpl edit + event.preventDefault(); + this.tplEditHandler(); + }; + this.docKuAltEHandler = (event) => { // change editor + event.preventDefault(); + this.changeEditorHandler(); + }; + this.docKuAltCtrlDHandler = (event) => { // delete + event.preventDefault(); + this.deleteHandler(); + }; + + try { + $(document).bind('keyup', 'e', this.docKuEHandler) + .bind('keyup', 'w', this.docKuWHandler) + .bind('keydown', 'd', this.docKuDHandler) + .bind('keydown', 's', this.docKuSHandler) + .bind('keydown', 'f', this.docKuFHandler) + .bind('keydown', 't', this.docKuTHandler) + .bind('keydown', 'b', this.docKuBHandler) + .bind('keydown', 'alt+r', this.docKuAltRHandler) + .bind('keydown', 'alt+h', this.docKuAltHHandler) + .bind('keydown', 'alt+l', this.docKuAltLHandler) + .bind('keydown', 'alt+s', this.docKuAltSHandler) + .bind('keydown', 'alt+c', this.docKuAltCHandler) + .bind('keydown', 'alt+m', this.docKuAltMHandler) + .bind('keydown', 'alt+o', this.docKuAltOHandler) + .bind('keydown', 'alt+t', this.docKuAltTHandler) + .bind('keydown', 'alt+e', this.docKuAltEHandler) + .bind('keydown', 'alt+ctrl+d', this.docKuAltCtrlDHandler); } catch (err) { console.log(err); } } diff --git a/src/resources/elements/em-blog-write.js b/src/resources/elements/em-blog-write.js index 87780a040fe3ea19d6619f04a73cea2ec14708fa..13c7ba29a75e9fe435842f5209d08d389f2ab8b3 100644 --- a/src/resources/elements/em-blog-write.js +++ b/src/resources/elements/em-blog-write.js @@ -16,6 +16,64 @@ export class EmBlogWrite { baseRes = utils.getResourceBase(); + detached() { + + window.__debug && console.log('EmBlogWrite--detached'); + + this.members = null; + this.blog = null; + + if (this.$paste) { + this.$paste.off('pasteImage', this.pasteHandler).off('pasteImageError', this.errHandler); + this.pasteHandler = null; + this.errHandler = null; + + this.$paste = null; + } + + $('#blog-save-btn').off('click', this.blogSaveHandler); + $('#switch-html').off('click', this.switchHandler); + + this.blogSaveHandler = null; + this.switchHandler = null; + + $('#blog-title-input').off('keyup', this.blogTitleInputKuHandler); + + $('.CodeMirror-wrap', '#txt-blog-write-wrapper').each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + + $('.editor-toolbar .fa.fa-upload', '#txt-blog-write-wrapper').each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + + $('.editor-toolbar .fa.fa-file-excel-o', '#txt-blog-write-wrapper').each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + + try { + + $(this.$chatMsgInputRef).textcomplete('destroy'); + this.$chatMsgInputRef = null; + + if (this.simplemde) { + + this.simplemde.codemirror.off('keyup', this.editKuHandler); + this.editKuHandler = null; + + this.simplemde.value(''); + this.simplemde.toTextArea(); + this.simplemde = null; + } + + } catch (err) { + console.error(err); + } + } + /** * 构造函数 */ @@ -53,23 +111,25 @@ export class EmBlogWrite { }); - this.blogTitleInputKeyupInit = _.once(() => { - $('#blog-title-input').keyup((e) => { - let $t = $(e.currentTarget); + this.blogTitleInputKuHandler = (e) => { + let $t = $(e.currentTarget); - if (!e.shiftKey && e.keyCode == 13) { // Enter - if (this.simplemde.value()) { - this.save(e, true); - } else { - this.simplemde.codemirror.focus(); - } - - } else if (e.shiftKey && e.keyCode == 13) { // Esc + if (!e.shiftKey && e.keyCode == 13) { // Enter + if (this.simplemde.value()) { + this.save(e, true); + } else { this.simplemde.codemirror.focus(); - } else if (e.keyCode == 27) { // Esc - $t.val(''); } - }); + + } else if (e.shiftKey && e.keyCode == 13) { // Esc + this.simplemde.codemirror.focus(); + } else if (e.keyCode == 27) { // Esc + $t.val(''); + } + }; + + this.blogTitleInputKeyupInit = _.once(() => { + $('#blog-title-input').keyup(this.blogTitleInputKuHandler); }); } @@ -89,9 +149,12 @@ export class EmBlogWrite { $('#blog-save-btn span').text('保存'); $('#blog-save-btn').attr('title', 'ctrl+click快速保存'); $('#blog-title-input').val(''); - this.simplemde.value(''); - this.simplemde.toTextArea(); - this.simplemde = null; + if (this.simplemde) { + this.simplemde.value(''); + this.simplemde.toTextArea(); + this.simplemde = null; + } + } _editInit() { @@ -276,7 +339,7 @@ export class EmBlogWrite { }, }); - this.simplemde.codemirror.on('keyup', (cm, e) => { + this.editKuHandler = (cm, e) => { if (e.ctrlKey && e.keyCode == 13) { // Ctrl+Enter this.save(e, true); } else if (e.keyCode == 27) { // Esc @@ -290,7 +353,9 @@ export class EmBlogWrite { } } } - }); + }; + + this.simplemde.codemirror.on('keyup', this.editKuHandler); this.$chatMsgInputRef = $('#txt-blog-write-wrapper').find('.CodeMirror textarea'); if (this.$chatMsgInputRef.size() === 0) { @@ -488,31 +553,37 @@ export class EmBlogWrite { initPaste() { - let $paste; if (this.$chatMsgInputRef.is('textarea')) { - $paste = $(this.$chatMsgInputRef).pastableTextarea(); + this.$paste = $(this.$chatMsgInputRef).pastableTextarea(); } else { - $paste = $(this.$chatMsgInputRef).pastableContenteditable(); + this.$paste = $(this.$chatMsgInputRef).pastableContenteditable(); } - $paste && ($paste.on('pasteImage', (ev, data) => { + if (this.$paste) { - $.post('/admin/file/base64', { - dataURL: data.dataURL, - type: data.blob.type, - toType: 'Blog' - }, (data, textStatus, xhr) => { - if (data.success) { - this.insertContent('![{name}]({baseURL}{path}{uuidName})' - .replace(/\{name\}/g, data.data.name) - .replace(/\{baseURL\}/g, utils.getBaseUrl() + '/') - .replace(/\{path\}/g, data.data.path) - .replace(/\{uuidName\}/g, data.data.uuidName)); - } - }); - }).on('pasteImageError', (ev, data) => { - toastr.error(data.message, '剪贴板粘贴图片错误!'); - })); + this.pasteHandler = (ev, data) => { + + $.post('/admin/file/base64', { + dataURL: data.dataURL, + type: data.blob.type, + toType: 'Blog' + }, (data, textStatus, xhr) => { + if (data.success) { + this.insertContent('![{name}]({baseURL}{path}{uuidName})' + .replace(/\{name\}/g, data.data.name) + .replace(/\{baseURL\}/g, utils.getBaseUrl() + '/') + .replace(/\{path\}/g, data.data.path) + .replace(/\{uuidName\}/g, data.data.uuidName)); + } + }); + }; + + this.errHandler = (ev, data) => { + toastr.error(data.message, '剪贴板粘贴图片错误!'); + }; + + this.$paste.on('pasteImage', this.pasteHandler).on('pasteImageError', this.errHandler); + } } initUploadDropzone(domRef, getInputTargetCb, clickable) { @@ -599,13 +670,17 @@ export class EmBlogWrite { * 当视图被附加到DOM中时被调用 */ attached() { - $('#blog-save-btn').click((event) => { + + this.blogSaveHandler = (event) => { this.save(event); - }); + }; - $('#switch-html').click((event) => { + this.switchHandler = (event) => { this.switchEditorHandler(); - }); + }; + + $('#blog-save-btn').click(this.blogSaveHandler); + $('#switch-html').click(this.switchHandler); } save(event, isKey) { diff --git a/src/resources/elements/em-channel-chat-task-talk-modal.html b/src/resources/elements/em-channel-chat-task-talk-modal.html index 15c8aaa27373f50a94e7c431433f1b494ebccc8b..0f7f6b78bda1055c98f23ecc02737e6a1c6ce3a2 100644 --- a/src/resources/elements/em-channel-chat-task-talk-modal.html +++ b/src/resources/elements/em-channel-chat-task-talk-modal.html @@ -3,7 +3,7 @@
频道任务评论
- +
diff --git a/src/resources/elements/em-channel-chat-task-talk-modal.js b/src/resources/elements/em-channel-chat-task-talk-modal.js index 695b7618a61440d1154724c633ca31274ff815ba..fe6c0e8959ee8ef9cb32731e44260e61db2a1a4c 100644 --- a/src/resources/elements/em-channel-chat-task-talk-modal.js +++ b/src/resources/elements/em-channel-chat-task-talk-modal.js @@ -32,6 +32,17 @@ export class EmChannelChatTaskTalkModal { }); } + detached() { + window.__debug && console.log('EmChannelChatTaskTalkModal--detached'); + + this.channel = null; + this.task = null; + this.actived = null; + this.chatTopicVm = null; + this.emModal = null; + + } + /** * 当数据绑定引擎从视图解除绑定时被调用 */ @@ -40,6 +51,7 @@ export class EmChannelChatTaskTalkModal { } approveHandler(modal) { + this.chatTopicVm.commit(); this.emModal.hide(); } } diff --git a/src/resources/elements/em-channel-task-create.js b/src/resources/elements/em-channel-task-create.js index 71a0b6b83ae56c03ea2c30ea627c92fffd470bee..d7814835626c7e6a359cc9f35309dc5fb0c2b241 100644 --- a/src/resources/elements/em-channel-task-create.js +++ b/src/resources/elements/em-channel-task-create.js @@ -55,6 +55,12 @@ export class EmChannelTaskCreate { }); this.simplemde.value(this.taskItem.content); + + _.delay(() => { + // this.simplemde.codemirror.focus(); + this.simplemde.value(this.taskItem.content); + }, 500); + } /** diff --git a/src/resources/elements/em-channel-task.js b/src/resources/elements/em-channel-task.js index 86a417f11f7de5e80a7e5c3faf8dac02c03e3593..63e16efd035254ac73a7c28f5c379cc8b62fc03e 100644 --- a/src/resources/elements/em-channel-task.js +++ b/src/resources/elements/em-channel-task.js @@ -7,9 +7,9 @@ export class EmChannelTask { @bindable loginUser; channelChanged() { - _.each(this.mapping, (v, k) => { - this[v] = {}; - }); + // _.each(this.mapping, (v, k) => { + // this[v] = {}; + // }); this._sortMembers(); } @@ -68,7 +68,7 @@ export class EmChannelTask { this.talkVm.show(payload); }); - + this.subscribe4 = ea.subscribe(nsCons.EVENT_MARKDOWN_TASK_ITEM_STATUS_TOGGLE, (payload) => { // console.log(payload); @@ -237,6 +237,18 @@ export class EmChannelTask { }); } + detached() { + + this.drake.destroy(); + this.drake = null; + + $('.em-channel-task').off('click', '.tms-task-filter > .text .remove.icon', this.taskClickHandler); + + this.taskClickHandler = null; + this.channel = null; + this.loginUser = null; + } + attached() { this.drake = dragula($(this.containerRef).find('.tms-dd-container').toArray(), { // isContainer: function(el) { @@ -287,7 +299,7 @@ export class EmChannelTask { }); - $('.em-channel-task').on('click', '.tms-task-filter > .text .remove.icon', event => { + this.taskClickHandler = event => { let $dd = $(event.currentTarget).parents('.tms-task-filter'); $dd.dropdown('clear').dropdown('hide'); @@ -298,7 +310,9 @@ export class EmChannelTask { item._hidden = false; }); } - }) + }; + + $('.em-channel-task').on('click', '.tms-task-filter > .text .remove.icon', this.taskClickHandler); } _sortMembers() { diff --git a/src/resources/elements/em-channel-tasks-modal.js b/src/resources/elements/em-channel-tasks-modal.js index 604208cb96bfbab83c20f6fe7c22660b0941bbf6..c6a4f643032fbecbe2bc7c810c9128f2e19278d0 100644 --- a/src/resources/elements/em-channel-tasks-modal.js +++ b/src/resources/elements/em-channel-tasks-modal.js @@ -20,6 +20,11 @@ export class EmChannelTasksModal { }); } + detached() { + this.channel = null; + this.loginUser = null; + } + /** * 当数据绑定引擎从视图解除绑定时被调用 */ diff --git a/src/resources/elements/em-chat-content-item-footbar.js b/src/resources/elements/em-chat-content-item-footbar.js index 661260030dcdbe945f4f630c1c074363f65d63cc..538a3afc7685aeb4dc3a865c30dab2113c27872d 100644 --- a/src/resources/elements/em-chat-content-item-footbar.js +++ b/src/resources/elements/em-chat-content-item-footbar.js @@ -44,19 +44,37 @@ export class EmChatContentItemFootbar { type: 'emoji' }]; - myTags = nsCtx.myTags; + myTags; /** * 构造函数 */ - constructor() { + constructor() {} + + detached() { + window.__debug && console.log('EmChatContentItemFootbar--detached'); + + $([this.addEmojiRef]).popup('destroy'); + $([this.addTagRef]).popup('destroy'); + + this.chat = null; + this.myTags = null; + this.tags = null; + this.addEmojiRef = null; + this.addTagRef = null; + this.tagRef = null; + } + + bind() { this.tags = tags; + this.myTags = nsCtx.myTags; } /** * 当视图被附加到DOM中时被调用 */ attached() { + $([this.addEmojiRef]) .popup({ inline: true, diff --git a/src/resources/elements/em-chat-content-item.js b/src/resources/elements/em-chat-content-item.js index d69bc7cdd859ff0afec00128c60a5170f0a3adc9..1a51321ce21afe223ac0207fade51791d93f30a2 100644 --- a/src/resources/elements/em-chat-content-item.js +++ b/src/resources/elements/em-chat-content-item.js @@ -140,25 +140,66 @@ export class EmChatContentItem { this.subscribe2.dispose(); } + detached() { + + $(document).unbind('keydown', this.keydownHandler); + $('.tms-content-body').off('click', '.markdown-body .at-user', this.atUserHandler); + $('.tms-content-body').off('click', '.markdown-body .at-group', this.atGroupHandler); + $('.tms-chat').off('mouseenter', '.markdown-body a[href*="#/chat/"]:not(.pp-not)', this.msgPpMiHandler); + $('.tms-chat').off('mouseleave', '.markdown-body a[href*="#/chat/"]:not(.pp-not)', this.msgPpMlHandler); + $('.tms-chat').off('mouseenter', '.tms-content-body .em-chat-content-item', this.wikiDirMiHandler); + $('.tms-chat').off('mouseleave', '.tms-content-body .em-chat-content-item', this.wikiDirMlHandler); + $('.tms-chat').off('click', '.panel-wiki-dir .wiki-dir-item', this.wikiDirItemClickHandler); + $('.tms-chat').off('mouseenter', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', this.userInfoPpMiHandler); + $('.tms-chat').off('mouseleave', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', this.userInfoPpMlHandler); + + + this.keydownHandler = null; + this.atUserHandler = null; + this.atGroupHandler = null; + this.msgPpMiHandler = null; + this.msgPpMlHandler = null; + this.wikiDirMiHandler = null; + this.wikiDirMlHandler = null; + this.wikiDirItemClickHandler = null; + this.userInfoPpMiHandler = null; + this.userInfoPpMlHandler = null; + + this.chats = null; + this.loginUser = null; + this.isAt = null; + this.channel = null; + this.markId = null; + this.chatTo = null; + this.members = []; + + this.hoverMsgTimeoutRef = null; + this.hoverMsgTarget = null; + + } + /** * 当视图被附加到DOM中时被调用 */ attached() { - $('.tms-content-body').on('click', '.markdown-body .at-user', (event) => { + this.atUserHandler = (event) => { event.preventDefault(); ea.publish(nsCons.EVENT_CHAT_MSG_INSERT, { content: `{~${$(event.currentTarget).attr('data-value')}} ` }); - }); - $('.tms-content-body').on('click', '.markdown-body .at-group', (event) => { + }; + + this.atGroupHandler = (event) => { event.preventDefault(); ea.publish(nsCons.EVENT_CHAT_MSG_INSERT, { content: `{!~${$(event.currentTarget).attr('data-value')}} ` }); - }); + }; - // 消息popup - $('.tms-chat').on('mouseenter', '.markdown-body a[href*="#/chat/"]:not(.pp-not)', (event) => { + $('.tms-content-body').on('click', '.markdown-body .at-user', this.atUserHandler); + $('.tms-content-body').on('click', '.markdown-body .at-group', this.atGroupHandler); + + this.msgPpMiHandler = (event) => { event.preventDefault(); let target = event.currentTarget; @@ -181,9 +222,9 @@ export class EmChatContentItem { this.hoverMsgTimeoutRef = null; }, 500); - }); + }; - $('.tms-chat').on('mouseleave', '.markdown-body a[href*="#/chat/"]:not(.pp-not)', (event) => { + this.msgPpMlHandler = (event) => { event.preventDefault(); if (this.hoverMsgTimeoutRef) { if (this.hoverMsgTarget === event.currentTarget) { @@ -191,10 +232,14 @@ export class EmChatContentItem { this.hoverMsgTimeoutRef = null; } } - }); + }; - // wiki dir - $('.tms-chat').on('mouseenter', '.tms-content-body .em-chat-content-item', (event) => { + // 消息popup + $('.tms-chat').on('mouseenter', '.markdown-body a[href*="#/chat/"]:not(.pp-not)', this.msgPpMiHandler); + $('.tms-chat').on('mouseleave', '.markdown-body a[href*="#/chat/"]:not(.pp-not)', this.msgPpMlHandler); + + + this.wikiDirMiHandler = (event) => { event.preventDefault(); var $c = $(event.currentTarget); @@ -205,23 +250,28 @@ export class EmChatContentItem { let chat = _.find(this.chats, { id: +$c.attr('data-id') }); chat && (chat._hovered = true); chat && (chat.__hovered = true); - }); + }; - $('.tms-chat').on('mouseleave', '.tms-content-body .em-chat-content-item', (event) => { + this.wikiDirMlHandler = (event) => { event.preventDefault(); var $c = $(event.currentTarget); let chat = _.find(this.chats, { id: +$c.attr('data-id') }); chat && (chat._hovered = false); - }); + }; + + // wiki dir + $('.tms-chat').on('mouseenter', '.tms-content-body .em-chat-content-item', this.wikiDirMiHandler); + $('.tms-chat').on('mouseleave', '.tms-content-body .em-chat-content-item', this.wikiDirMlHandler); - $('.tms-chat').on('click', '.panel-wiki-dir .wiki-dir-item', (event) => { + this.wikiDirItemClickHandler = (event) => { event.preventDefault(); ea.publish(nsCons.EVENT_CHAT_CONTENT_SCROLL_TO, { target: $('#' + $(event.currentTarget).attr('data-id')) }); - }); + }; - // 用户信息popup - $('.tms-chat').on('mouseenter', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', (event) => { + $('.tms-chat').on('click', '.panel-wiki-dir .wiki-dir-item', this.wikiDirItemClickHandler); + + this.userInfoPpMiHandler = (event) => { event.preventDefault(); let target = event.currentTarget; @@ -246,10 +296,9 @@ export class EmChatContentItem { this.hoverTimeoutRef = null; }, 500); - }); + }; - // 用户信息popup - $('.tms-chat').on('mouseleave', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', (event) => { + this.userInfoPpMlHandler = (event) => { event.preventDefault(); if (this.hoverTimeoutRef) { if (this.hoverUserTarget === event.currentTarget) { @@ -258,7 +307,11 @@ export class EmChatContentItem { } } - }); + }; + + // 用户信息popup + $('.tms-chat').on('mouseenter', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', this.userInfoPpMiHandler); + $('.tms-chat').on('mouseleave', 'span[data-value].at-user:not(.pp-not),span[data-value].at-group:not(.pp-not),a[data-value].author:not(.pp-not)', this.userInfoPpMlHandler); this.initHotkeys(); } @@ -304,13 +357,14 @@ export class EmChatContentItem { } initHotkeys() { - $(document).bind('keydown', 'e', (evt) => { + this.keydownHandler = (evt) => { evt.preventDefault(); let chat = _.findLast(this.chats, c => c.creator.username == this.loginUser.username); if (chat) { this.editHandler(chat, $(`.em-chat-content-item[data-id="${chat.id}"]`).find('> .content > textarea')); } - }); + }; + $(document).bind('keydown', 'e', this.keydownHandler); } editHandler(item, editTxtRef) { diff --git a/src/resources/elements/em-chat-input.js b/src/resources/elements/em-chat-input.js index 7981ba5697270c947c2d798a6afd3823a40b9bd7..a7201b328104796c68ec26d163dbb3d73dda8b9b 100644 --- a/src/resources/elements/em-chat-input.js +++ b/src/resources/elements/em-chat-input.js @@ -5,6 +5,9 @@ import emojis from 'common/common-emoji'; import { default as SimpleMDE } from 'simplemde'; +import { + default as Dropzone +} from 'dropzone'; @containerless export class EmChatInput { @@ -66,34 +69,89 @@ export class EmChatInput { this.initHotkeys(); } + detached() { + window.__debug && console.log('EmChatInput--detached'); + + this.chatTo = null; + this.isAt = null; + this.channel = null; + this.members = []; + + if (this.$paste) { + this.$paste.off('pasteImage', this.pasteHandler).off('pasteImageError', this.errHandler); + this.pasteHandler = null; + this.errHandler = null; + + this.$paste = null; + } + + $(this.chatBtnRef).popup('destroy'); + this.chatBtnRef = null; + + $('.CodeMirror-wrap', this.inputRef).each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + this.inputRef = null; + + $(this.btnItemUploadRef).children().andSelf().each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + this.btnItemUploadRef = null; + + $(this.btnItemCsvRef).children().andSelf().each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + this.btnItemCsvRef = null; + + try { + // https://github.com/sparksuite/simplemde-markdown-editor + this.simplemde.toTextArea(); + this.simplemde = null; + + $(this.$chatMsgInputRef).textcomplete('destroy'); + this.$chatMsgInputRef = null; + } catch (err) { + console.error(err); + } + + } + initPaste() { - let $paste; if (this.$chatMsgInputRef.is('textarea')) { - $paste = $(this.$chatMsgInputRef).pastableTextarea(); + this.$paste = $(this.$chatMsgInputRef).pastableTextarea(); } else { - $paste = $(this.$chatMsgInputRef).pastableContenteditable(); + this.$paste = $(this.$chatMsgInputRef).pastableContenteditable(); } - $paste && ($paste.on('pasteImage', (ev, data) => { - - $.post('/admin/file/base64', { - dataURL: data.dataURL, - type: data.blob.type, - toType: nsCtx.isAt ? 'User' : 'Channel', - toId: nsCtx.chatTo - }, (data, textStatus, xhr) => { - if (data.success) { - this.insertContent('![{name}]({baseURL}{path}{uuidName})' - .replace(/\{name\}/g, data.data.name) - .replace(/\{baseURL\}/g, utils.getBaseUrl() + '/') - .replace(/\{path\}/g, data.data.path) - .replace(/\{uuidName\}/g, data.data.uuidName)); - } - }); - }).on('pasteImageError', (ev, data) => { - toastr.error(data.message, '剪贴板粘贴图片错误!'); - })); + if (this.$paste) { + + this.pasteHandler = (ev, data) => { + + $.post('/admin/file/base64', { + dataURL: data.dataURL, + type: data.blob.type, + toType: nsCtx.isAt ? 'User' : 'Channel', + toId: nsCtx.chatTo + }, (data, textStatus, xhr) => { + if (data.success) { + this.insertContent('![{name}]({baseURL}{path}{uuidName})' + .replace(/\{name\}/g, data.data.name) + .replace(/\{baseURL\}/g, utils.getBaseUrl() + '/') + .replace(/\{path\}/g, data.data.path) + .replace(/\{uuidName\}/g, data.data.uuidName)); + } + }); + }; + + this.errHandler = (ev, data) => { + toastr.error(data.message, '剪贴板粘贴图片错误!'); + }; + this.$paste.on('pasteImage', this.pasteHandler).on('pasteImageError', this.errHandler); + } } initDropzone() { diff --git a/src/resources/elements/em-chat-msg.js b/src/resources/elements/em-chat-msg.js index df27b07d8fb6be1da917ed0b0427f2b32e337a69..f8d89d8b13bbac2aa1697c8e30ff6c3667abbc77 100644 --- a/src/resources/elements/em-chat-msg.js +++ b/src/resources/elements/em-chat-msg.js @@ -20,12 +20,28 @@ export class EmChatMsg { this.initHotkeys(); } + detached() { + window.__debug && console.log('EmChatMsg--detached'); + + $(document).unbind('keydown', this.openKeydownHandler); + + this.openKeydownHandler = null; + this.loginUser = null; + this.channel = null; + this.chats = null; + this.actived = null; + + } + initHotkeys() { - $(document).bind('keydown', 'o', (event) => { + + this.openKeydownHandler = (event) => { event.preventDefault(); let item = _.find(this.chats, { isHover: true }); item && (item.isOpen = !item.isOpen); - }); + }; + + $(document).bind('keydown', 'o', this.openKeydownHandler); } diff --git a/src/resources/elements/em-chat-share.js b/src/resources/elements/em-chat-share.js index 39697a0ad41cc7bc70ab2f3517f35a0b26fc539a..62634ac413f678c3487e4d4086a9054c0103783e 100644 --- a/src/resources/elements/em-chat-share.js +++ b/src/resources/elements/em-chat-share.js @@ -71,6 +71,16 @@ export class EmChatShare { }); } + detached() { + $(this.shareRef).popup('destroy'); + + this.chat = null; + this.channel = null; + this.loginUser = null; + this.shareRef = null; + this.searchRef = null; + } + shareSearchKeyupHandler(event) { if (event.keyCode === 13 && !$(this.searchRef).search('is visible')) { let val = $(this.inputSearchRef).val(); diff --git a/src/resources/elements/em-chat-sidebar-left.js b/src/resources/elements/em-chat-sidebar-left.js index 80cd6f0a46ef94b94ddbcea6af77bf673020d730..3b405bb6f5566e6b0ab1b9f9c23f20aea19526ac 100644 --- a/src/resources/elements/em-chat-sidebar-left.js +++ b/src/resources/elements/em-chat-sidebar-left.js @@ -54,13 +54,29 @@ export class EmChatSidebarLeft { this.subscribe2.dispose(); } + detached() { + window.__debug && console.log('EmChatSidebarLeft--detached'); + + $(this.logoRef).off('mouseenter', this.logoMeHandler); + + this.logoMeHandler = null; + this.users = null; + this.loginUser = null; + this.channels = null; + this.onlines = null; + + } + /** * 当视图被附加到DOM中时被调用 */ attached() { - $(this.logoRef).on('mouseenter', (event) => { + + this.logoMeHandler = (event) => { $(this.logoRef).animateCss('flip'); - }); + }; + + $(this.logoRef).on('mouseenter', this.logoMeHandler); } _filter() { @@ -164,7 +180,7 @@ export class EmChatSidebarLeft { // } isSubscribed(item) { - return _.some(item.subscriber, { username: this.loginUser.username }); + return _.some(item.subscriber, { username: this.loginUser ? this.loginUser.username : '' }); } subscribeHandler(item) { diff --git a/src/resources/elements/em-chat-sidebar-right.js b/src/resources/elements/em-chat-sidebar-right.js index 794898743c514033908e6f7c41342d36145127cd..bc5e81f76d16d31c88a27feaa42be4b6ca6a778e 100644 --- a/src/resources/elements/em-chat-sidebar-right.js +++ b/src/resources/elements/em-chat-sidebar-right.js @@ -56,6 +56,15 @@ export class EmChatSidebarRight { this.subscribe2.dispose(); } + detached() { + window.__debug && console.log('EmChatSidebarRight--detached'); + + this.loginUser = null; + this.channels = null; + this.actived = null; + + } + attachHandler(payload) { this.chatAttachVm.fetch(); } diff --git a/src/resources/elements/em-chat-top-menu.js b/src/resources/elements/em-chat-top-menu.js index 23d57e8a5460cc8d559397f4de2f78062537be5f..8a0994d2ae8be7f4d796b1a5ac0d1f89411f0a91 100644 --- a/src/resources/elements/em-chat-top-menu.js +++ b/src/resources/elements/em-chat-top-menu.js @@ -30,6 +30,29 @@ export class EmChatTopMenu { channelLinks = []; channelGantts = []; + + detached() { + window.__debug && console.log('EmChatTopMenu--detached'); + + window.removeEventListener && window.removeEventListener('message', this.messageHandler, false); + $(document).unbind('keydown', this.sidebarHandler); + + this.messageHandler = null; + this.sidebarHandler = null; + + this.loginUser = null; + this.chatUser = null; + this.users = null; + this.channels = null; + this.channel = null; + this.chatId = null; + this.chatTo = null; + this.onlines = null; + this.channelLinks = []; + this.channelGantts = []; + + } + loginUserChanged() { if (this.loginUser) { this.isSuper = utils.isSuperUser(this.loginUser); @@ -242,14 +265,16 @@ export class EmChatTopMenu { } }); - window.addEventListener && window.addEventListener('message', function(ev) { + this.messageHandler = function(ev) { // console.info('message from parent:', ev.data); if (ev.origin != window.location.origin) return; if (ev.data.source != 'gantt') return; ea.publish(nsCons.EVENT_CHANNEL_GANTTS_REFRESH, ev.data); - }, false); + }; + + window.addEventListener && window.addEventListener('message', this.messageHandler, false); $('.tms-em-chat-top-menu .tms-notice').css({ 'max-width': $(window).width() - 1000 }); } @@ -360,16 +385,17 @@ export class EmChatTopMenu { } initHotkeys() { - $(document).bind('keydown', 's', (event) => { // sidebar + + this.sidebarHandler = (event) => { // sidebar event.preventDefault(); this.toggleRightSidebar(); - }).bind('keydown', 'ctrl+k', (event) => { - event.preventDefault(); - }); + }; - $(this.filterChatToUser).bind('keydown', 'ctrl+k', (event) => { - event.preventDefault(); - }); + $(document).bind('keydown', 's', this.sidebarHandler); + + // $(this.filterChatToUser).bind('keydown', 'ctrl+k', (event) => { + // event.preventDefault(); + // }); } searchFocusHandler() { diff --git a/src/resources/elements/em-chat-topic-input.js b/src/resources/elements/em-chat-topic-input.js index c38f551f37a4e61da669ebfa39533d06b21b296f..78baa051a2859a96a219454d7c5c7c81a42997df 100644 --- a/src/resources/elements/em-chat-topic-input.js +++ b/src/resources/elements/em-chat-topic-input.js @@ -5,6 +5,9 @@ import emojis from 'common/common-emoji'; import { default as SimpleMDE } from 'simplemde'; +import { + default as Dropzone +} from 'dropzone'; @containerless export class EmChatTopicInput { @@ -46,6 +49,56 @@ export class EmChatTopicInput { this.subscribe2.dispose(); } + detached() { + window.__debug && console.log('EmChatTopicInput--detached'); + + this.channel = null; + this.chat = null; + this.name = null; + this.members = []; + + if (this.$paste) { + this.$paste.off('pasteImage', this.pasteHandler).off('pasteImageError', this.errHandler); + this.pasteHandler = null; + this.errHandler = null; + + this.$paste = null; + } + + $(this.chatBtnRef).popup('destroy'); + this.chatBtnRef = null; + + $('.CodeMirror-wrap', this.inputRef).each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + this.inputRef = null; + + $(this.btnItemUploadRef).children().andSelf().each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + this.btnItemUploadRef = null; + + $(this.btnItemCsvRef).children().andSelf().each((index, elem) => { + let dd = Dropzone.forElement(elem); + dd && dd.destroy(); + }); + this.btnItemCsvRef = null; + + try { + // https://github.com/sparksuite/simplemde-markdown-editor + this.simplemde.toTextArea(); + this.simplemde = null; + + $(this.$chatMsgInputRef).textcomplete('destroy'); + this.$chatMsgInputRef = null; + } catch (err) { + console.error(err); + } + + } + /** * 当视图被附加到DOM中时被调用 */ @@ -57,32 +110,38 @@ export class EmChatTopicInput { initPaste() { - let $paste; if (this.$chatMsgInputRef.is('textarea')) { - $paste = $(this.$chatMsgInputRef).pastableTextarea(); + this.$paste = $(this.$chatMsgInputRef).pastableTextarea(); } else { - $paste = $(this.$chatMsgInputRef).pastableContenteditable(); + this.$paste = $(this.$chatMsgInputRef).pastableContenteditable(); } - $paste && ($paste.on('pasteImage', (ev, data) => { - - $.post('/admin/file/base64', { - dataURL: data.dataURL, - type: data.blob.type, - toType: nsCtx.isAt ? 'User' : 'Channel', - toId: nsCtx.chatTo - }, (data, textStatus, xhr) => { - if (data.success) { - this.insertContent('![{name}]({baseURL}{path}{uuidName})' - .replace(/\{name\}/g, data.data.name) - .replace(/\{baseURL\}/g, utils.getBaseUrl() + '/') - .replace(/\{path\}/g, data.data.path) - .replace(/\{uuidName\}/g, data.data.uuidName)); - } - }); - }).on('pasteImageError', (ev, data) => { - toastr.error(data.message, '剪贴板粘贴图片错误!'); - })); + if (this.$paste) { + + this.pasteHandler = (ev, data) => { + + $.post('/admin/file/base64', { + dataURL: data.dataURL, + type: data.blob.type, + toType: nsCtx.isAt ? 'User' : 'Channel', + toId: nsCtx.chatTo + }, (data, textStatus, xhr) => { + if (data.success) { + this.insertContent('![{name}]({baseURL}{path}{uuidName})' + .replace(/\{name\}/g, data.data.name) + .replace(/\{baseURL\}/g, utils.getBaseUrl() + '/') + .replace(/\{path\}/g, data.data.path) + .replace(/\{uuidName\}/g, data.data.uuidName)); + } + }); + }; + + this.errHandler = (ev, data) => { + toastr.error(data.message, '剪贴板粘贴图片错误!'); + }; + + this.$paste.on('pasteImage', this.pasteHandler).on('pasteImageError', this.errHandler); + } } initDropzone() { diff --git a/src/resources/elements/em-chat-topic.html b/src/resources/elements/em-chat-topic.html index 8129c245d917c416a2f6d3a2d27a0e389802785e..c4b9a44c7194d4affd8d47c479feae19c910cb45 100644 --- a/src/resources/elements/em-chat-topic.html +++ b/src/resources/elements/em-chat-topic.html @@ -72,7 +72,7 @@ - +
回复话题消息会自动关注话题,接收话题更新邮件通知
diff --git a/src/resources/elements/em-chat-topic.js b/src/resources/elements/em-chat-topic.js index e8ab4077ab770292cb2c6e681d3b77b363be5d2d..6b6e4660087cb267f086d17114b896363f55e274 100644 --- a/src/resources/elements/em-chat-topic.js +++ b/src/resources/elements/em-chat-topic.js @@ -202,7 +202,7 @@ export class EmChatTopic { scrollToAfterImgLoaded(to) { _.defer(() => { - new ImagesLoaded(this.commentsRef).always(() => { + this.commentsRef && new ImagesLoaded(this.commentsRef).always(() => { this._scrollTo(to); }); @@ -211,8 +211,29 @@ export class EmChatTopic { } + detached() { + window.__debug && console.log('EmChatTopic--detached'); + + $(this.commentsRef).off('dblclick', '.comment.tms-reply', this.replydblclickHandler); + $(this.commentsRef).off('click', '.markdown-body .at-user', this.atUserHandler); + $(this.commentsRef).off('click', '.markdown-body .at-group', this.atGroupHandler); + + this.replydblclickHandler = null; + this.atUserHandler = null; + this.atGroupHandler = null; + + this.actived = null; + this.channel = null; + this.members = []; + this.chat = []; + this.commentsRef = null; + this.ajaxTopic = null; + this.followers = null; + } + attached() { - $(this.commentsRef).on('dblclick', '.comment.tms-reply', (event) => { + + this.replydblclickHandler = (event) => { if (event.ctrlKey && event.shiftKey) { let chatId = $(event.currentTarget).attr('data-id'); let $t = $(event.currentTarget).find('.content > textarea'); @@ -229,23 +250,29 @@ export class EmChatTopic { autosize.update($t.get(0)); }); } - }); + }; - $(this.commentsRef).on('click', '.markdown-body .at-user', (event) => { + $(this.commentsRef).on('dblclick', '.comment.tms-reply', this.replydblclickHandler); + + this.atUserHandler = (event) => { event.preventDefault(); ea.publish(nsCons.EVENT_CHAT_TOPIC_MSG_INSERT, { from: this.name, content: `{~${$(event.currentTarget).attr('data-value')}} ` }); - }); + }; - $(this.commentsRef).on('click', '.markdown-body .at-group', (event) => { + $(this.commentsRef).on('click', '.markdown-body .at-user', this.atUserHandler); + + this.atGroupHandler = (event) => { event.preventDefault(); ea.publish(nsCons.EVENT_CHAT_TOPIC_MSG_INSERT, { from: this.name, content: `{!~${$(event.currentTarget).attr('data-value')}} ` }); - }); + }; + + $(this.commentsRef).on('click', '.markdown-body .at-group', this.atGroupHandler); } unbind() { @@ -551,4 +578,8 @@ export class EmChatTopic { content: `{~${item.creator.username}} ` }); } + + commit() { + this.chatTopicInputVm.sendChatMsgHandler(); + } } diff --git a/src/resources/elements/em-dropdown.js b/src/resources/elements/em-dropdown.js index 3795bb8c7abe7284d884ecd200b16485b7e2b867..36996e8b419cb7ae69e8929f3530faf9f64c644a 100644 --- a/src/resources/elements/em-dropdown.js +++ b/src/resources/elements/em-dropdown.js @@ -39,4 +39,12 @@ export class EmDropdown { }); } } + + detached() { + window.__debug && console.log('EmDropdown--detached'); + + this.selectedItem = null; + this.menuItems = []; + this.dropdown = null; + } } diff --git a/src/resources/elements/em-user-avatar.js b/src/resources/elements/em-user-avatar.js index c33021daf033af41999752914dc713b1c5b087e0..e6d6bcca2390ded4c302ac5ace4372d83c2d5bdc 100644 --- a/src/resources/elements/em-user-avatar.js +++ b/src/resources/elements/em-user-avatar.js @@ -32,11 +32,20 @@ export class EmUserAvatar { * 当视图被附加到DOM中时被调用 */ attached() { + $(this.avatarRef).hover(() => { this._calcNameChar(false); }, () => { this._calcNameChar(); }); + + } + + detached() { + window.__debug && console.log('EmUserAvatar--detached'); + $(this.avatarRef).unbind('mouseenter').unbind('mouseleave'); + this.avatarRef = null; + this.user = null; } dblclickHandler() {