diff --git a/README.md b/README.md
index 3512dacbd..2598653b5 100644
--- a/README.md
+++ b/README.md
@@ -113,23 +113,23 @@ RainLoop 1.14 vs SnappyMail
|js/* |RainLoop |Snappy |
|--------------- |--------: |--------: |
-|admin.js |2.130.942 | 120.785 |
-|app.js |4.184.455 | 529.074 |
+|admin.js |2.130.942 | 119.180 |
+|app.js |4.184.455 | 527.492 |
|boot.js | 671.522 | 4.842 |
|libs.js | 647.614 | 235.475 |
|polyfills.js | 325.834 | 0 |
|serviceworker.js | 0 | 285 |
-|TOTAL |7.960.367 | 890.449 |
+|TOTAL |7.960.367 | 887.274 |
|js/min/* |RainLoop |Snappy |Rain gzip |gzip |brotli |
|--------------- |--------: |--------: |--------: |--------: |--------: |
-|admin.min.js | 252.147 | 62.863 | 73.657 | 18.009 | 15.992 |
-|app.min.js | 511.202 | 259.534 |140.462 | 74.005 | 62.184 |
+|admin.min.js | 252.147 | 61.128 | 73.657 | 17.416 | 15.445 |
+|app.min.js | 511.202 | 256.673 |140.462 | 73.698 | 61.839 |
|boot.min.js | 66.007 | 2.630 | 22.567 | 1.375 | 1.189 |
|libs.min.js | 572.545 | 130.930 |176.720 | 47.397 | 42.116 |
|polyfills.min.js | 32.452 | 0 | 11.312 | 0 | 0 |
-|TOTAL |1.434.353 | 455.957 |424.718 |140.786 |121.481 |
-|TOTAL (no admin) |1.182.206 | 393.094 |351.061 |122.777 |105.489 |
+|TOTAL |1.434.353 | 451.361 |424.718 |139.886 |120.589 |
+|TOTAL (no admin) |1.182.206 | 390.233 |351.061 |122.470 |105.144 |
For a user its around 65% smaller and faster than traditional RainLoop.
diff --git a/dev/App/Abstract.js b/dev/App/Abstract.js
index 304ceffcb..3ae56927b 100644
--- a/dev/App/Abstract.js
+++ b/dev/App/Abstract.js
@@ -9,17 +9,17 @@ import {
import { KeyState } from 'Common/Enums';
import { rootAdmin, rootUser } from 'Common/Links';
-import { initOnStartOrLangChange } from 'Common/Translator';
+import { i18nToNodes, initOnStartOrLangChange } from 'Common/Translator';
-import LanguageStore from 'Stores/Language';
+import { LanguageStore } from 'Stores/Language';
import { ThemeStore } from 'Stores/Theme';
-import SaveTriggerComponent from 'Component/SaveTrigger';
-import InputComponent from 'Component/Input';
-import SelectComponent from 'Component/Select';
-import TextAreaComponent from 'Component/TextArea';
-import CheckboxMaterialDesignComponent from 'Component/MaterialDesign/Checkbox';
-import CheckboxComponent from 'Component/Checkbox';
+import { SaveTriggerComponent } from 'Component/SaveTrigger';
+import { InputComponent } from 'Component/Input';
+import { SelectComponent } from 'Component/Select';
+import { TextAreaComponent } from 'Component/TextArea';
+import { CheckboxMaterialDesignComponent } from 'Component/MaterialDesign/Checkbox';
+import { CheckboxComponent } from 'Component/Checkbox';
export class AbstractApp {
/**
@@ -84,16 +84,39 @@ export class AbstractApp {
bootstart() {
const mobile = Settings.app('mobile'),
- register = (key, obj) => ko.components.register(key, obj);
+ register = (key, ClassObject, templateID) => ko.components.register(key, {
+ template: { element: templateID || (key + 'Component') },
+ viewModel: {
+ createViewModel: (params, componentInfo) => {
+ params = params || {};
+ params.element = null;
+
+ if (componentInfo && componentInfo.element) {
+ params.component = componentInfo;
+ params.element = componentInfo.element;
+
+ i18nToNodes(componentInfo.element);
+
+ if (undefined !== params.inline && ko.unwrap(params.inline)) {
+ params.element.style.display = 'inline-block';
+ }
+ }
+
+ return new ClassObject(params);
+ }
+ }
+ });
register('SaveTrigger', SaveTriggerComponent);
register('Input', InputComponent);
register('Select', SelectComponent);
register('TextArea', TextAreaComponent);
- register('CheckboxSimple', CheckboxComponent);
- register('Checkbox', Settings.app('materialDesign') && !mobile
- ? CheckboxMaterialDesignComponent
- : CheckboxComponent);
+ register('CheckboxSimple', CheckboxComponent, 'CheckboxComponent');
+ if (mobile || !Settings.app('materialDesign')) {
+ register('Checkbox', CheckboxComponent);
+ } else {
+ register('Checkbox', CheckboxMaterialDesignComponent, 'CheckboxMaterialDesignComponent');
+ }
initOnStartOrLangChange();
diff --git a/dev/Common/Plugins.js b/dev/Common/Plugins.js
index cf2858d13..e49164fd4 100644
--- a/dev/Common/Plugins.js
+++ b/dev/Common/Plugins.js
@@ -9,11 +9,9 @@ const USER_VIEW_MODELS_HOOKS = [],
* @param {Object=} parameters
* @param {?number=} timeout
*/
-export function remoteRequest(callback, action, parameters, timeout) {
- if (rl.app) {
- rl.app.remote().defaultRequest(callback, 'Plugin' + action, parameters, timeout);
- }
-}
+rl.pluginRemoteRequest = (callback, action, parameters, timeout) => {
+ rl.app && rl.app.remote().defaultRequest(callback, 'Plugin' + action, parameters, timeout);
+};
/**
* @param {Function} SettingsViewModelClass
@@ -21,9 +19,9 @@ export function remoteRequest(callback, action, parameters, timeout) {
* @param {string} template
* @param {string} route
*/
-export function addSettingsViewModel(SettingsViewModelClass, template, labelName, route) {
+rl.addSettingsViewModel = (SettingsViewModelClass, template, labelName, route) => {
USER_VIEW_MODELS_HOOKS.push([SettingsViewModelClass, template, labelName, route]);
-}
+};
/**
* @param {Function} SettingsViewModelClass
@@ -31,9 +29,9 @@ export function addSettingsViewModel(SettingsViewModelClass, template, labelName
* @param {string} template
* @param {string} route
*/
-export function addSettingsViewModelForAdmin(SettingsViewModelClass, template, labelName, route) {
+rl.addSettingsViewModelForAdmin = (SettingsViewModelClass, template, labelName, route) => {
ADMIN_VIEW_MODELS_HOOKS.push([SettingsViewModelClass, template, labelName, route]);
-}
+};
/**
* @param {boolean} admin
@@ -49,8 +47,8 @@ export function runSettingsViewModelHooks(admin) {
* @param {string} name
* @returns {?}
*/
-export function settingsGet(pluginSection, name) {
+rl.pluginSettingsGet = (pluginSection, name) => {
let plugins = rl.settings.get('Plugins');
plugins = plugins && null != plugins[pluginSection] ? plugins[pluginSection] : null;
return plugins ? (null == plugins[name] ? null : plugins[name]) : null;
-}
+};
diff --git a/dev/Component/Abstract.js b/dev/Component/Abstract.js
index 42b3754c8..61640cae0 100644
--- a/dev/Component/Abstract.js
+++ b/dev/Component/Abstract.js
@@ -1,8 +1,5 @@
-import ko from 'ko';
-import { i18nToNodes } from 'Common/Translator';
-
-class AbstractComponent {
+export class AbstractComponent {
disposable = [];
dispose() {
@@ -13,33 +10,3 @@ class AbstractComponent {
});
}
}
-
-/**
- * @param {*} ClassObject
- * @param {string} templateID = ''
- * @returns {Object}
- */
-const componentExportHelper = (ClassObject, templateID = '') => ({
- template: templateID ? { element: templateID } : '',
- viewModel: {
- createViewModel: (params, componentInfo) => {
- params = params || {};
- params.element = null;
-
- if (componentInfo && componentInfo.element) {
- params.component = componentInfo;
- params.element = componentInfo.element;
-
- i18nToNodes(componentInfo.element);
-
- if (undefined !== params.inline && ko.unwrap(params.inline)) {
- params.element.style.display = 'inline-block';
- }
- }
-
- return new ClassObject(params);
- }
- }
-});
-
-export { AbstractComponent, componentExportHelper };
diff --git a/dev/Component/Checkbox.js b/dev/Component/Checkbox.js
index a8c7f6fd6..9927babdc 100644
--- a/dev/Component/Checkbox.js
+++ b/dev/Component/Checkbox.js
@@ -1,6 +1,3 @@
-import { componentExportHelper } from 'Component/Abstract';
import { AbstractCheckbox } from 'Component/AbstractCheckbox';
-class CheckboxComponent extends AbstractCheckbox {}
-
-export default componentExportHelper(CheckboxComponent, 'CheckboxComponent');
+export class CheckboxComponent extends AbstractCheckbox {}
diff --git a/dev/Component/Input.js b/dev/Component/Input.js
index c9df0a461..ca0a450fa 100644
--- a/dev/Component/Input.js
+++ b/dev/Component/Input.js
@@ -1,6 +1,3 @@
-import { componentExportHelper } from 'Component/Abstract';
import { AbstractInput } from 'Component/AbstractInput';
-class InputComponent extends AbstractInput {}
-
-export default componentExportHelper(InputComponent, 'InputComponent');
+export class InputComponent extends AbstractInput {}
diff --git a/dev/Component/MaterialDesign/Checkbox.js b/dev/Component/MaterialDesign/Checkbox.js
index 2aefa32ad..547fb1b69 100644
--- a/dev/Component/MaterialDesign/Checkbox.js
+++ b/dev/Component/MaterialDesign/Checkbox.js
@@ -1,8 +1,7 @@
import ko from 'ko';
-import { componentExportHelper } from 'Component/Abstract';
import { AbstractCheckbox } from 'Component/AbstractCheckbox';
-class CheckboxMaterialDesignComponent extends AbstractCheckbox {
+export class CheckboxMaterialDesignComponent extends AbstractCheckbox {
/**
* @param {Object} params
*/
@@ -40,5 +39,3 @@ class CheckboxMaterialDesignComponent extends AbstractCheckbox {
}
}
}
-
-export default componentExportHelper(CheckboxMaterialDesignComponent, 'CheckboxMaterialDesignComponent');
diff --git a/dev/Component/SaveTrigger.js b/dev/Component/SaveTrigger.js
index 220ea6548..166535547 100644
--- a/dev/Component/SaveTrigger.js
+++ b/dev/Component/SaveTrigger.js
@@ -1,7 +1,7 @@
import { SaveSettingsStep } from 'Common/Enums';
-import { AbstractComponent, componentExportHelper } from 'Component/Abstract';
+import { AbstractComponent } from 'Component/Abstract';
-class SaveTriggerComponent extends AbstractComponent {
+export class SaveTriggerComponent extends AbstractComponent {
/**
* @param {Object} params
*/
@@ -36,5 +36,3 @@ class SaveTriggerComponent extends AbstractComponent {
this.element.querySelector('.error').hidden = value !== SaveSettingsStep.FalseResult;
}
}
-
-export default componentExportHelper(SaveTriggerComponent, 'SaveTriggerComponent');
diff --git a/dev/Component/Script.js b/dev/Component/Script.js
deleted file mode 100644
index 0f9b1fa92..000000000
--- a/dev/Component/Script.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { AbstractComponent, componentExportHelper } from 'Component/Abstract';
-
-class ScriptComponent extends AbstractComponent {
- /**
- * @param {Object} params
- */
- constructor(params) {
- super();
-
- if (
- params.component &&
- params.component.templateNodes &&
- params.element
- ) {
- let el = params.element, script = el.outerHTML;
- script = script ? script.replace(/<\/b><\/x-script>/i, '') : '';
-
- if (script) {
- const koNodes = params.component.templateNodes[0];
- el.textContent = '';
- el.replaceWith(
- Element.fromHTML(script).textContent = koNodes && koNodes.nodeValue ? koNodes.nodeValue : ''
- );
- } else {
- el.remove();
- }
- }
- }
-}
-
-export default componentExportHelper(ScriptComponent, 'ScriptComponent');
diff --git a/dev/Component/Select.js b/dev/Component/Select.js
index 37205869d..b7390f7ba 100644
--- a/dev/Component/Select.js
+++ b/dev/Component/Select.js
@@ -1,9 +1,8 @@
import { i18n } from 'Common/Translator';
import { defaultOptionsAfterRender } from 'Common/Utils';
-import { componentExportHelper } from 'Component/Abstract';
import { AbstractInput } from 'Component/AbstractInput';
-class SelectComponent extends AbstractInput {
+export class SelectComponent extends AbstractInput {
/**
* @param {Object} params
*/
@@ -23,5 +22,3 @@ class SelectComponent extends AbstractInput {
this.defaultOptionsAfterRender = defaultOptionsAfterRender;
}
}
-
-export default componentExportHelper(SelectComponent, 'SelectComponent');
diff --git a/dev/Component/TextArea.js b/dev/Component/TextArea.js
index 97d05d6b4..bc2ad55a9 100644
--- a/dev/Component/TextArea.js
+++ b/dev/Component/TextArea.js
@@ -1,18 +1,13 @@
-import { componentExportHelper } from 'Component/Abstract';
import { AbstractInput } from 'Component/AbstractInput';
-const DEFAULT_ROWS = 5;
-
-class TextAreaComponent extends AbstractInput {
+export class TextAreaComponent extends AbstractInput {
/**
* @param {Object} params
*/
constructor(params) {
super(params);
- this.rows = params.rows || DEFAULT_ROWS;
+ this.rows = params.rows || 5;
this.spellcheck = !!params.spellcheck;
}
}
-
-export default componentExportHelper(TextAreaComponent, 'TextAreaComponent');
diff --git a/dev/Settings/Admin/General.js b/dev/Settings/Admin/General.js
index fade40f7d..464530be0 100644
--- a/dev/Settings/Admin/General.js
+++ b/dev/Settings/Admin/General.js
@@ -15,7 +15,7 @@ import { showScreenPopup } from 'Knoin/Knoin';
import Remote from 'Remote/Admin/Fetch';
import { ThemeStore } from 'Stores/Theme';
-import LanguageStore from 'Stores/Language';
+import { LanguageStore } from 'Stores/Language';
import AppAdminStore from 'Stores/Admin/App';
import CapaAdminStore from 'Stores/Admin/Capa';
import LanguagesPopupView from 'View/Popup/Languages';
@@ -26,8 +26,12 @@ export class GeneralAdminSettings {
constructor() {
this.language = LanguageStore.language;
this.languages = LanguageStore.languages;
- this.languageAdmin = LanguageStore.languageAdmin;
- this.languagesAdmin = LanguageStore.languagesAdmin;
+
+ const aLanguagesAdmin = rl.settings.app('languagesAdmin');
+ this.languagesAdmin = ko.observableArray(Array.isArray(aLanguagesAdmin) ? aLanguagesAdmin : []);
+ this.languageAdmin = ko
+ .observable(settingsGet('LanguageAdmin'))
+ .extend({ limitedList: this.languagesAdmin, reversible: true });
this.theme = ThemeStore.theme;
this.themes = ThemeStore.themes;
@@ -174,7 +178,7 @@ export class GeneralAdminSettings {
showScreenPopup(LanguagesPopupView, [
this.languageAdmin,
this.languagesAdmin(),
- LanguageStore.userLanguageAdmin()
+ settingsGet('UserLanguageAdmin')
]);
}
}
diff --git a/dev/Settings/User/General.js b/dev/Settings/User/General.js
index f828eb311..4cc9088b7 100644
--- a/dev/Settings/User/General.js
+++ b/dev/Settings/User/General.js
@@ -12,7 +12,7 @@ import { i18n, trigger as translatorTrigger, reload as translatorReload, convert
import { showScreenPopup } from 'Knoin/Knoin';
import AppStore from 'Stores/User/App';
-import LanguageStore from 'Stores/Language';
+import { LanguageStore } from 'Stores/Language';
import SettingsStore from 'Stores/User/Settings';
import IdentityStore from 'Stores/User/Identity';
import NotificationStore from 'Stores/User/Notification';
diff --git a/dev/Stores/Language.js b/dev/Stores/Language.js
index a2d1139e0..ed7e96421 100644
--- a/dev/Stores/Language.js
+++ b/dev/Stores/Language.js
@@ -1,36 +1,17 @@
import ko from 'ko';
-class LanguageStore {
- constructor() {
- this.languages = ko.observableArray();
- this.languagesAdmin = ko.observableArray();
+export const LanguageStore = {
+ languages: ko.observableArray(),
+ userLanguage: ko.observable(''),
- this.language = ko
- .observable('')
- .extend({ limitedList: this.languages, reversible: true });
-
- this.languageAdmin = ko
- .observable('')
- .extend({ limitedList: this.languagesAdmin, reversible: true });
-
- this.userLanguage = ko.observable('');
- this.userLanguageAdmin = ko.observable('');
- }
-
- populate() {
+ populate: function() {
const Settings = rl.settings,
- aLanguages = Settings.app('languages'),
- aLanguagesAdmin = Settings.app('languagesAdmin');
-
+ aLanguages = Settings.app('languages');
this.languages(Array.isArray(aLanguages) ? aLanguages : []);
- this.languagesAdmin(Array.isArray(aLanguagesAdmin) ? aLanguagesAdmin : []);
-
this.language(Settings.get('Language'));
- this.languageAdmin(Settings.get('LanguageAdmin'));
-
this.userLanguage(Settings.get('UserLanguage'));
- this.userLanguageAdmin(Settings.get('UserLanguageAdmin'));
}
}
-export default new LanguageStore();
+LanguageStore.language = ko.observable('')
+ .extend({ limitedList: LanguageStore.languages, reversible: true });
diff --git a/dev/View/Popup/Languages.js b/dev/View/Popup/Languages.js
index 2f42af61f..350b8e775 100644
--- a/dev/View/Popup/Languages.js
+++ b/dev/View/Popup/Languages.js
@@ -33,7 +33,7 @@ class LanguagesPopupView extends AbstractViewPopup {
setLanguageSelection() {
const currentLang = this.fLang ? ko.unwrap(this.fLang) : '';
- this.languages.forEach(item => item.selected(item.key === currentLang));
+ this.languages().forEach(item => item.selected(item.key === currentLang));
}
onBeforeShow() {
@@ -51,10 +51,7 @@ class LanguagesPopupView extends AbstractViewPopup {
}
changeLanguage(lang) {
- if (this.fLang) {
- this.fLang(lang);
- }
-
+ this.fLang && this.fLang(lang);
this.cancelCommand();
}
}
diff --git a/dev/View/User/Login.js b/dev/View/User/Login.js
index 2ea37d9c0..e781dee1e 100644
--- a/dev/View/User/Login.js
+++ b/dev/View/User/Login.js
@@ -10,7 +10,7 @@ import { ClientSideKeyName } from 'Common/EnumsUser';
import { getNotification, getNotificationFromResponse, reload as translatorReload, convertLangName } from 'Common/Translator';
import AppStore from 'Stores/User/App';
-import LanguageStore from 'Stores/Language';
+import { LanguageStore } from 'Stores/Language';
import * as Local from 'Storage/Client';
diff --git a/dev/bootstrap.js b/dev/bootstrap.js
index 87ec39f2f..479399823 100644
--- a/dev/bootstrap.js
+++ b/dev/bootstrap.js
@@ -1,6 +1,5 @@
import { doc, dropdownVisibility } from 'Common/Globals';
-import * as Enums from 'Common/Enums';
-import * as Plugins from 'Common/Plugins';
+import { StorageResultType } from 'Common/Enums';
import { i18n } from 'Common/Translator';
import { root } from 'Common/Links';
@@ -35,13 +34,9 @@ export default (App) => {
rl.i18n = i18n;
- rl.addSettingsViewModel = Plugins.addSettingsViewModel;
- rl.addSettingsViewModelForAdmin = Plugins.addSettingsViewModelForAdmin;
-
- rl.pluginSettingsGet = Plugins.settingsGet;
- rl.pluginRemoteRequest = Plugins.remoteRequest;
-
- rl.Enums = Enums;
+ rl.Enums = {
+ StorageResultType: StorageResultType
+ };
rl.Dropdowns = [];
rl.Dropdowns.register = function(element) { this.push(element); };