diff --git a/dev/Common/Booter.jsx b/dev/Common/Booter.jsx new file mode 100644 index 000000000..c821cbdb2 --- /dev/null +++ b/dev/Common/Booter.jsx @@ -0,0 +1,163 @@ + +import window from 'window'; +import $ from '$'; + +import rainLoopStorage from 'Storage/RainLoop'; + +window.__rlah = () => { + return rainLoopStorage ? rainLoopStorage.getHash() : null; +}; + +window.__rlah_set = () => { + if (rainLoopStorage) + { + rainLoopStorage.setHash(); + } +}; + +window.__rlah_clear = () => { + if (rainLoopStorage) + { + rainLoopStorage.clearHash(); + } +}; + +window.__includeScr = (src) => { + window.document.write(unescape('%3Csc' + 'ript data-cfasync="false" type="text/jav' + 'ascr' + 'ipt" sr' + 'c="' + src + '"%3E%3C/' + 'scr' + 'ipt%3E')); +}; + +window.__includeStyle = (styles) => { + window.document.write(unescape('%3Csty' + 'le%3E' + styles + '"%3E%3C/' + 'sty' + 'le%3E')); +}; + +window.__showError = (additionalError) => { + + const + oR = window.document.getElementById('rl-loading'), + oL = window.document.getElementById('rl-loading-error'), + oLA = window.document.getElementById('rl-loading-error-additional') + ; + + if (oR) + { + oR.style.display = 'none'; + } + + if (oL) + { + oL.style.display = 'block'; + } + + if (oLA && additionalError) + { + oLA.style.display = 'block'; + oLA.innerHTML = additionalError; + } + + if (window.rainloopProgressJs) + { + window.rainloopProgressJs.set(100); + } +}; + +window.__showDescription = (description) => { + + const + oE = window.document.getElementById('rl-loading'), + oElDesc = window.document.getElementById('rl-loading-desc') + ; + + if (oElDesc && description) + { + oElDesc.innerHTML = description; + } + + if (oE && oE.style) + { + oE.style.opacity = 0; + window.setTimeout(() => { + oE.style.opacity = 1; + }, 300); + } +}; + +window.__runBoot = (withError, additionalError) => { + if (window.__APP_BOOT && !withError) { + window.__APP_BOOT(function (bV) { + if (!bV) { + window.__showError(additionalError); + } + }); + } else { + window.__showError(additionalError); + } +}; + +window.__runApp = (BaseAppLibsScriptLink, BaseAppMainScriptLink, BaseAppEditorScriptLink) => { + + const appData = window.rainloopAppData; + + if (window.$LAB && window.progressJs && appData && appData.TemplatesLink && appData.LangLink) + { + const p = window.progressJs(); + window.rainloopProgressJs = p; + + p.setOptions({theme: 'rainloop'}); + p.start().set(5); + + window.$LAB + .script(function () { + return [ + {src: BaseAppLibsScriptLink, type: 'text/javascript', charset: 'utf-8'} + ]; + }) + .wait(function () { + + p.set(20); + + if (appData.IncludeBackground && $) { + $('#rl-bg').attr('style', 'background-image: none !important;') + .backstretch(appData.IncludeBackground.replace('{{USER}}', + (window.__rlah ? window.__rlah() || '0' : '0')), {fade: 100, centeredX: true, centeredY: true}) + .removeAttr('style') + ; + } + }) + .script(function () { + return [ + {src: appData.TemplatesLink, type: 'text/javascript', charset: 'utf-8'}, + {src: appData.LangLink, type: 'text/javascript', charset: 'utf-8'} + ]; + }) + .wait(function () { + p.set(30); + }) + .script(function () { + return {src: BaseAppMainScriptLink, type: 'text/javascript', charset: 'utf-8'}; + }) + .wait(function () { + p.set(50); + }) + .script(function () { + return appData.PluginsLink ? {src: appData.PluginsLink, type: 'text/javascript', charset: 'utf-8'} : null; + }) + .wait(function () { + p.set(70); + window.__runBoot(false); + }) + .script(function () { + return {src: BaseAppEditorScriptLink, type: 'text/javascript', charset: 'utf-8'}; + }) + .wait(function () { + if (window.CKEDITOR && window.__initEditor) { + window.__initEditor(); + window.__initEditor = null; + } + }) + ; + } + else + { + window.__runBoot(true); + } +}; diff --git a/dev/Storage/RainLoop.jsx b/dev/Storage/RainLoop.jsx new file mode 100644 index 000000000..0ebc7ffe1 --- /dev/null +++ b/dev/Storage/RainLoop.jsx @@ -0,0 +1,62 @@ + +import window from 'window'; + +const STORAGE_KEY = '__rlA'; + +class RainLoopStorage +{ + s = null; + t = null; + + constructor() + { + this.s = window.sessionStorage || null; + this.t = window.top || window; + } + + getHash() { + let result = null; + if (this.s) + { + result = this.s.getItem(STORAGE_KEY) || null; + } + else if (this.t && JSON) + { + const data = this.t.name && '{' === this.t.name.toString().substr(0, 1) ? JSON.parse(this.t.name.toString()) : null; + result = data ? (data[STORAGE_KEY] || null) : null; + } + + return result; + } + + setHash() { + const + key = 'AuthAccountHash', + appData = window.rainloopAppData + ; + if (this.s) + { + this.s.setItem(STORAGE_KEY, appData && appData[key] ? appData[key] : ''); + } + else if (this.t && JSON) + { + let data = {}; + data[STORAGE_KEY] = appData && appData[key] ? appData[key] : ''; + + this.t.name = JSON.stringify(data); + } + } + + clearHash() { + if (this.s) + { + this.s.setItem(STORAGE_KEY, ''); + } + else if (this.t) + { + this.t.name = ''; + } + } +} + +module.exports = new RainLoopStorage(); diff --git a/dev/Styles/Main.less b/dev/Styles/Main.less index 1146ebecb..684fb162b 100644 --- a/dev/Styles/Main.less +++ b/dev/Styles/Main.less @@ -51,7 +51,7 @@ select:focus { outline: none; } -html.mobile * { +html.mobile *, html.rl-mobile * { -webkit-tap-highlight-color: rgba(0,0,0,0); } diff --git a/dev/boot.jsx b/dev/boot.jsx new file mode 100644 index 000000000..e15efc72e --- /dev/null +++ b/dev/boot.jsx @@ -0,0 +1,12 @@ + +import window from 'window'; + +require('json2/json2.js'); +require('modernizr/modernizr-custom.js'); +require('Common/Booter.jsx'); + +import {$LAB} from 'labjs/LAB.src.js'; +import {progressJs} from 'progress.js/src/progress.js'; + +window.$LAB = $LAB; +window.progressJs = progressJs; diff --git a/gulpfile.js b/gulpfile.js index e278bd1c5..922754975 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -141,16 +141,6 @@ cfg.paths.css = { }; cfg.paths.js = { - boot: { - name: 'boot.js', - src: [ - 'vendors/json2.min.js', - 'vendors/labjs/LAB.min.js', - 'vendors/modernizr.js', - 'vendors/progress.js/minified/progress.min.js', - 'vendors/rl/rl-1.5.min.js' - ] - }, openpgp: { name: 'openpgp.min.js', src: [ @@ -293,13 +283,6 @@ gulp.task('css:main:min', ['css:main'], function() { }); // JS -gulp.task('js:boot', function() { - return gulp.src(cfg.paths.js.boot.src) - .pipe(concat(cfg.paths.js.boot.name)) - .pipe(eol('\n', true)) - .pipe(gulp.dest(cfg.paths.staticMinJS)); -}); - gulp.task('js:encrypt', function() { return gulp.src(cfg.paths.js.encrypt.src) .pipe(concat(cfg.paths.js.encrypt.name)) @@ -705,7 +688,7 @@ gulp.task('rainloop:owncloud:shortname', ['rainloop:owncloud:md5'], function(cal // MAIN gulp.task('js:pgp', ['js:openpgp', 'js:openpgpworker']); -gulp.task('default', ['js:libs', 'js:boot', 'js:pgp', 'js:min', 'css:main:min', 'ckeditor', 'fontastic']); +gulp.task('default', ['js:libs', 'js:pgp', 'js:min', 'css:main:min', 'ckeditor', 'fontastic']); gulp.task('fast-', ['js:app', 'js:admin', 'js:chunks', 'css:main']); gulp.task('fast', ['package:community-on', 'fast-']); diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php index ee66948a8..c067e9545 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php @@ -194,9 +194,14 @@ class Service } $aTemplateParameters = $this->indexTemplateParameters($bAdmin, $bMobile, $bMobileDevice); + if (!empty($aTemplateParameters['{{BaseApplicationConfigurationJson}}'])) + { + $this->oActions->Logger()->Write($aTemplateParameters['{{BaseApplicationConfigurationJson}}'], + \MailSo\Log\Enumerations\Type::INFO, 'APP'); + } $sCacheFileName = ''; - if ($this->oActions->Config()->Get('labs', 'cache_system_data', true)) + if ($this->oActions->Config()->Get('labs', 'cache_system_data', true) && !empty($aTemplateParameters['{{BaseHash}}'])) { $sCacheFileName = 'TMPL:'.$aTemplateParameters['{{BaseHash}}']; $sResult = $this->oActions->Cacher()->Get($sCacheFileName); @@ -327,6 +332,18 @@ class Service ) : array()); } + /** + * @param string $sPath + * + * @return string + */ + private function staticPath($sPath) + { + $sStaticSuffix = $this->oActions->IsOpen() ? '?vo' : '?vs'; + + return \RainLoop\Utils::WebStaticPath().$sPath.$sStaticSuffix; + } + /** * @param bool $bAdmin = false * @param bool $bMobile = false @@ -346,21 +363,18 @@ class Service $sFaviconUrl = (string) $this->oActions->Config()->Get('webmail', 'favicon_url', ''); - $sStaticPrefix = \RainLoop\Utils::WebStaticPath(); - $aData = array( 'Language' => $sLanguage, 'Theme' => $sTheme, - 'FaviconPngLink' => $sFaviconUrl ? $sFaviconUrl : $sStaticPrefix.'favicon.png', - 'AppleTouchLink' => $sFaviconUrl ? '' : $sStaticPrefix.'apple-touch-icon.png', - 'AppCssLink' => $sStaticPrefix.'css/app'.($bAppCssDebug ? '' : '.min').'.css', - 'BootJsLink' => $sStaticPrefix.'js/min/boot.js', - 'ComponentsJsLink' => $sStaticPrefix.'js/'.($bAppJsDebug ? '' : 'min/').'components.js', - 'LibJsLink' => $sStaticPrefix.'js/min/libs.js', - 'EditorJsLink' => $sStaticPrefix.'ckeditor/ckeditor.js', - 'OpenPgpJsLink' => $sStaticPrefix.'js/min/openpgp.min.js', - 'AppJsCommonLink' => $sStaticPrefix.'js/'.($bAppJsDebug ? '' : 'min/').'common.js', - 'AppJsLink' => $sStaticPrefix.'js/'.($bAppJsDebug ? '' : 'min/').($bAdmin ? 'admin' : 'app').'.js' + 'FaviconPngLink' => $sFaviconUrl ? $sFaviconUrl : $this->staticPath('apple-touch-icon.png'), + 'AppleTouchLink' => $sFaviconUrl ? '' : $this->staticPath('apple-touch-icon.png'), + 'AppCssLink' => $this->staticPath('css/app'.($bAppCssDebug ? '' : '.min').'.css'), + 'BootJsLink' => $this->staticPath('js/'.($bAppJsDebug ? '' : 'min/').'boot.js'), + 'LibJsLink' => $this->staticPath('js/min/libs.js'), + 'EditorJsLink' => $this->staticPath('ckeditor/ckeditor.js'), + 'OpenPgpJsLink' => $this->staticPath('js/min/openpgp.min.js'), + 'AppJsCommonLink' => $this->staticPath('js/'.($bAppJsDebug ? '' : 'min/').'common.js'), + 'AppJsLink' => $this->staticPath('js/'.($bAppJsDebug ? '' : 'min/').($bAdmin ? 'admin' : 'app').'.js') ); $aTemplateParameters = array( @@ -370,7 +384,6 @@ class Service '{{BaseAppAppleTouchFile}}' => $aData['AppleTouchLink'], '{{BaseAppMainCssLink}}' => $aData['AppCssLink'], '{{BaseAppBootScriptLink}}' => $aData['BootJsLink'], - '{{BaseAppComponentsScriptLink}}' => $aData['ComponentsJsLink'], '{{BaseAppLibsScriptLink}}' => $aData['LibJsLink'], '{{BaseAppEditorScriptLink}}' => $aData['EditorJsLink'], '{{BaseAppOpenPgpScriptLink}}' => $aData['OpenPgpJsLink'], @@ -388,7 +401,8 @@ class Service $bAdmin ? '1' : '0', \md5($this->oActions->Config()->Get('cache', 'index', '')), $this->oActions->Plugins()->Hash(), - \RainLoop\Utils::WebVersionPath(), APP_VERSION + \RainLoop\Utils::WebVersionPath(), + APP_VERSION, )). \implode('~', $aTemplateParameters) ); diff --git a/rainloop/v/0.0.0/app/templates/Index.html b/rainloop/v/0.0.0/app/templates/Index.html index 743ee8cf6..cf8b65624 100644 --- a/rainloop/v/0.0.0/app/templates/Index.html +++ b/rainloop/v/0.0.0/app/templates/Index.html @@ -69,89 +69,7 @@
- - + +