From b7709c8117cc253ed0c442a44b2e499fa6311c40 Mon Sep 17 00:00:00 2001 From: RainLoop Team Date: Mon, 6 Apr 2015 23:32:19 +0400 Subject: [PATCH] Code refactoring --- dev/App/User.js | 7 +- dev/Common/Cache.js | 7 -- dev/External/Opentip.js | 3 +- dev/External/ko.js | 33 +++++++ dev/Model/MessageSimple.js | 12 +-- dev/Model/MessageStates.js | 66 -------------- dev/Promises/User/Ajax.js | 43 +++++++++ dev/Screen/User/MailBox.js | 5 -- dev/Stores/User/Message.js | 38 ++++---- dev/Styles/Ui.less | 8 +- dev/Styles/_CkeFix.less | 28 ++++++ dev/Styles/_End.less | 4 + dev/View/Popup/Compose.js | 87 +++++++++++-------- dev/View/Popup/Identity.js | 41 +-------- dev/View/Popup/NewOpenPgpKey.js | 17 ++-- .../Views/Admin/AdminSettingsLicensing.html | 2 + .../templates/Views/User/PopupsCompose.html | 6 +- .../templates/Views/User/PopupsIdentity.html | 2 +- .../templates/Views/User/PopupsTwoStep.html | 64 ++++++++++++++ rainloop/v/0.0.0/static/ckeditor/CUSTOMS | 8 +- vendors/ckeditor/CUSTOMS | 2 +- 21 files changed, 291 insertions(+), 192 deletions(-) delete mode 100644 dev/Model/MessageStates.js create mode 100644 rainloop/v/0.0.0/app/templates/Views/User/PopupsTwoStep.html diff --git a/dev/App/User.js b/dev/App/User.js index 1b9568f5d..72849500c 100644 --- a/dev/App/User.js +++ b/dev/App/User.js @@ -209,11 +209,6 @@ Remote.messageList(Utils.emptyFunction, Cache.getFolderInboxName(), 0, SettingsStore.messagesPerPage(), '', true); }; - AppUser.prototype.reloadMessageListHelper = function (bEmptyList) - { - this.reloadMessageList(bEmptyList); - }; - /** * @param {Function} fResultFunc * @returns {boolean} @@ -316,7 +311,7 @@ } } - this.reloadMessageListHelper(0 === MessageStore.messageList().length); + this.reloadMessageList(0 === MessageStore.messageList().length); this.quotaDebounce(); } }; diff --git a/dev/Common/Cache.js b/dev/Common/Cache.js index d9f38ef3f..23805973b 100644 --- a/dev/Common/Cache.js +++ b/dev/Common/Cache.js @@ -65,11 +65,6 @@ */ CacheUserStorage.prototype.oMessageFlagsCache = {}; - /** - * @type {Object} - */ - CacheUserStorage.prototype.oBodies = {}; - /** * @type {Object} */ @@ -88,10 +83,8 @@ this.oFolderUidNextCache = {}; this.oMessageListHashCache = {}; this.oMessageFlagsCache = {}; - this.oBodies = {}; }; - /** * @param {string} sEmail * @param {Function} fCallback diff --git a/dev/External/Opentip.js b/dev/External/Opentip.js index 5063edf5e..d4530d84d 100644 --- a/dev/External/Opentip.js +++ b/dev/External/Opentip.js @@ -30,7 +30,8 @@ }; Opentip.styles.rainloopTestTip = { - 'extends': 'rainloop' + 'extends': 'rainloop', + 'className': 'rainloopTestTip' }; module.exports = Opentip; diff --git a/dev/External/ko.js b/dev/External/ko.js index cbd3279f4..61972672f 100644 --- a/dev/External/ko.js +++ b/dev/External/ko.js @@ -20,6 +20,39 @@ } ; + ko.bindingHandlers.editor = { + 'init': function (oElement, fValueAccessor) { + + var + fValue = fValueAccessor(), + oEditor = null, + fUpdateEditorValue = function () { + if (oEditor) + { + oEditor.setHtmlOrPlain(fValue()); + } + }, + fUpdateKoValue = function () { + if (oEditor) + { + fValue(oEditor.getDataWithHtmlMark()); + } + }, + HtmlEditor = require('Common/HtmlEditor') + ; + + if (fValue) + { + oEditor = new HtmlEditor(oElement, fUpdateKoValue, fUpdateEditorValue, fUpdateKoValue); + fValue.__editor = oEditor; + fValue.__fetchEditorValue = fUpdateKoValue; + fValue.__updateEditorValue = fUpdateEditorValue; + + fValue.subscribe(fUpdateEditorValue); + } + } + }; + ko.bindingHandlers.tooltip = { 'init': function (oElement, fValueAccessor) { diff --git a/dev/Model/MessageSimple.js b/dev/Model/MessageSimple.js index 00b582a20..ed994eebd 100644 --- a/dev/Model/MessageSimple.js +++ b/dev/Model/MessageSimple.js @@ -71,7 +71,7 @@ }; /** - * @param {AjaxJsonMessage} oJson + * @param {Object} oJson * @return {boolean} */ MessageSimpleModel.prototype.initByJson = function (oJson) @@ -85,14 +85,16 @@ this.subject = Utils.pString(oJson.Subject); - this.subjectPrefix = ''; - this.subjectSuffix = this.subject; - if (Utils.isArray(oJson.SubjectParts)) { this.subjectPrefix = Utils.pString(oJson.SubjectParts[0]); this.subjectSuffix = Utils.pString(oJson.SubjectParts[1]); } + else + { + this.subjectPrefix = ''; + this.subjectSuffix = this.subject; + } this.from = MessageHelper.emailArrayFromJson(oJson.From); this.to = MessageHelper.emailArrayFromJson(oJson.To); @@ -132,7 +134,7 @@ /** * @static - * @param {AjaxJsonMessage} oJson + * @param {Object} oJson * @return {?MessageSimpleModel} */ MessageSimpleModel.newInstanceFromJson = function (oJson) diff --git a/dev/Model/MessageStates.js b/dev/Model/MessageStates.js deleted file mode 100644 index cba0a2fd0..000000000 --- a/dev/Model/MessageStates.js +++ /dev/null @@ -1,66 +0,0 @@ - -(function () { - - 'use strict'; - - var - _ = require('_'), - ko = require('ko'), - -// Enums = require('Common/Enums'), -// Utils = require('Common/Utils'), -// -// MessageHelper = require('Helper/Message'), - - AbstractModel = require('Knoin/AbstractModel') - ; - - /** - * @constructor - */ - function MessageStatesModel() - { - AbstractModel.call(this, 'MessageStatesModel'); - - this.flags = {}; - this.states = {}; - - this.flags.unseen = ko.observable(false); - this.flags.deleted = ko.observable(false); - this.flags.flagged = ko.observable(false); - this.flags.answered = ko.observable(false); - this.flags.forwarded = ko.observable(false); - - this.states.checked = ko.observable(false); - this.states.deleted = ko.observable(false); - this.states.selected = ko.observable(false); - this.states.focused = ko.observable(false); - - this.states.showReadReceipt = ko.observable(false); - this.states.showExternalImages = ko.observable(false); - - this.states.hasUnseenSubMessages = ko.observable(false); - this.states.hasFlaggedSubMessages = ko.observable(false); - - this.threads = ko.observableArray([]); - } - - _.extend(MessageStatesModel.prototype, AbstractModel.prototype); - - MessageStatesModel.prototype.flags = {}; - MessageStatesModel.prototype.states = {}; - - MessageStatesModel.prototype.clear = function () - { - this.flags.unseen(false); - this.flags.deleted(false); - this.flags.flagged(false); - this.flags.answered(false); - this.flags.forwarded(false); - - this.threads([]); - }; - - module.exports = MessageStatesModel; - -}()); \ No newline at end of file diff --git a/dev/Promises/User/Ajax.js b/dev/Promises/User/Ajax.js index 2d81901ff..3f566c05e 100644 --- a/dev/Promises/User/Ajax.js +++ b/dev/Promises/User/Ajax.js @@ -113,6 +113,49 @@ }); }; +// UserAjaxUserPromises.prototype.messageList = function (sFolderFullNameRaw, iOffset, iLimit, sSearch, fTrigger) +// { +// sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw); +// sSearch = Utils.pString(sSearch); +// iOffset = Utils.pInt(iOffset); +// iLimit = Utils.pInt(iLimit); +// +// var sFolderHash = Cache.getFolderHash(sFolderFullNameRaw); +// +// if ('' !== sFolderHash && ('' === sSearch || -1 === sSearch.indexOf('is:'))) +// { +// return this.abort('MessageList') +// .getRequest('MessageList', fTrigger, +// Links.subQueryPrefix() + '/' + Base64.urlsafe_encode([ +// sFolderFullNameRaw, +// iOffset, +// iLimit, +// sSearch, +// AppStore.projectHash(), +// sFolderHash, +// Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '', +// AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0', +// '' +// ].join(String.fromCharCode(0)))) +// .then(PromisesPopulator.messageList); +// } +// else +// { +// return this.abort('MessageList') +// .postRequest('MessageList', fTrigger,{ +// 'Folder': sFolderFullNameRaw, +// 'Offset': iOffset, +// 'Limit': iLimit, +// 'Search': sSearch, +// 'UidNext': Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '', +// 'UseThreads': AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0' +// }) +// .then(PromisesPopulator.messageList); +// } +// +// return this.fastReject(Enums.Notification.UnknownError); +// }; +// // UserAjaxUserPromises.prototype.message = function (sFolderFullNameRaw, iUid, fTrigger) // { // sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw); diff --git a/dev/Screen/User/MailBox.js b/dev/Screen/User/MailBox.js index 3c73ae1a1..64bb526cf 100644 --- a/dev/Screen/User/MailBox.js +++ b/dev/Screen/User/MailBox.js @@ -85,11 +85,6 @@ MessageStore.messageListPage(iPage); MessageStore.messageListSearch(sSearch); -// if (Enums.Layout.NoPreview === SettingsStore.layout() && MessageStore.message()) -// { -// MessageStore.message(null); -// } - require('App/User').reloadMessageList(); } }; diff --git a/dev/Stores/User/Message.js b/dev/Stores/User/Message.js index 54222b153..2a93eaa24 100644 --- a/dev/Stores/User/Message.js +++ b/dev/Stores/User/Message.js @@ -55,12 +55,12 @@ this.messageListDisableAutoSelect = ko.observable(false).extend({'falseTimeout': 500}); - // message viewer - this.message = ko.observable(null); - this.selectorMessageSelected = ko.observable(null); this.selectorMessageFocused = ko.observable(null); + // message viewer + this.message = ko.observable(null); + this.message.viewTrigger = ko.observable(false); this.messageLastThreadUidsData = ko.observable(null); @@ -403,6 +403,24 @@ } }; + MessageUserStore.prototype.addBlockquoteSwitcherCallback = function () + { + var $self = $(this); + if ('' !== Utils.trim(($self.text()))) + { + $self.addClass('rl-bq-switcher hidden-bq'); + $('') + .insertBefore($self) + .on('click.rlBlockquoteSwitcher', function () { + $self.toggleClass('hidden-bq'); + Utils.windowResize(); + }) + .after('
') + .before('
') + ; + } + }; + /** * @param {Object} oMessageTextBody */ @@ -416,19 +434,7 @@ if ($oList && 0 < $oList.length) { - $oList.each(function () { - var $self = $(this); - $self.addClass('rl-bq-switcher hidden-bq'); - $('') - .insertBefore($self) - .click(function () { - $self.toggleClass('hidden-bq'); - Utils.windowResize(); - }) - .after('
') - .before('
') - ; - }); + $oList.each(this.addBlockquoteSwitcherCallback); } } }; diff --git a/dev/Styles/Ui.less b/dev/Styles/Ui.less index 17d320aec..94e44bad7 100644 --- a/dev/Styles/Ui.less +++ b/dev/Styles/Ui.less @@ -1,9 +1,9 @@ .g-ui-user-select-none { - webkit-touch-callout: none; - user-select: none; - standard-user-select: none; - touch-callout: none; +// webkit-touch-callout: none; +// user-select: none; +// standard-user-select: none; +// touch-callout: none; } .g-ui-user-select-allow { diff --git a/dev/Styles/_CkeFix.less b/dev/Styles/_CkeFix.less index d022d8a71..a7b486efc 100644 --- a/dev/Styles/_CkeFix.less +++ b/dev/Styles/_CkeFix.less @@ -130,3 +130,31 @@ } } } + +.cke_dialog { + + a:hover { + text-decoration: none; + } + + .cke_dialog_ui_labeled_content { + margin-top: 5px; + margin-bottom: 5px; + } + + .cke_dialog_ui_input_select, .cke_dialog_ui_input_text, .cke_dialog_ui_input_textarea { + + box-shadow: none; + border-radius: 2px; + + &:focus { + outline: 0; + border: 1px solid #999; + } + } + + .cke_dialog_ui_input_select, .cke_dialog_ui_input_text { + height: 25px; + line-height: 25px; + } +} \ No newline at end of file diff --git a/dev/Styles/_End.less b/dev/Styles/_End.less index a0b0e8c4a..73eb20bbe 100644 --- a/dev/Styles/_End.less +++ b/dev/Styles/_End.less @@ -37,4 +37,8 @@ .ot-content { font-size: 13px; } + + &.style-rainloopTestTip .ot-content { + color: red; + } } diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index 099417aba..5e07444d8 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -131,10 +131,42 @@ this.sendSuccessButSaveError = ko.observable(false); this.savedError = ko.observable(false); + this.sendErrorDesc = ko.observable(''); + this.savedErrorDesc = ko.observable(''); + + this.sendError.subscribe(function (bValue) { + if (!bValue) + { + this.sendErrorDesc(''); + } + }, this); + + this.savedError.subscribe(function (bValue) { + if (!bValue) + { + this.savedErrorDesc(''); + } + }, this); + + this.sendSuccessButSaveError.subscribe(function (bValue) { + if (!bValue) + { + this.savedErrorDesc(''); + } + }, this); + this.savedTime = ko.observable(0); - this.savedOrSendingText = ko.observable(''); + this.savedTimeText = ko.computed(function () { + return 0 < this.savedTime() ? Translator.i18n('COMPOSE/SAVED_TIME', { + 'TIME': Momentor.format(this.savedTime() - 1, 'LT') + }) : ''; + }, this); this.emptyToError = ko.observable(false); + this.emptyToErrorTooltip = ko.computed(function () { + return this.emptyToError() ? Translator.i18n('COMPOSE/EMPTY_TO_ERROR_DESC') : ''; + }, this); + this.attachmentsInProcessError = ko.observable(false); this.attachmentsInErrorError = ko.observable(false); @@ -597,27 +629,25 @@ { var aIdentities = IdentityStore.identities(), + iResultIndex = 1000, oResultIdentity = null, oIdentitiesCache = {}, - fFindHelper = function (oItem) { - if (oResultIdentity) - { - return true; - } + fEachHelper = function (oItem) { - if (!oResultIdentity && oItem && oItem.email && oIdentitiesCache[oItem.email]) + if (oItem && oItem.email && oIdentitiesCache[oItem.email]) { - oResultIdentity = oIdentitiesCache[oItem.email]; - return true; + if (!oResultIdentity || iResultIndex > oIdentitiesCache[oItem.email][1]) + { + oResultIdentity = oIdentitiesCache[oItem.email][0]; + iResultIndex = oIdentitiesCache[oItem.email][1]; + } } - - return false; } ; - _.each(aIdentities, function (oItem) { - oIdentitiesCache[oItem.email()] = oItem; + _.each(aIdentities, function (oItem, iIndex) { + oIdentitiesCache[oItem.email()] = [oItem, iIndex]; }); if (oMessage) @@ -630,10 +660,10 @@ case Enums.ComposeType.ReplyAll: case Enums.ComposeType.Forward: case Enums.ComposeType.ForwardAsAttachment: - _.find(_.union(oMessage.to, oMessage.cc, oMessage.bcc, oMessage.deliveredTo), fFindHelper); + _.each(_.union(oMessage.to, oMessage.cc, oMessage.bcc, oMessage.deliveredTo), fEachHelper); break; case Enums.ComposeType.Draft: - _.find(_.union(oMessage.from, oMessage.replyTo), fFindHelper); + _.each(_.union(oMessage.from, oMessage.replyTo), fEachHelper); break; } } @@ -673,7 +703,7 @@ if (oData && Enums.Notification.CantSaveMessage === oData.ErrorCode) { this.sendSuccessButSaveError(true); - window.alert(Utils.trim(Translator.i18n('COMPOSE/SAVED_ERROR_ON_SEND'))); + this.savedErrorDesc(Utils.trim(Translator.i18n('COMPOSE/SAVED_ERROR_ON_SEND'))); } else { @@ -681,7 +711,7 @@ oData && oData.ErrorMessage ? oData.ErrorMessage : ''); this.sendError(true); - window.alert(sMessage || Translator.getNotification(Enums.Notification.CantSendMessage)); + this.sendErrorDesc(sMessage || Translator.getNotification(Enums.Notification.CantSendMessage)); } } @@ -717,12 +747,6 @@ this.savedTime(window.Math.round((new window.Date()).getTime() / 1000)); - this.savedOrSendingText( - 0 < this.savedTime() ? Translator.i18n('COMPOSE/SAVED_TIME', { - 'TIME': Momentor.format(this.savedTime() - 1, 'LT') - }) : '' - ); - if (this.bFromDraft) { Cache.setFolderHash(this.draftFolder(), ''); @@ -733,7 +757,7 @@ if (!bResult) { this.savedError(true); - this.savedOrSendingText(Translator.getNotification(Enums.Notification.CantSaveMessage)); + this.savedErrorDesc(Translator.getNotification(Enums.Notification.CantSaveMessage)); } this.reloadDraftFolder(); @@ -1046,16 +1070,12 @@ oText = $(oMessage.body).clone(); if (oText) { - oText.find('blockquote.rl-bq-switcher').each(function () { - $(this).removeClass('rl-bq-switcher hidden-bq'); - }); - oText.find('.rlBlockquoteSwitcher').each(function () { - $(this).remove(); - }); - } + oText.find('blockquote.rl-bq-switcher').removeClass('rl-bq-switcher hidden-bq'); + oText.find('.rlBlockquoteSwitcher').off('.rlBlockquoteSwitcher').remove(); + oText.find('[data-html-editor-font-wrapper]').removeAttr('data-html-editor-font-wrapper'); - oText.find('[data-html-editor-font-wrapper]').removeAttr('data-html-editor-font-wrapper'); - sText = oText.html(); + sText = oText.html(); + } switch (sComposeType) { @@ -2058,7 +2078,6 @@ this.sendSuccessButSaveError(false); this.savedError(false); this.savedTime(0); - this.savedOrSendingText(''); this.emptyToError(false); this.attachmentsInProcessError(false); diff --git a/dev/View/Popup/Identity.js b/dev/View/Popup/Identity.js index dbfe4ff15..92c931230 100644 --- a/dev/View/Popup/Identity.js +++ b/dev/View/Popup/Identity.js @@ -11,7 +11,6 @@ Globals = require('Common/Globals'), Utils = require('Common/Utils'), Translator = require('Common/Translator'), - HtmlEditor = require('Common/HtmlEditor'), Remote = require('Remote/User/Ajax'), @@ -33,9 +32,6 @@ this.edit = ko.observable(false); this.owner = ko.observable(false); - this.editor = null; - this.signatureDom = ko.observable(null); - this.email = ko.observable('').validateEmail(); this.email.focused = ko.observable(false); this.name = ko.observable(''); @@ -70,7 +66,10 @@ this.addOrEditIdentityCommand = Utils.createCommand(this, function () { - this.populateSignatureFromEditor(); + if (this.signature && this.signature.__fetchEditorValue) + { + this.signature.__fetchEditorValue(); + } if (!this.email.hasError()) { @@ -158,36 +157,6 @@ this.submitRequest(false); this.submitError(''); - - if (this.editor) - { - this.editor.setPlain('', false); - } - }; - - IdentityPopupView.prototype.populateSignatureFromEditor = function () - { - if (this.editor) - { - this.signature(this.editor.getDataWithHtmlMark()); - } - }; - - IdentityPopupView.prototype.editorSetSignature = function (sSignature) - { - if (!this.editor && this.signatureDom()) - { - var self = this; - this.editor = new HtmlEditor(self.signatureDom(), function () { - self.populateSignatureFromEditor(); - }, function () { - self.editor.setHtmlOrPlain(sSignature); - }); - } - else - { - this.editor.setHtmlOrPlain(sSignature); - } }; /** @@ -215,8 +184,6 @@ { this.id = Utils.fakeMd5(); } - - this.editorSetSignature(this.signature()); }; IdentityPopupView.prototype.onShowWithDelay = function () diff --git a/dev/View/Popup/NewOpenPgpKey.js b/dev/View/Popup/NewOpenPgpKey.js index 83e0ac2bf..e929a438a 100644 --- a/dev/View/Popup/NewOpenPgpKey.js +++ b/dev/View/Popup/NewOpenPgpKey.js @@ -61,11 +61,17 @@ this.submitRequest(true); _.delay(function () { - mKeyPair = PgpStore.openpgp.generateKeyPair({ - 'userId': sUserID, - 'numBits': Utils.pInt(self.keyBitLength()), - 'passphrase': Utils.trim(self.password()) - }); + + mKeyPair = false; + try { + mKeyPair = PgpStore.openpgp.generateKeyPair({ + 'userId': sUserID, + 'numBits': Utils.pInt(self.keyBitLength()), + 'passphrase': Utils.trim(self.password()) + }); + } catch (e) { +// window.console.log(e); + } if (mKeyPair && mKeyPair.privateKeyArmored) { @@ -78,6 +84,7 @@ } self.submitRequest(false); + }, 100); return true; diff --git a/rainloop/v/0.0.0/app/templates/Views/Admin/AdminSettingsLicensing.html b/rainloop/v/0.0.0/app/templates/Views/Admin/AdminSettingsLicensing.html index 9c6e7ed24..89a19ccd0 100644 --- a/rainloop/v/0.0.0/app/templates/Views/Admin/AdminSettingsLicensing.html +++ b/rainloop/v/0.0.0/app/templates/Views/Admin/AdminSettingsLicensing.html @@ -79,12 +79,14 @@    + diff --git a/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html b/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html index 85f88b210..820119068 100644 --- a/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html +++ b/rainloop/v/0.0.0/app/templates/Views/User/PopupsCompose.html @@ -1,12 +1,12 @@
diff --git a/rainloop/v/0.0.0/app/templates/Views/User/PopupsTwoStep.html b/rainloop/v/0.0.0/app/templates/Views/User/PopupsTwoStep.html new file mode 100644 index 000000000..b82169a7e --- /dev/null +++ b/rainloop/v/0.0.0/app/templates/Views/User/PopupsTwoStep.html @@ -0,0 +1,64 @@ +
+ +
diff --git a/rainloop/v/0.0.0/static/ckeditor/CUSTOMS b/rainloop/v/0.0.0/static/ckeditor/CUSTOMS index a3c9e8fa1..7ceb2db01 100644 --- a/rainloop/v/0.0.0/static/ckeditor/CUSTOMS +++ b/rainloop/v/0.0.0/static/ckeditor/CUSTOMS @@ -27,4 +27,10 @@ disableContextMenu:function(){return false;this.on("contextmenu", proto:{addTarget:function(a,e){a.on("contextmenu",function(a){ --> -proto:{addTarget:function(a,e){a.on("contextmenu",function(a){return false; \ No newline at end of file +proto:{addTarget:function(a,e){a.on("contextmenu",function(a){return false; + +--- + +var a=this.$.nodeName.toLowerCase(); +--> +var a=(this.$?(this.$.nodeName||''):'').toLowerCase(); \ No newline at end of file diff --git a/vendors/ckeditor/CUSTOMS b/vendors/ckeditor/CUSTOMS index a3c9e8fa1..6713c8963 100644 --- a/vendors/ckeditor/CUSTOMS +++ b/vendors/ckeditor/CUSTOMS @@ -27,4 +27,4 @@ disableContextMenu:function(){return false;this.on("contextmenu", proto:{addTarget:function(a,e){a.on("contextmenu",function(a){ --> -proto:{addTarget:function(a,e){a.on("contextmenu",function(a){return false; \ No newline at end of file +proto:{addTarget:function(a,e){a.on("contextmenu",function(a){return false;