diff --git a/Gruntfile.js b/Gruntfile.js index 5afd556a9..d001f0cd2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -171,6 +171,7 @@ module.exports = function (grunt) { "dev/ViewModels/PopupsPluginViewModel.js", "dev/ViewModels/PopupsActivateViewModel.js", "dev/ViewModels/PopupsLanguagesViewModel.js", + "dev/ViewModels/PopupsAskViewModel.js", "dev/ViewModels/AdminLoginViewModel.js", @@ -260,6 +261,7 @@ module.exports = function (grunt) { "dev/ViewModels/PopupsAddAccountViewModel.js", "dev/ViewModels/PopupsIdentityViewModel.js", "dev/ViewModels/PopupsLanguagesViewModel.js", + "dev/ViewModels/PopupsAskViewModel.js", "dev/ViewModels/LoginViewModel.js", diff --git a/dev/Admin/Plugins.js b/dev/Admin/Plugins.js index 4e54bbb86..dd6e87591 100644 --- a/dev/Admin/Plugins.js +++ b/dev/Admin/Plugins.js @@ -35,8 +35,27 @@ AdminPlugins.prototype.configurePlugin = function (oPlugin) RL.remote().plugin(this.onPluginLoadRequest, oPlugin.name); }; -AdminPlugins.prototype.onBuild = function () +AdminPlugins.prototype.onBuild = function (oDom) { + var self = this; + + oDom + .on('click', '.e-item .configure-plugin-action', function () { + var oPlugin = ko.dataFor(this); + if (oPlugin) + { + self.configurePlugin(oPlugin); + } + }) + .on('click', '.e-item .disable-plugin', function () { + var oPlugin = ko.dataFor(this); + if (oPlugin) + { + self.disablePlugin(oPlugin); + } + }) + ; + this.enabledPlugins.subscribe(function (bValue) { RL.remote().saveAdminConfig(Utils.emptyFunction, { 'EnabledPlugins': bValue ? '1' : '0' diff --git a/dev/Boots/AbstractApp.js b/dev/Boots/AbstractApp.js index 3e97620d5..b8045903c 100644 --- a/dev/Boots/AbstractApp.js +++ b/dev/Boots/AbstractApp.js @@ -240,7 +240,6 @@ AbstractApp.prototype.pub = function (sName, aArgs) { if (!Utils.isUnd(this.oSubs[sName])) { - window.console.log(sName); _.each(this.oSubs[sName], function (aItem) { if (aItem[0]) { diff --git a/dev/Common/Enums.js b/dev/Common/Enums.js index 1221ded4b..9a3ab9aaa 100644 --- a/dev/Common/Enums.js +++ b/dev/Common/Enums.js @@ -110,6 +110,7 @@ Enums.ClientSideKeyName = { */ Enums.EventKeyCode = { 'Backspace': 8, + 'Tab': 9, 'Enter': 13, 'Esc': 27, 'PageUp': 33, diff --git a/dev/Styles/@Main.less b/dev/Styles/@Main.less index 728c76290..ea0e7b5f3 100644 --- a/dev/Styles/@Main.less +++ b/dev/Styles/@Main.less @@ -40,6 +40,7 @@ @import "Scroll.less"; @import "SystemDropDown.less"; @import "Login.less"; +@import "Ask.less"; @import "FolderList.less"; @import "FolderClear.less"; @import "FolderCreate.less"; diff --git a/dev/Styles/Ask.less b/dev/Styles/Ask.less new file mode 100644 index 000000000..de9299341 --- /dev/null +++ b/dev/Styles/Ask.less @@ -0,0 +1,20 @@ +.popups { + .b-ask-content { + + &.modal { + z-index: 10000; + } + + .modal-header { + background-color: #fff; + } + + .modal-body { + text-align: center; + } + + .desc-place { + font-size: 18px; + } + } +} diff --git a/dev/Styles/_End.less b/dev/Styles/_End.less index 99a809136..3eadac4e1 100644 --- a/dev/Styles/_End.less +++ b/dev/Styles/_End.less @@ -1,2 +1,5 @@ - - +input[type="text"], input[type="password"], input[type="email"], input[type="search"] { + height: 20px; + line-height: 21px; +} + diff --git a/dev/Styles/_InputosaurusFix.less b/dev/Styles/_InputosaurusFix.less index c8b9ab275..0fe753dff 100644 --- a/dev/Styles/_InputosaurusFix.less +++ b/dev/Styles/_InputosaurusFix.less @@ -45,12 +45,6 @@ } } - .inputosaurus-fake-span { - position: absolute; - top: 0; - left: -5000px; - } - .inputosaurus-input { margin: 1px 10px 1px 0px; @@ -66,4 +60,10 @@ .ui-autocomplete { z-index: 2000; -} \ No newline at end of file +} + +.inputosaurus-fake-span { + position: absolute; + top: 0; + left: -5000px; +} diff --git a/dev/ViewModels/PopupsAddAccountViewModel.js b/dev/ViewModels/PopupsAddAccountViewModel.js index 13252d788..3ac52e917 100644 --- a/dev/ViewModels/PopupsAddAccountViewModel.js +++ b/dev/ViewModels/PopupsAddAccountViewModel.js @@ -108,8 +108,18 @@ PopupsAddAccountViewModel.prototype.onShow = function () this.emailFocus(true); }; - PopupsAddAccountViewModel.prototype.onBuild = function () { this.allowCustomLogin(!!RL.settingsGet('AllowCustomLogin')); + + var self = this; + $window.on('keydown', function (oEvent) { + var bResult = true; + if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility()) + { + kn.delegateRun(self, 'cancelCommand'); + bResult = false; + } + return bResult; + }); }; diff --git a/dev/ViewModels/PopupsAdvancedSearchViewModel.js b/dev/ViewModels/PopupsAdvancedSearchViewModel.js index ed44ee165..ad8d7650e 100644 --- a/dev/ViewModels/PopupsAdvancedSearchViewModel.js +++ b/dev/ViewModels/PopupsAdvancedSearchViewModel.js @@ -105,3 +105,17 @@ PopupsAdvancedSearchViewModel.prototype.onShow = function () this.fromFocus(true); }; + +PopupsAdvancedSearchViewModel.prototype.onBuild = function () +{ + var self = this; + $window.on('keydown', function (oEvent) { + var bResult = true; + if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility()) + { + kn.delegateRun(self, 'cancelCommand'); + bResult = false; + } + return bResult; + }); +}; diff --git a/dev/ViewModels/PopupsAskViewModel.js b/dev/ViewModels/PopupsAskViewModel.js new file mode 100644 index 000000000..06d1a7c59 --- /dev/null +++ b/dev/ViewModels/PopupsAskViewModel.js @@ -0,0 +1,116 @@ +/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ + +/** + * @constructor + * @extends KnoinAbstractViewModel + */ +function PopupsAskViewModel() +{ + KnoinAbstractViewModel.call(this, 'Popups', 'PopupsAsk'); + + this.askDesc = ko.observable(''); + this.yesButton = ko.observable(''); + this.noButton = ko.observable(''); + + this.yesFocus = ko.observable(false); + this.noFocus = ko.observable(false); + + this.fYesAction = null; + this.fNoAction = null; + + Knoin.constructorEnd(this); +} + +Utils.extendAsViewModel('PopupsAskViewModel', PopupsAskViewModel); + +PopupsAskViewModel.prototype.clearPopup = function () +{ + this.askDesc(''); + this.yesButton(Utils.i18n('POPUPS_ASK/BUTTON_YES')); + this.noButton(Utils.i18n('POPUPS_ASK/BUTTON_NO')); + + this.yesFocus(false); + this.noFocus(false); + + this.fYesAction = null; + this.fNoAction = null; +}; + +PopupsAskViewModel.prototype.yesClick = function () +{ + if (Utils.isFunc(this.fYesAction)) + { + this.fYesAction.call(null); + } + + this.cancelCommand(); +}; + +PopupsAskViewModel.prototype.noClick = function () +{ + if (Utils.isFunc(this.fNoAction)) + { + this.fNoAction.call(null); + } + + this.cancelCommand(); +}; + +/** + * @param {string} sAskDesc + * @param {Function=} fYesFunc + * @param {Function=} fNoFunc + * @param {string=} sYesButton + * @param {string=} sNoButton + */ +PopupsAskViewModel.prototype.onShow = function (sAskDesc, fYesFunc, fNoFunc, sYesButton, sNoButton) +{ + this.clearPopup(); + + this.fYesAction = fYesFunc || null; + this.fNoAction = fNoFunc || null; + + this.askDesc(sAskDesc || ''); + if (sYesButton) + { + this.yesButton(sYesButton); + } + + if (sYesButton) + { + this.yesButton(sNoButton); + } + + this.yesFocus(true); +}; + +PopupsAskViewModel.prototype.onHide = function () +{ +}; + +PopupsAskViewModel.prototype.onBuild = function () +{ + var self = this; + $window.on('keydown', function (oEvent) { + var bResult = true; + if (oEvent && self.modalVisibility()) + { + if (Enums.EventKeyCode.Tab === oEvent.keyCode || Enums.EventKeyCode.Right === oEvent.keyCode || Enums.EventKeyCode.Left === oEvent.keyCode) + { + if (self.yesFocus()) + { + self.noFocus(true); + } + else + { + self.yesFocus(true); + } + + bResult = false; + } + } + + return bResult; + }); +}; + diff --git a/dev/ViewModels/PopupsComposeViewModel.js b/dev/ViewModels/PopupsComposeViewModel.js index 973c03aa5..00d1bd79d 100644 --- a/dev/ViewModels/PopupsComposeViewModel.js +++ b/dev/ViewModels/PopupsComposeViewModel.js @@ -801,6 +801,17 @@ PopupsComposeViewModel.prototype.onShow = function (sType, oMessageOrArray, aToE this.triggerForResize(); }; +PopupsComposeViewModel.prototype.tryToClosePopup = function () +{ + var self = this; + kn.showScreenPopup(PopupsAskViewModel, [Utils.i18n('POPUPS_ASK/DESC_WANT_CLOSE_THIS_WINDOW'), function () { + if (self.modalVisibility()) + { + kn.delegateRun(self, 'closeCommand'); + } + }]); +}; + PopupsComposeViewModel.prototype.onBuild = function () { this.initEditor(); @@ -826,6 +837,11 @@ PopupsComposeViewModel.prototype.onBuild = function () self.sendCommand(); bResult = false; } + else if (Enums.EventKeyCode.Esc === oEvent.keyCode) + { + self.tryToClosePopup(); + bResult = false; + } } return bResult; diff --git a/dev/ViewModels/PopupsContactsViewModel.js b/dev/ViewModels/PopupsContactsViewModel.js index c64ed7fb3..019b49f79 100644 --- a/dev/ViewModels/PopupsContactsViewModel.js +++ b/dev/ViewModels/PopupsContactsViewModel.js @@ -457,6 +457,17 @@ PopupsContactsViewModel.prototype.onBuild = function (oDom) } }) ; + + $window.on('keydown', function (oEvent) { + var bResult = true; + if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility()) + { + kn.delegateRun(self, 'closeCommand'); + bResult = false; + } + + return bResult; + }); }; PopupsContactsViewModel.prototype.onShow = function () diff --git a/dev/ViewModels/PopupsDomainViewModel.js b/dev/ViewModels/PopupsDomainViewModel.js index 699162f4b..cf943a3ed 100644 --- a/dev/ViewModels/PopupsDomainViewModel.js +++ b/dev/ViewModels/PopupsDomainViewModel.js @@ -186,6 +186,20 @@ PopupsDomainViewModel.prototype.onShow = function (oDomain) } }; +PopupsDomainViewModel.prototype.onBuild = function () +{ + var self = this; + $window.on('keydown', function (oEvent) { + var bResult = true; + if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility()) + { + kn.delegateRun(self, 'cancelCommand'); + bResult = false; + } + return bResult; + }); +}; + PopupsDomainViewModel.prototype.clearForm = function () { this.edit(false); diff --git a/dev/ViewModels/PopupsFolderClearViewModel.js b/dev/ViewModels/PopupsFolderClearViewModel.js index f894bf94c..00a8c527b 100644 --- a/dev/ViewModels/PopupsFolderClearViewModel.js +++ b/dev/ViewModels/PopupsFolderClearViewModel.js @@ -95,3 +95,17 @@ PopupsFolderClearViewModel.prototype.onShow = function (oFolder) this.selectedFolder(oFolder); } }; + +PopupsFolderClearViewModel.prototype.onBuild = function () +{ + var self = this; + $window.on('keydown', function (oEvent) { + var bResult = true; + if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility()) + { + kn.delegateRun(self, 'cancelCommand'); + bResult = false; + } + return bResult; + }); +}; diff --git a/dev/ViewModels/PopupsFolderCreateViewModel.js b/dev/ViewModels/PopupsFolderCreateViewModel.js index 714a00824..469e12d27 100644 --- a/dev/ViewModels/PopupsFolderCreateViewModel.js +++ b/dev/ViewModels/PopupsFolderCreateViewModel.js @@ -105,3 +105,17 @@ PopupsFolderCreateViewModel.prototype.onShow = function () this.clearPopup(); this.focusTrigger(true); }; + +PopupsFolderCreateViewModel.prototype.onBuild = function () +{ + var self = this; + $window.on('keydown', function (oEvent) { + var bResult = true; + if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility()) + { + kn.delegateRun(self, 'cancelCommand'); + bResult = false; + } + return bResult; + }); +}; diff --git a/dev/ViewModels/PopupsFolderSystemViewModel.js b/dev/ViewModels/PopupsFolderSystemViewModel.js index 47e5bdbf2..5e013a794 100644 --- a/dev/ViewModels/PopupsFolderSystemViewModel.js +++ b/dev/ViewModels/PopupsFolderSystemViewModel.js @@ -103,3 +103,17 @@ PopupsFolderSystemViewModel.prototype.onShow = function (iNotificationType) this.notification(sNotification); }; +PopupsFolderSystemViewModel.prototype.onBuild = function () +{ + var self = this; + $window.on('keydown', function (oEvent) { + var bResult = true; + if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility()) + { + kn.delegateRun(self, 'cancelCommand'); + bResult = false; + } + return bResult; + }); +}; + diff --git a/dev/ViewModels/PopupsIdentityViewModel.js b/dev/ViewModels/PopupsIdentityViewModel.js index 152fea4fb..6f19b0671 100644 --- a/dev/ViewModels/PopupsIdentityViewModel.js +++ b/dev/ViewModels/PopupsIdentityViewModel.js @@ -120,7 +120,6 @@ PopupsIdentityViewModel.prototype.clearPopup = function () }; /** - * * @param {?IdentityModel} oIdentity */ PopupsIdentityViewModel.prototype.onShow = function (oIdentity) @@ -145,3 +144,17 @@ PopupsIdentityViewModel.prototype.onShow = function (oIdentity) this.email.focused(true); } }; + +PopupsIdentityViewModel.prototype.onBuild = function () +{ + var self = this; + $window.on('keydown', function (oEvent) { + var bResult = true; + if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility()) + { + kn.delegateRun(self, 'cancelCommand'); + bResult = false; + } + return bResult; + }); +}; diff --git a/dev/ViewModels/PopupsLanguagesViewModel.js b/dev/ViewModels/PopupsLanguagesViewModel.js index 993056089..46026ab72 100644 --- a/dev/ViewModels/PopupsLanguagesViewModel.js +++ b/dev/ViewModels/PopupsLanguagesViewModel.js @@ -54,6 +54,20 @@ PopupsLanguagesViewModel.prototype.onHide = function () this.exp(false); }; +PopupsLanguagesViewModel.prototype.onBuild = function () +{ + var self = this; + $window.on('keydown', function (oEvent) { + var bResult = true; + if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility()) + { + kn.delegateRun(self, 'cancelCommand'); + bResult = false; + } + return bResult; + }); +}; + PopupsLanguagesViewModel.prototype.changeLanguage = function (sLang) { RL.data().mainLanguage(sLang); diff --git a/dev/ViewModels/PopupsPluginViewModel.js b/dev/ViewModels/PopupsPluginViewModel.js index 849f7fc5a..7826e0d23 100644 --- a/dev/ViewModels/PopupsPluginViewModel.js +++ b/dev/ViewModels/PopupsPluginViewModel.js @@ -111,3 +111,28 @@ PopupsPluginViewModel.prototype.onShow = function (oPlugin) } } }; + +PopupsPluginViewModel.prototype.tryToClosePopup = function () +{ + var self = this; + kn.showScreenPopup(PopupsAskViewModel, [Utils.i18n('POPUPS_ASK/DESC_WANT_CLOSE_THIS_WINDOW'), function () { + if (self.modalVisibility()) + { + kn.delegateRun(self, 'cancelCommand'); + } + }]); +}; + +PopupsPluginViewModel.prototype.onBuild = function () +{ + var self = this; + $window.on('keydown', function (oEvent) { + var bResult = true; + if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility()) + { + self.tryToClosePopup(); + bResult = false; + } + return bResult; + }); +}; diff --git a/package.json b/package.json index 46c8ad822..f1ecfd0aa 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "RainLoop", "title": "RainLoop Webmail", - "version": "1.5.0", - "release": "532", + "version": "1.5.1", + "release": "546", "description": "Simple, modern & fast web-based email client", "homepage": "http://rainloop.net", "main": "Gruntfile.js", diff --git a/rainloop/v/0.0.0/app/templates/Views/AdminSettingsContacts.html b/rainloop/v/0.0.0/app/templates/Views/AdminSettingsContacts.html index 6aba2b56a..57001b492 100644 --- a/rainloop/v/0.0.0/app/templates/Views/AdminSettingsContacts.html +++ b/rainloop/v/0.0.0/app/templates/Views/AdminSettingsContacts.html @@ -33,7 +33,7 @@
- PDO (MySQL / PostgreSQL / ...) + PDO (MySQL / PostgreSQL)