mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-09-20 07:35:55 +08:00
Improve scripts load system
This commit is contained in:
parent
58b9eed8e8
commit
72bf212f67
|
@ -23,7 +23,7 @@ class AbstractApp extends AbstractBoot
|
|||
{
|
||||
super();
|
||||
|
||||
this.iframe = $('<iframe style="display:none" src="javascript:;" />').appendTo('body');
|
||||
this.iframe = $('<iframe style="display:none" />').appendTo('body');
|
||||
|
||||
Globals.$win.on('error', function (oEvent) {
|
||||
if (oEvent && oEvent.originalEvent && oEvent.originalEvent.message &&
|
||||
|
|
|
@ -1213,13 +1213,6 @@ class AppUser extends AbstractApp
|
|||
{
|
||||
kn.hideLoading();
|
||||
|
||||
progressJs.onbeforeend(() => {
|
||||
$('.progressjs-container').hide();
|
||||
_.delay(() => {
|
||||
$('.progressjs-container').remove();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
progressJs.set(100).end();
|
||||
}
|
||||
else
|
||||
|
@ -1239,7 +1232,6 @@ class AppUser extends AbstractApp
|
|||
require('Stores/User/Contact').populate();
|
||||
|
||||
var
|
||||
$LAB = require('$LAB'),
|
||||
sJsHash = Settings.appSettingsGet('jsHash'),
|
||||
sStartupUrl = Utils.pString(Settings.settingsGet('StartupUrl')),
|
||||
iContactsSyncInterval = Utils.pInt(Settings.settingsGet('ContactsSyncInterval')),
|
||||
|
@ -1288,7 +1280,7 @@ class AppUser extends AbstractApp
|
|||
kn.routeOn();
|
||||
}
|
||||
|
||||
if ($LAB && window.crypto && window.crypto.getRandomValues && Settings.capa(Enums.Capa.OpenPGP))
|
||||
if (window.jsloader && window.crypto && window.crypto.getRandomValues && Settings.capa(Enums.Capa.OpenPGP))
|
||||
{
|
||||
const openpgpCallback = (openpgp) => {
|
||||
|
||||
|
@ -1298,8 +1290,7 @@ class AppUser extends AbstractApp
|
|||
{
|
||||
try
|
||||
{
|
||||
// PgpStore.openpgp.initWorker(Links.openPgpWorkerJs()); // 1.2.0
|
||||
PgpStore.openpgp.initWorker({path: Links.openPgpWorkerJs()}); // 2.3.0
|
||||
PgpStore.openpgp.initWorker({path: Links.openPgpWorkerJs()});
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
|
@ -1321,7 +1312,7 @@ class AppUser extends AbstractApp
|
|||
}
|
||||
else
|
||||
{
|
||||
$LAB.script(Links.openPgpJs()).wait(() => {
|
||||
window.jsloader(Links.openPgpJs()).then(() => {
|
||||
if (window.openpgp)
|
||||
{
|
||||
openpgpCallback(window.openpgp);
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
|
||||
import window from 'window';
|
||||
import $ from '$';
|
||||
import progressJs from 'progressJs';
|
||||
|
||||
import rainLoopStorage from 'Storage/RainLoop';
|
||||
|
||||
let rlAppDataStorage = null;
|
||||
|
||||
window.__rlah = () => {
|
||||
return rainLoopStorage ? rainLoopStorage.getHash() : null;
|
||||
};
|
||||
|
||||
window.__rlah_data = () => {
|
||||
return rlAppDataStorage;
|
||||
};
|
||||
|
||||
window.__rlah_set = () => {
|
||||
if (rainLoopStorage)
|
||||
{
|
||||
|
@ -22,20 +29,59 @@ window.__rlah_clear = () => {
|
|||
}
|
||||
};
|
||||
|
||||
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.__includeAppScr = (src) => {
|
||||
window.__includeScr(src + (window.__rlah ? window.__rlah() || '0' : '0') + '/' + window.Math.random().toString().substr(2) + '/');
|
||||
};
|
||||
|
||||
window.__includeStyle = (styles) => {
|
||||
function includeStyle(styles)
|
||||
{
|
||||
window.document.write(unescape('%3Csty' + 'le%3E' + styles + '"%3E%3C/' + 'sty' + 'le%3E'));
|
||||
};
|
||||
}
|
||||
|
||||
window.__showError = (additionalError) => {
|
||||
function includeScr(src)
|
||||
{
|
||||
window.document.write(unescape('%3Csc' + 'ript type="text/jav' + 'ascr' + 'ipt" data-cfasync="false" sr' + 'c="' + src + '"%3E%3C/' + 'scr' + 'ipt%3E'));
|
||||
}
|
||||
|
||||
function includeLayout()
|
||||
{
|
||||
const
|
||||
layout = require('Html/Layout.html'),
|
||||
app = window.document.getElementById('rl-app')
|
||||
;
|
||||
|
||||
if (app && layout)
|
||||
{
|
||||
app.innerHTML = layout.replace(/[\r\n\t]+/g, '');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function includeAppScr(data = {})
|
||||
{
|
||||
let src = './?/';
|
||||
src += data.admin ? 'Admin' : '';
|
||||
src += 'AppData@';
|
||||
src += data.mobile ? 'mobile' : 'no-mobile';
|
||||
src += data.mobileDevice ? '-1' : '-0';
|
||||
src += '/';
|
||||
|
||||
includeScr(src + (window.__rlah ? window.__rlah() || '0' : '0') + '/' + window.Math.random().toString().substr(2) + '/');
|
||||
}
|
||||
|
||||
function getRainloopBootData()
|
||||
{
|
||||
let result = {};
|
||||
const meta = window.document.getElementById('app-boot-data');
|
||||
|
||||
if (meta && meta.getAttribute)
|
||||
{
|
||||
result = JSON.parse(meta.getAttribute('content')) || {};
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function showError(additionalError)
|
||||
{
|
||||
const
|
||||
oR = window.document.getElementById('rl-loading'),
|
||||
oL = window.document.getElementById('rl-loading-error'),
|
||||
|
@ -58,14 +104,14 @@ window.__showError = (additionalError) => {
|
|||
oLA.innerHTML = additionalError;
|
||||
}
|
||||
|
||||
if (window.rainloopProgressJs)
|
||||
if (progressJs)
|
||||
{
|
||||
window.rainloopProgressJs.set(100);
|
||||
progressJs.set(100).end();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.__showDescription = (description) => {
|
||||
|
||||
function showDescriptionAndLoading(description)
|
||||
{
|
||||
const
|
||||
oE = window.document.getElementById('rl-loading'),
|
||||
oElDesc = window.document.getElementById('rl-loading-desc')
|
||||
|
@ -83,76 +129,81 @@ window.__showDescription = (description) => {
|
|||
oE.style.opacity = 1;
|
||||
}, 300);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
window.__runBoot = (withError, additionalError) => {
|
||||
if (window.__APP_BOOT && !withError) {
|
||||
function runMainBoot(withError, additionalError)
|
||||
{
|
||||
if (window.__APP_BOOT && !withError)
|
||||
{
|
||||
window.__APP_BOOT(function (bV) {
|
||||
if (!bV) {
|
||||
window.__showError(additionalError);
|
||||
if (!bV)
|
||||
{
|
||||
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)
|
||||
else
|
||||
{
|
||||
const p = window.progressJs();
|
||||
window.rainloopProgressJs = p;
|
||||
showError(additionalError);
|
||||
}
|
||||
}
|
||||
|
||||
function runApp()
|
||||
{
|
||||
const appData = window.__rlah_data();
|
||||
|
||||
if (window.jsloader && progressJs && appData && appData.TemplatesLink && appData.LangLink &&
|
||||
appData.StaticLibJsLink && appData.StaticAppJsLink && appData.StaticEditorJsLink)
|
||||
{
|
||||
const p = progressJs;
|
||||
|
||||
p.setOptions({theme: 'rainloop'});
|
||||
p.start().set(5);
|
||||
|
||||
window.$LAB
|
||||
.script(function () {
|
||||
return [
|
||||
{src: BaseAppLibsScriptLink, type: 'text/javascript', charset: 'utf-8'}
|
||||
];
|
||||
})
|
||||
.wait(function () {
|
||||
const
|
||||
libs = window.jsloader(appData.StaticLibJsLink).then(() => {
|
||||
if (window.$)
|
||||
{
|
||||
if (!window.$('#rl-check').is(':visible'))
|
||||
{
|
||||
window.$('html').addClass('no-css');
|
||||
throw new Error('no-css');
|
||||
}
|
||||
|
||||
p.set(20);
|
||||
window.$('#rl-check').remove();
|
||||
|
||||
if (appData.IncludeBackground && $) {
|
||||
$('#rl-bg').attr('style', 'background-image: none !important;')
|
||||
if (appData.IncludeBackground)
|
||||
{
|
||||
window.$('#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})
|
||||
(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 () {
|
||||
}
|
||||
}),
|
||||
common = window.Promise.all([
|
||||
window.jsloader(appData.TemplatesLink),
|
||||
window.jsloader(appData.LangLink)
|
||||
])
|
||||
;
|
||||
|
||||
window.Promise.all([libs, common])
|
||||
.then(() => {
|
||||
p.set(30);
|
||||
})
|
||||
.script(function () {
|
||||
return {src: BaseAppMainScriptLink, type: 'text/javascript', charset: 'utf-8'};
|
||||
})
|
||||
.wait(function () {
|
||||
return window.jsloader(appData.StaticAppJsLink);
|
||||
}).then(() => {
|
||||
p.set(50);
|
||||
})
|
||||
.script(function () {
|
||||
return appData.PluginsLink ? {src: appData.PluginsLink, type: 'text/javascript', charset: 'utf-8'} : null;
|
||||
})
|
||||
.wait(function () {
|
||||
return appData.PluginsLink ? window.jsloader(appData.PluginsLink) : window.Promise.resolve();
|
||||
}).then(() => {
|
||||
p.set(70);
|
||||
window.__runBoot(false);
|
||||
})
|
||||
.script(function () {
|
||||
return {src: BaseAppEditorScriptLink, type: 'text/javascript', charset: 'utf-8'};
|
||||
})
|
||||
.wait(function () {
|
||||
runMainBoot(false);
|
||||
}).catch((e) => {
|
||||
runMainBoot(true);
|
||||
throw e;
|
||||
}).then(() => {
|
||||
return window.jsloader(appData.StaticEditorJsLink);
|
||||
}).then(() => {
|
||||
if (window.CKEDITOR && window.__initEditor) {
|
||||
window.__initEditor();
|
||||
window.__initEditor = null;
|
||||
|
@ -162,6 +213,41 @@ window.__runApp = (BaseAppLibsScriptLink, BaseAppMainScriptLink, BaseAppEditorSc
|
|||
}
|
||||
else
|
||||
{
|
||||
window.__runBoot(true);
|
||||
runMainBoot(true);
|
||||
}
|
||||
}
|
||||
|
||||
window.__initAppData = function(data) {
|
||||
|
||||
rlAppDataStorage = data;
|
||||
|
||||
window.__rlah_set();
|
||||
|
||||
if (rlAppDataStorage.NewThemeLink)
|
||||
{
|
||||
window.document.getElementById('app-theme-link').href = rlAppDataStorage.NewThemeLink;
|
||||
}
|
||||
|
||||
if (rlAppDataStorage.IncludeCss)
|
||||
{
|
||||
includeStyle(rlAppDataStorage.IncludeCss);
|
||||
}
|
||||
|
||||
showDescriptionAndLoading(rlAppDataStorage ? (rlAppDataStorage.LoadingDescriptionEsc || '') : '');
|
||||
|
||||
runApp();
|
||||
};
|
||||
|
||||
window.__runBoot = function() {
|
||||
|
||||
if (!window.navigator || !window.navigator.cookieEnabled)
|
||||
{
|
||||
window.document.location.replace('./?/NoCookie');
|
||||
}
|
||||
|
||||
if (includeLayout())
|
||||
{
|
||||
includeAppScr(getRainloopBootData());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
25
dev/Common/Loader.jsx
Normal file
25
dev/Common/Loader.jsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
import window from 'window';
|
||||
import {Promise} from 'es6-promise-polyfill/promise.js';
|
||||
|
||||
window.Promise = window.Promise || Promise;
|
||||
|
||||
export default (url) => {
|
||||
return new window.Promise((resolve, reject) => {
|
||||
|
||||
const element = document.createElement('script');
|
||||
|
||||
element.onload = () => {
|
||||
resolve(url);
|
||||
};
|
||||
|
||||
element.onerror = () => {
|
||||
reject(new Error(url));
|
||||
};
|
||||
|
||||
element.async = true;
|
||||
element.src = url;
|
||||
|
||||
document.body.appendChild(element);
|
||||
});
|
||||
};
|
|
@ -1419,7 +1419,7 @@
|
|||
aContent.push('' + sKey + '=' + sValue);
|
||||
});
|
||||
|
||||
$('#rl-head-viewport').attr('content', aContent.join(', '));
|
||||
$('#app-head-viewport').attr('content', aContent.join(', '));
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1538,8 +1538,8 @@
|
|||
Utils.changeTheme = function (sValue, themeTrigger)
|
||||
{
|
||||
var
|
||||
oThemeLink = $('#rlThemeLink'),
|
||||
oThemeStyle = $('#rlThemeStyle'),
|
||||
oThemeLink = $('#app-theme-link'),
|
||||
oThemeStyle = $('#app-theme-style'),
|
||||
sUrl = oThemeLink.attr('href')
|
||||
;
|
||||
|
||||
|
@ -1576,7 +1576,7 @@
|
|||
{
|
||||
if (oThemeLink && oThemeLink[0] && (!oThemeStyle || !oThemeStyle[0]))
|
||||
{
|
||||
oThemeStyle = $('<style id="rlThemeStyle"></style>');
|
||||
oThemeStyle = $('<style id="app-theme-style"></style>');
|
||||
oThemeLink.after(oThemeStyle);
|
||||
oThemeLink.remove();
|
||||
}
|
||||
|
|
24
dev/Html/Layout.html
Normal file
24
dev/Html/Layout.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
<div id="rl-bg" class="thm-body"></div>
|
||||
<div id="rl-loading" class="thm-loading" style="opacity:0">
|
||||
<div id="rl-loading-desc"></div>
|
||||
<div class="e-spinner">
|
||||
<div class="e-bounce bounce1"></div>
|
||||
<div class="e-bounce bounce2"></div>
|
||||
<div class="e-bounce bounce3"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rl-loading-error" class="thm-loading">
|
||||
An error occurred. <br /> Please refresh the page and try again.
|
||||
<div id="rl-loading-error-additional"></div>
|
||||
</div>
|
||||
<div id="rl-content">
|
||||
<div id="rl-popups"></div>
|
||||
<div id="rl-center">
|
||||
<div id="rl-top"></div>
|
||||
<div id="rl-left"></div>
|
||||
<div id="rl-right"></div>
|
||||
<div id="rl-bottom"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rl-templates"></div>
|
||||
<div id="rl-hidden"></div>
|
|
@ -32,7 +32,7 @@ class RainLoopStorage
|
|||
setHash() {
|
||||
const
|
||||
key = 'AuthAccountHash',
|
||||
appData = window.rainloopAppData
|
||||
appData = window.__rlah_data()
|
||||
;
|
||||
if (this.s)
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@ class SettingsStorage
|
|||
appSettings = {};
|
||||
|
||||
constructor() {
|
||||
this.settings = window.rainloopAppData || {};
|
||||
this.settings = window.__rlah_data() || {};
|
||||
this.settings = Utils.isNormal(this.settings) ? this.settings : {};
|
||||
|
||||
this.appSettings = this.settings.System || null;
|
||||
|
|
|
@ -349,7 +349,7 @@ html.rl-ctrl-key-pressed {
|
|||
#rl-loading, #rl-loading-error {
|
||||
position: absolute;
|
||||
font-size: 30px;
|
||||
line-height: 100%;
|
||||
line-height: 130%;
|
||||
top: 50%;
|
||||
width: 100%;
|
||||
height: 65px;
|
||||
|
@ -370,6 +370,14 @@ html.rl-ctrl-key-pressed {
|
|||
font-size: 20px;
|
||||
}
|
||||
|
||||
#rl-app{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#rl-check{
|
||||
display: block;
|
||||
}
|
||||
|
||||
html.rl-mobile .hide-on-mobile {
|
||||
display: none !important;
|
||||
}
|
||||
|
|
|
@ -28,10 +28,6 @@
|
|||
opacity: 0;
|
||||
}
|
||||
|
||||
#rl-check {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.opentip-container {
|
||||
|
||||
z-index: 2001 !important;
|
||||
|
|
25
dev/boot.jsx
25
dev/boot.jsx
|
@ -1,12 +1,27 @@
|
|||
|
||||
import window from 'window';
|
||||
import jsloader from 'Common/Loader';
|
||||
import {progressJs} from 'progress.js/src/progress.js';
|
||||
|
||||
window.jsloader = jsloader;
|
||||
window.progressJs = window.progressJs || progressJs();
|
||||
|
||||
window.progressJs.onbeforeend(() => {
|
||||
if (window.$)
|
||||
{
|
||||
window.$('.progressjs-container').hide();
|
||||
window.setTimeout(() => {
|
||||
window.$('.progressjs-container').remove();
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
|
||||
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;
|
||||
if (window.__runBoot)
|
||||
{
|
||||
window.__runBoot();
|
||||
}
|
||||
|
|
|
@ -48,17 +48,10 @@ export default (App) => {
|
|||
window['rl']['EmailModel'] = EmailModel;
|
||||
window['rl']['Enums'] = Enums;
|
||||
|
||||
window['__APP_BOOT'] = function (fCall) {
|
||||
window.__APP_BOOT = function (fCall) {
|
||||
|
||||
$(_.delay(function () {
|
||||
|
||||
if (!$('#rl-check').is(':visible'))
|
||||
{
|
||||
Globals.$html.addClass('no-css');
|
||||
}
|
||||
|
||||
$('#rl-check').remove();
|
||||
|
||||
if (window['rainloopTEMPLATES'] && window['rainloopTEMPLATES'][0])
|
||||
{
|
||||
$('#rl-templates').html(window['rainloopTEMPLATES'][0]);
|
||||
|
@ -79,7 +72,7 @@ export default (App) => {
|
|||
fCall(false);
|
||||
}
|
||||
|
||||
window['__APP_BOOT'] = null;
|
||||
window.__APP_BOOT = null;
|
||||
|
||||
}, 10));
|
||||
};
|
||||
|
|
|
@ -97,7 +97,7 @@ function copyFile(sFile, sNewFile, callback)
|
|||
callback();
|
||||
}
|
||||
|
||||
cfg.paths.globjs = 'dev/**/*.{js,jsx}';
|
||||
cfg.paths.globjs = 'dev/**/*.{js,jsx,html}';
|
||||
cfg.paths.globjsonly = 'dev/**/*.js';
|
||||
cfg.paths.globjsxonly = 'dev/**/*.jsx';
|
||||
cfg.paths.static = 'rainloop/v/' + cfg.devVersion + '/static/';
|
||||
|
@ -260,7 +260,6 @@ gulp.task('package:community-off', function() {
|
|||
});
|
||||
|
||||
gulp.task('css:clear-less', ['css:main-begin'], function() {
|
||||
|
||||
return gulp.src(cfg.paths.staticCSS + cfg.paths.less.main.name, {read: false})
|
||||
.pipe(require('gulp-rimraf')());
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "RainLoop",
|
||||
"title": "RainLoop Webmail",
|
||||
"version": "1.10.0",
|
||||
"release": "108",
|
||||
"release": "112",
|
||||
"ownCloudPackageVersion": "4.16",
|
||||
"description": "Simple, modern & fast web-based email client",
|
||||
"homepage": "http://rainloop.net",
|
||||
|
@ -84,6 +84,7 @@
|
|||
"lodash": "~3.9.3",
|
||||
"node-fs": "*",
|
||||
"node-notifier": "~4.2.3",
|
||||
"raw-loader": "^0.5.1",
|
||||
"rimraf": "*",
|
||||
"webpack": "*"
|
||||
}
|
||||
|
|
8
phpunit.xml
Normal file
8
phpunit.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit colors="true" stopOnFailure="true" syntaxCheck="true" bootstrap="tests/bootstrap.php">
|
||||
<testsuites>
|
||||
<testsuite name="RainLoop Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
|
@ -1905,11 +1905,6 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack
|
|||
}
|
||||
}
|
||||
|
||||
$sStaticCache = \md5(APP_VERSION.$this->Plugins()->Hash());
|
||||
|
||||
$sTheme = $this->ValidateTheme($sTheme, $bMobile);
|
||||
$sNewThemeLink = './?/Css/0/'.($bAdmin ? 'Admin' : 'User').'/-/'.$sTheme.'/-/'.$sStaticCache.'/Hash/-/';
|
||||
|
||||
if (!$aResult['Auth'])
|
||||
{
|
||||
if (!$bAdmin)
|
||||
|
@ -1923,14 +1918,11 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack
|
|||
}
|
||||
}
|
||||
|
||||
$sPluginsLink = '';
|
||||
if (0 < $this->Plugins()->Count() && $this->Plugins()->HaveJs($bAdmin))
|
||||
{
|
||||
$sPluginsLink = './?/Plugins/0/'.($bAdmin ? 'Admin' : 'User').'/'.$sStaticCache.'/';
|
||||
}
|
||||
$sTheme = $this->ValidateTheme($sTheme, $bMobile);
|
||||
$sStaticCache = $this->StaticCache();
|
||||
|
||||
$aResult['Theme'] = $sTheme;
|
||||
$aResult['NewThemeLink'] = $sNewThemeLink;
|
||||
$aResult['NewThemeLink'] = $this->ThemeLink($sTheme, $bAdmin);
|
||||
|
||||
$aResult['Language'] = $this->ValidateLanguage($sLanguage, '', false);
|
||||
$aResult['LanguageAdmin'] = $this->ValidateLanguage($sLanguageAdmin, '', true);
|
||||
|
@ -1940,11 +1932,23 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack
|
|||
$aResult['UserLanguage'] = $this->ValidateLanguage($aResult['UserLanguageRaw'], '', false, true);
|
||||
$aResult['UserLanguageAdmin'] = $this->ValidateLanguage($aResult['UserLanguageRaw'], '', true, true);
|
||||
|
||||
$aResult['PluginsLink'] = '';
|
||||
if (0 < $this->Plugins()->Count() && $this->Plugins()->HaveJs($bAdmin))
|
||||
{
|
||||
$aResult['PluginsLink'] = './?/Plugins/0/'.($bAdmin ? 'Admin' : 'User').'/'.$sStaticCache.'/';
|
||||
}
|
||||
|
||||
$aResult['LangLink'] = './?/Lang/0/'.($bAdmin ? 'Admin' : 'App').'/'.
|
||||
($bAdmin ? $aResult['LanguageAdmin'] : $aResult['Language']).'/'.$sStaticCache.'/';
|
||||
|
||||
$aResult['TemplatesLink'] = './?/Templates/0/'.($bAdmin ? 'Admin' : 'App').'/'.$sStaticCache.'/';
|
||||
$aResult['PluginsLink'] = $sPluginsLink;
|
||||
|
||||
$bAppJsDebug = !!$this->Config()->Get('labs', 'use_app_debug_js', false);
|
||||
|
||||
$aResult['StaticLibJsLink'] = $this->StaticPath('js/min/libs.js');
|
||||
$aResult['StaticAppJsLink'] = $this->StaticPath('js/'.($bAppJsDebug ? '' : 'min/').($bAdmin ? 'admin' : 'app').'.js');
|
||||
$aResult['StaticEditorJsLink'] = $this->StaticPath('ckeditor/ckeditor.js');
|
||||
|
||||
$aResult['EditorDefaultType'] = \in_array($aResult['EditorDefaultType'], array('Plain', 'Html', 'HtmlForced', 'PlainForced')) ?
|
||||
$aResult['EditorDefaultType'] : 'Plain';
|
||||
|
||||
|
@ -9057,6 +9061,29 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack
|
|||
return $mResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function StaticCache()
|
||||
{
|
||||
static $sCache = null;
|
||||
if (!$sCache)
|
||||
{
|
||||
$sCache = \md5(APP_VERSION.$this->Plugins()->Hash());
|
||||
}
|
||||
return $sCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTheme
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function ThemeLink($sTheme, $bAdmin)
|
||||
{
|
||||
return './?/Css/0/'.($bAdmin ? 'Admin' : 'User').'/-/'.$sTheme.'/-/'.$this->StaticCache().'/Hash/-/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTheme
|
||||
*
|
||||
|
@ -9694,6 +9721,18 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack
|
|||
return isset($aLang[$sKey]) ? $aLang[$sKey] : $sKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPath
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function StaticPath($sPath)
|
||||
{
|
||||
$sResult = \RainLoop\Utils::WebStaticPath().$sPath;
|
||||
return $sResult.(false === \strpos($sResult, '?') ? '?' : '&').
|
||||
($this->IsOpen() ? 'community' : 'standard');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MailSo\Cache\CacheClient|null
|
||||
*/
|
||||
|
|
|
@ -241,7 +241,7 @@ class Service
|
|||
$sResult .= '][owncloud:true';
|
||||
}
|
||||
|
||||
$sResult .= '] //-->';
|
||||
$sResult .= ']-->';
|
||||
}
|
||||
|
||||
// Output result
|
||||
|
@ -259,9 +259,7 @@ class Service
|
|||
*/
|
||||
private function staticPath($sPath)
|
||||
{
|
||||
$sResult = \RainLoop\Utils::WebStaticPath().$sPath;
|
||||
return $sResult.(false === \strpos($sResult, '?') ? '?' : '&').
|
||||
($this->oActions->IsOpen() ? 'v=community' : 'v=standard');
|
||||
return $this->oActions->StaticPath($sPath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -283,42 +281,27 @@ class Service
|
|||
|
||||
$sFaviconUrl = (string) $this->oActions->Config()->Get('webmail', 'favicon_url', '');
|
||||
|
||||
$aData = array(
|
||||
'Language' => $sLanguage,
|
||||
'Theme' => $sTheme,
|
||||
'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')
|
||||
);
|
||||
|
||||
$aAdd = array();
|
||||
$aAdd[] = $bMobile ? 'mobile' : 'no-mobile';
|
||||
$aAdd[] = $bMobileDevice ? '1' : '0';
|
||||
$sFaviconPngLink = $sFaviconUrl ? $sFaviconUrl : $this->staticPath('apple-touch-icon.png');
|
||||
$sAppleTouchLink = $sFaviconUrl ? '' : $this->staticPath('apple-touch-icon.png');
|
||||
|
||||
$aTemplateParameters = array(
|
||||
'{{BaseAppDataScriptLink}}' => ($bAdmin ? './?/AdminAppData' : './?/AppData').(0 < \count($aAdd) ? '@'.\implode('-', $aAdd) : '').'/',
|
||||
'{{BaseAppFaviconPngLinkTag}}' => $aData['FaviconPngLink'] ? '<link rel="shortcut icon" href="'.$aData['FaviconPngLink'].'" type="image/png" />' : '',
|
||||
'{{BaseAppFaviconTouchLinkTag}}' => $aData['AppleTouchLink'] ? '<link rel="apple-touch-icon" href="'.$aData['AppleTouchLink'].'" type="image/png" />' : '',
|
||||
'{{BaseAppAppleTouchFile}}' => $aData['AppleTouchLink'],
|
||||
'{{BaseAppMainCssLink}}' => $aData['AppCssLink'],
|
||||
'{{BaseAppBootScriptLink}}' => $aData['BootJsLink'],
|
||||
'{{BaseAppLibsScriptLink}}' => $aData['LibJsLink'],
|
||||
'{{BaseAppEditorScriptLink}}' => $aData['EditorJsLink'],
|
||||
'{{BaseAppOpenPgpScriptLink}}' => $aData['OpenPgpJsLink'],
|
||||
'{{BaseAppMainCommonScriptLink}}' => $aData['AppJsCommonLink'],
|
||||
'{{BaseAppMainScriptLink}}' => $aData['AppJsLink'],
|
||||
'{{BaseVersion}}' => APP_VERSION,
|
||||
'{{BaseAppFaviconPngLinkTag}}' => $sFaviconPngLink ? '<link type="image/png" rel="shortcut icon" href="'.$sFaviconPngLink.'" />' : '',
|
||||
'{{BaseAppFaviconTouchLinkTag}}' => $sAppleTouchLink ? '<link type="image/png" rel="apple-touch-icon" href="'.$sAppleTouchLink.'" />' : '',
|
||||
'{{BaseAppMainCssLink}}' => $this->staticPath('css/app'.($bAppCssDebug ? '' : '.min').'.css'),
|
||||
'{{BaseAppThemeCssLink}}' => $this->oActions->ThemeLink($sTheme, $bAdmin),
|
||||
'{{BaseAppBootScriptLink}}' => $this->staticPath('js/'.($bAppJsDebug ? '' : 'min/').'boot.js'),
|
||||
'{{BaseViewport}}' => $bMobile ? 'width=device-width,initial-scale=1,user-scalable=no' : 'width=950,maximum-scale=2',
|
||||
'{{BaseDir}}' => 'ltr'
|
||||
// '{{BaseDir}}' => \in_array($aData['Language'], array('ar', 'he', 'ur')) ? 'rtl' : 'ltr'
|
||||
'{{BaseDir}}' => false && \in_array($sLanguage, array('ar', 'he', 'ur')) ? 'rtl' : 'ltr'
|
||||
);
|
||||
|
||||
$aTemplateParameters['{{RainloopBootData}}'] = \json_encode(array(
|
||||
'admin' => $bAdmin,
|
||||
'language' => $sLanguage,
|
||||
'theme' => $sTheme,
|
||||
'mobile' => $bMobile,
|
||||
'mobileDevice' => $bMobileDevice
|
||||
));
|
||||
|
||||
$aTemplateParameters['{{BaseHash}}'] = \md5(
|
||||
\implode('~', array(
|
||||
$bAdmin ? '1' : '0',
|
||||
|
|
|
@ -1369,9 +1369,8 @@ class ServiceActions
|
|||
private function compileAppData($aAppData, $bWrapByScriptTag = true)
|
||||
{
|
||||
return
|
||||
($bWrapByScriptTag ? '<script data-cfasync="false">' : '').
|
||||
'window.rainloopAppData='.\json_encode($aAppData).';'.
|
||||
'if(window.__rlah_set){__rlah_set()};'.
|
||||
($bWrapByScriptTag ? '<script type="text/javascript" data-cfasync="false">' : '').
|
||||
'if(window.__initAppData){window.__initAppData('.\json_encode($aAppData).');}'.
|
||||
($bWrapByScriptTag ? '</script>' : '')
|
||||
;
|
||||
}
|
||||
|
|
|
@ -475,12 +475,13 @@ class Utils
|
|||
public static function ClearHtmlOutput($sHtml)
|
||||
{
|
||||
// return $sHtml;
|
||||
return \str_replace('> <', '><',
|
||||
return \trim(\str_replace('> <', '><',
|
||||
\str_replace('" />', '"/>',
|
||||
\preg_replace('/[\s]+ /i', ' ',
|
||||
\preg_replace('/ [\s]+/i', ' ',
|
||||
\preg_replace('/[\r\n\t]+/', ' ',
|
||||
$sHtml
|
||||
))));
|
||||
))))));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,74 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="no-js rl-booted-trigger rl-started-trigger" dir="{{BaseDir}}">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta id="rl-head-viewport" name="viewport" content="{{BaseViewport}}">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<noscript>
|
||||
<meta http-equiv="refresh" content="0; URL=./?/NoScript" />
|
||||
</noscript>
|
||||
<!--[if lte IE 8]>
|
||||
<meta http-equiv="refresh" content="0; URL=./?/BadBrowser" />
|
||||
<![endif]-->
|
||||
<script type="text/javascript" data-cfasync="false">
|
||||
if (!window.navigator || !window.navigator.cookieEnabled) {
|
||||
window.document.location.replace('./?/NoCookie');
|
||||
}
|
||||
</script>
|
||||
<meta name="Author" content="RainLoop Team" />
|
||||
<meta name="robots" content="noindex,nofollow,noodp" />
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="viewport" content="{{BaseViewport}}" id="app-head-viewport">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="google" content="notranslate" />
|
||||
<meta name="robots" content="noindex,nofollow,noodp" />
|
||||
<meta name="AppBootData" content='{{RainloopBootData}}' id="app-boot-data" />
|
||||
<title></title>
|
||||
<style>#rl-content{display:none;}#rl-check{display:none;}</style>
|
||||
{{BaseAppFaviconPngLinkTag}}{{BaseAppFaviconTouchLinkTag}}
|
||||
{{BaseAppFaviconPngLinkTag}}
|
||||
{{BaseAppFaviconTouchLinkTag}}
|
||||
<style>#rl-check{display:none}</style>
|
||||
<link type="text/css" rel="stylesheet" href="{{BaseAppMainCssLink}}" />
|
||||
<link type="text/css" rel="stylesheet" id="rlThemeLink" />
|
||||
<script type="text/javascript" data-cfasync="false" src="{{BaseAppBootScriptLink}}"></script>
|
||||
<script type="text/javascript" data-cfasync="false">
|
||||
window.__includeAppScr('{{BaseAppDataScriptLink}}');
|
||||
</script>
|
||||
<script type="text/javascript" data-cfasync="false">
|
||||
if (window.rainloopAppData && window.rainloopAppData['NewThemeLink']) {
|
||||
window.document.getElementById('rlThemeLink').href = window.rainloopAppData['NewThemeLink'];
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" data-cfasync="false">
|
||||
if (window.rainloopAppData && window.rainloopAppData['IncludeCss']) {
|
||||
window.__includeStyle(window.rainloopAppData['IncludeCss']);
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript" data-cfasync="false"></script>
|
||||
<link type="text/css" rel="stylesheet" href="{{BaseAppThemeCssLink}}" id="app-theme-link" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="rl-app"></div>
|
||||
<div id="rl-check"></div>
|
||||
<div id="rl-bg" class="thm-body"></div>
|
||||
<div id="rl-loading" class="thm-loading">
|
||||
<div id="rl-loading-desc">Loading</div>
|
||||
<div class="e-spinner">
|
||||
<div class="e-bounce bounce1"></div>
|
||||
<div class="e-bounce bounce2"></div>
|
||||
<div class="e-bounce bounce3"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rl-loading-error" class="thm-loading">
|
||||
An Error occurred,
|
||||
<br />
|
||||
please refresh the page and try again.
|
||||
<div id="rl-loading-error-additional"></div>
|
||||
</div>
|
||||
<div id="rl-content">
|
||||
<div id="rl-popups"></div>
|
||||
<div id="rl-center">
|
||||
<div id="rl-top"></div>
|
||||
<div id="rl-left"></div>
|
||||
<div id="rl-right"></div>
|
||||
<div id="rl-bottom"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rl-templates"></div>
|
||||
<div id="rl-hidden"></div>
|
||||
<script type="text/javascript" data-cfasync="false">__showDescription(window.rainloopAppData ? window.rainloopAppData['LoadingDescriptionEsc'] : '');</script>
|
||||
<script type="text/javascript" data-cfasync="false">__runApp('{{BaseAppLibsScriptLink}}', '{{BaseAppMainScriptLink}}', '{{BaseAppEditorScriptLink}}');</script>
|
||||
<script type="text/javascript" data-cfasync="false" src="{{BaseAppBootScriptLink}}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -187,9 +187,39 @@
|
|||
.thm-rgba-background-color(@message-background-color, @message-rgba-background-color);
|
||||
}
|
||||
|
||||
#rl-app{
|
||||
display: block;
|
||||
}
|
||||
|
||||
html.no-css {
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: Arial, Verdana, Geneva, sans-serif;
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#rl-loading, #rl-loading-error {
|
||||
position: absolute;
|
||||
font-size: 30px;
|
||||
line-height: 130%;
|
||||
top: 50%;
|
||||
width: 100%;
|
||||
height: 65px;
|
||||
margin: 0;
|
||||
margin-top: -60px;
|
||||
background-color: transparent;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.progressjs-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.thm-body {
|
||||
color: #333;
|
||||
background-color: #aaa;
|
||||
|
|
|
@ -3,13 +3,12 @@
|
|||
<div class="btn-toolbar">
|
||||
<div class="btn-group btn-group-last pull-right dropdown colored-toggle" data-bind="registrateBootstrapDropdown: true, openDropdownTrigger: accountMenuDropdownTrigger">
|
||||
<a id="top-system-dropdown-id" href="#" tabindex="-1" class="btn single btn-ellipsis btn-block dropdown-toggle system-dropdown" data-toggle="dropdown">
|
||||
<i data-bind="css: {'icon-user': !accounts.loading(), 'icon-spinner animated': accounts.loading()}"
|
||||
></i>
|
||||
<i data-bind="css: {'icon-user': !accounts.loading(), 'icon-spinner animated': accounts.loading()}"></i>
|
||||
<!--
|
||||
<b data-bind="text: accountsUnreadCount, visible: 100 > accountsUnreadCount() && 0 < accountsUnreadCount()"></b>
|
||||
<b data-bind="visible: 99 < accountsUnreadCount()">99+</b>
|
||||
-->
|
||||
|
||||
-->
|
||||
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
module.exports = {
|
||||
url: 'https://mail.rainloop.net/',
|
||||
testLogin: 'demo@rainloop.test',
|
||||
testPassword: '12345'
|
||||
};
|
1
tests/bootstrap.php
Normal file
1
tests/bootstrap.php
Normal file
|
@ -0,0 +1 @@
|
|||
<?php
|
|
@ -1,70 +0,0 @@
|
|||
|
||||
var cfg = require('./_config.js');
|
||||
|
||||
casper.start(cfg.url);
|
||||
|
||||
casper.then(function() {
|
||||
this.echo('testing: ' + cfg.url);
|
||||
}).wait(100);
|
||||
|
||||
casper.then(function() {
|
||||
|
||||
casper.test.begin('Login page should contains "Sign In" button', 1, function (test) {
|
||||
|
||||
casper.then(function() {
|
||||
test.assertExists('button.buttonLogin');
|
||||
});
|
||||
|
||||
casper.then(function() {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin('Login page should allow langs selection', 3, function (test) {
|
||||
|
||||
casper.then(function() {
|
||||
test.assertExists('.e-languages .flag-selector .flag-name');
|
||||
});
|
||||
|
||||
casper.then(function() {
|
||||
this.click('.e-languages .flag-selector .flag-name');
|
||||
}).wait(300);
|
||||
|
||||
casper.then(function() {
|
||||
test.assertExists('.b-languages-content');
|
||||
});
|
||||
|
||||
casper.then(function() {
|
||||
this.click('.b-languages-content .lang-item .flag.flag-ru_ru');
|
||||
}).wait(1000);
|
||||
|
||||
casper.then(function() {
|
||||
test.assertEquals('Войти', this.fetchText('button.buttonLogin'));
|
||||
});
|
||||
|
||||
casper.then(function() {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
casper.test.begin('Login page submit', 1, function (test) {
|
||||
|
||||
casper.then(function() {
|
||||
this.fill('form.loginForm', {
|
||||
'RainLoopEmail': cfg.testLogin,
|
||||
'RainLoopPassword': cfg.testPassword
|
||||
}, true);
|
||||
}).wait(3000);
|
||||
|
||||
casper.then(function() {
|
||||
test.assertEquals(cfg.testLogin, this.fetchText('.accountPlace'));
|
||||
});
|
||||
|
||||
casper.then(function() {
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
casper.run();
|
2
vendors/es6-promise-polyfill/.gitignore
vendored
Normal file
2
vendors/es6-promise-polyfill/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/node_modules
|
||||
/tmp
|
3
vendors/es6-promise-polyfill/.npmignore
vendored
Normal file
3
vendors/es6-promise-polyfill/.npmignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/node_modules/
|
||||
/tmp
|
||||
/test
|
6
vendors/es6-promise-polyfill/.travis.yml
vendored
Normal file
6
vendors/es6-promise-polyfill/.travis.yml
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- "0.12"
|
||||
- "node"
|
||||
- "iojs"
|
18
vendors/es6-promise-polyfill/CHANGELOG.md
vendored
Normal file
18
vendors/es6-promise-polyfill/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
## 1.2.0 (December 8, 2015)
|
||||
|
||||
- Support for IE8 and below
|
||||
- Promises/A+ tests added
|
||||
|
||||
## 1.1.0 (October 16, 2015)
|
||||
|
||||
- Change way to get reference to `global`, since `Function()()` may be prohibited
|
||||
- Add AMD support
|
||||
|
||||
## 1.0.1 (September 14, 2015)
|
||||
|
||||
- Fix exports - use polyfill only if native implementation isn't supported
|
||||
- Add license
|
||||
|
||||
## 1.0.0 (June 19, 2014)
|
||||
|
||||
- Init release
|
|
@ -1,4 +1,6 @@
|
|||
Copyright 2015 RainLoop Team
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014 Roman Dvornov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
88
vendors/es6-promise-polyfill/README.md
vendored
Normal file
88
vendors/es6-promise-polyfill/README.md
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
[![NPM version](https://img.shields.io/npm/v/es6-promise-polyfill.svg)](https://www.npmjs.com/package/es6-promise-polyfill)
|
||||
[![Build Status](https://travis-ci.org/lahmatiy/es6-promise-polyfill.svg?branch=master)](https://travis-ci.org/lahmatiy/es6-promise-polyfill)
|
||||
|
||||
# ES6 Promise polyfill
|
||||
|
||||
This is a polyfill of [ES6 Promise](https://github.com/domenic/promises-unwrapping). The implementation based on [Jake Archibald implementation](https://github.com/jakearchibald/es6-promise) a subset of [rsvp.js](https://github.com/tildeio/rsvp.js). If you're wanting extra features and more debugging options, check out the [full library](https://github.com/tildeio/rsvp.js).
|
||||
|
||||
For API details and how to use promises, see the <a href="http://www.html5rocks.com/en/tutorials/es6/promises/">JavaScript Promises HTML5Rocks article</a>.
|
||||
|
||||
## Notes
|
||||
|
||||
The main target: implementation should be conformance with browser's implementations and to be minimal as possible in size. So it's strictly polyfill of ES6 Promise specification and nothing more.
|
||||
|
||||
It passes both [Promises/A+ test suite](https://github.com/promises-aplus/promises-tests) and [rsvp.js test suite](https://github.com/jakearchibald/es6-promise/tree/master/test). And as small as 2,6KB min (or 1KB min+gzip).
|
||||
|
||||
The polyfill uses `setImmediate` if available, or fallback to use `setTimeout`. Use [setImmediate polyfill](https://github.com/YuzuJS/setImmediate) by @YuzuJS to reach better performance.
|
||||
|
||||
## How to use
|
||||
|
||||
### Browser
|
||||
|
||||
To install:
|
||||
|
||||
```sh
|
||||
bower install es6-promise-polyfill
|
||||
```
|
||||
|
||||
To use:
|
||||
|
||||
```html
|
||||
<script src="bower_components/es6-promise-polyfill/promise.min.js"></script>
|
||||
<script>
|
||||
var promise = new Promise(...);
|
||||
</script>
|
||||
```
|
||||
|
||||
### Node.js
|
||||
|
||||
To install:
|
||||
|
||||
```sh
|
||||
npm install es6-promise-polyfill
|
||||
```
|
||||
|
||||
To use:
|
||||
|
||||
```js
|
||||
var Promise = require('es6-promise-polyfill').Promise;
|
||||
var promise = new Promise(...);
|
||||
```
|
||||
|
||||
### AMD
|
||||
|
||||
To install:
|
||||
|
||||
```sh
|
||||
npm install es6-promise-polyfill
|
||||
```
|
||||
|
||||
To use:
|
||||
|
||||
```js
|
||||
define(['es6-promise-polyfill'], function(Promise) {
|
||||
var promise = new Promise(...);
|
||||
});
|
||||
```
|
||||
|
||||
## Usage in IE<9
|
||||
|
||||
`catch` is a reserved word in IE<9, meaning `promise.catch(func)` throws a syntax error. To work around this, use a string to access the property:
|
||||
|
||||
```js
|
||||
promise['catch'](function(err) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Or use `.then` instead:
|
||||
|
||||
```js
|
||||
promise.then(undefined, function(err) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the MIT License.
|
11
vendors/es6-promise-polyfill/bower.json
vendored
Normal file
11
vendors/es6-promise-polyfill/bower.json
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "es6-promise-polyfill",
|
||||
"version": "1.1.1",
|
||||
"main": "promise.js",
|
||||
"ignore": [
|
||||
".*",
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"test"
|
||||
]
|
||||
}
|
27
vendors/es6-promise-polyfill/package.json
vendored
Normal file
27
vendors/es6-promise-polyfill/package.json
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "es6-promise-polyfill",
|
||||
"description": "Polyfill for ES6 Promise",
|
||||
"version": "1.2.0",
|
||||
"author": "Roman Dvornov <rdvornov@gmail.com>",
|
||||
"license": "MIT",
|
||||
"repository": "lahmatiy/es6-promise-polyfill",
|
||||
"bugs": {
|
||||
"url": "https://github.com/lahmatiy/es6-promise-polyfill/issues"
|
||||
},
|
||||
"main": "promise.js",
|
||||
"dependencies": {
|
||||
},
|
||||
"devDependencies": {
|
||||
"promises-aplus-tests": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "promises-aplus-tests test/test-adapter"
|
||||
},
|
||||
"keywords": [
|
||||
"es6",
|
||||
"es2015",
|
||||
"polyfill",
|
||||
"promise",
|
||||
"promises"
|
||||
]
|
||||
}
|
346
vendors/es6-promise-polyfill/promise.js
vendored
Normal file
346
vendors/es6-promise-polyfill/promise.js
vendored
Normal file
|
@ -0,0 +1,346 @@
|
|||
(function(global){
|
||||
|
||||
//
|
||||
// Check for native Promise and it has correct interface
|
||||
//
|
||||
|
||||
var NativePromise = global['Promise'];
|
||||
var nativePromiseSupported =
|
||||
NativePromise &&
|
||||
// Some of these methods are missing from
|
||||
// Firefox/Chrome experimental implementations
|
||||
'resolve' in NativePromise &&
|
||||
'reject' in NativePromise &&
|
||||
'all' in NativePromise &&
|
||||
'race' in NativePromise &&
|
||||
// Older version of the spec had a resolver object
|
||||
// as the arg rather than a function
|
||||
(function(){
|
||||
var resolve;
|
||||
new NativePromise(function(r){ resolve = r; });
|
||||
return typeof resolve === 'function';
|
||||
})();
|
||||
|
||||
|
||||
//
|
||||
// export if necessary
|
||||
//
|
||||
|
||||
if (typeof exports !== 'undefined' && exports)
|
||||
{
|
||||
// node.js
|
||||
exports.Promise = nativePromiseSupported ? NativePromise : Promise;
|
||||
exports.Polyfill = Promise;
|
||||
}
|
||||
else
|
||||
{
|
||||
// AMD
|
||||
if (typeof define == 'function' && define.amd)
|
||||
{
|
||||
define(function(){
|
||||
return nativePromiseSupported ? NativePromise : Promise;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// in browser add to global
|
||||
if (!nativePromiseSupported)
|
||||
global['Promise'] = Promise;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Polyfill
|
||||
//
|
||||
|
||||
var PENDING = 'pending';
|
||||
var SEALED = 'sealed';
|
||||
var FULFILLED = 'fulfilled';
|
||||
var REJECTED = 'rejected';
|
||||
var NOOP = function(){};
|
||||
|
||||
function isArray(value) {
|
||||
return Object.prototype.toString.call(value) === '[object Array]';
|
||||
}
|
||||
|
||||
// async calls
|
||||
var asyncSetTimer = typeof setImmediate !== 'undefined' ? setImmediate : setTimeout;
|
||||
var asyncQueue = [];
|
||||
var asyncTimer;
|
||||
|
||||
function asyncFlush(){
|
||||
// run promise callbacks
|
||||
for (var i = 0; i < asyncQueue.length; i++)
|
||||
asyncQueue[i][0](asyncQueue[i][1]);
|
||||
|
||||
// reset async asyncQueue
|
||||
asyncQueue = [];
|
||||
asyncTimer = false;
|
||||
}
|
||||
|
||||
function asyncCall(callback, arg){
|
||||
asyncQueue.push([callback, arg]);
|
||||
|
||||
if (!asyncTimer)
|
||||
{
|
||||
asyncTimer = true;
|
||||
asyncSetTimer(asyncFlush, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function invokeResolver(resolver, promise) {
|
||||
function resolvePromise(value) {
|
||||
resolve(promise, value);
|
||||
}
|
||||
|
||||
function rejectPromise(reason) {
|
||||
reject(promise, reason);
|
||||
}
|
||||
|
||||
try {
|
||||
resolver(resolvePromise, rejectPromise);
|
||||
} catch(e) {
|
||||
rejectPromise(e);
|
||||
}
|
||||
}
|
||||
|
||||
function invokeCallback(subscriber){
|
||||
var owner = subscriber.owner;
|
||||
var settled = owner.state_;
|
||||
var value = owner.data_;
|
||||
var callback = subscriber[settled];
|
||||
var promise = subscriber.then;
|
||||
|
||||
if (typeof callback === 'function')
|
||||
{
|
||||
settled = FULFILLED;
|
||||
try {
|
||||
value = callback(value);
|
||||
} catch(e) {
|
||||
reject(promise, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!handleThenable(promise, value))
|
||||
{
|
||||
if (settled === FULFILLED)
|
||||
resolve(promise, value);
|
||||
|
||||
if (settled === REJECTED)
|
||||
reject(promise, value);
|
||||
}
|
||||
}
|
||||
|
||||
function handleThenable(promise, value) {
|
||||
var resolved;
|
||||
|
||||
try {
|
||||
if (promise === value)
|
||||
throw new TypeError('A promises callback cannot return that same promise.');
|
||||
|
||||
if (value && (typeof value === 'function' || typeof value === 'object'))
|
||||
{
|
||||
var then = value.then; // then should be retrived only once
|
||||
|
||||
if (typeof then === 'function')
|
||||
{
|
||||
then.call(value, function(val){
|
||||
if (!resolved)
|
||||
{
|
||||
resolved = true;
|
||||
|
||||
if (value !== val)
|
||||
resolve(promise, val);
|
||||
else
|
||||
fulfill(promise, val);
|
||||
}
|
||||
}, function(reason){
|
||||
if (!resolved)
|
||||
{
|
||||
resolved = true;
|
||||
|
||||
reject(promise, reason);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (!resolved)
|
||||
reject(promise, e);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function resolve(promise, value){
|
||||
if (promise === value || !handleThenable(promise, value))
|
||||
fulfill(promise, value);
|
||||
}
|
||||
|
||||
function fulfill(promise, value){
|
||||
if (promise.state_ === PENDING)
|
||||
{
|
||||
promise.state_ = SEALED;
|
||||
promise.data_ = value;
|
||||
|
||||
asyncCall(publishFulfillment, promise);
|
||||
}
|
||||
}
|
||||
|
||||
function reject(promise, reason){
|
||||
if (promise.state_ === PENDING)
|
||||
{
|
||||
promise.state_ = SEALED;
|
||||
promise.data_ = reason;
|
||||
|
||||
asyncCall(publishRejection, promise);
|
||||
}
|
||||
}
|
||||
|
||||
function publish(promise) {
|
||||
var callbacks = promise.then_;
|
||||
promise.then_ = undefined;
|
||||
|
||||
for (var i = 0; i < callbacks.length; i++) {
|
||||
invokeCallback(callbacks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function publishFulfillment(promise){
|
||||
promise.state_ = FULFILLED;
|
||||
publish(promise);
|
||||
}
|
||||
|
||||
function publishRejection(promise){
|
||||
promise.state_ = REJECTED;
|
||||
publish(promise);
|
||||
}
|
||||
|
||||
/**
|
||||
* @class
|
||||
*/
|
||||
function Promise(resolver){
|
||||
if (typeof resolver !== 'function')
|
||||
throw new TypeError('Promise constructor takes a function argument');
|
||||
|
||||
if (this instanceof Promise === false)
|
||||
throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.');
|
||||
|
||||
this.then_ = [];
|
||||
|
||||
invokeResolver(resolver, this);
|
||||
}
|
||||
|
||||
Promise.prototype = {
|
||||
constructor: Promise,
|
||||
|
||||
state_: PENDING,
|
||||
then_: null,
|
||||
data_: undefined,
|
||||
|
||||
then: function(onFulfillment, onRejection){
|
||||
var subscriber = {
|
||||
owner: this,
|
||||
then: new this.constructor(NOOP),
|
||||
fulfilled: onFulfillment,
|
||||
rejected: onRejection
|
||||
};
|
||||
|
||||
if (this.state_ === FULFILLED || this.state_ === REJECTED)
|
||||
{
|
||||
// already resolved, call callback async
|
||||
asyncCall(invokeCallback, subscriber);
|
||||
}
|
||||
else
|
||||
{
|
||||
// subscribe
|
||||
this.then_.push(subscriber);
|
||||
}
|
||||
|
||||
return subscriber.then;
|
||||
},
|
||||
|
||||
'catch': function(onRejection) {
|
||||
return this.then(null, onRejection);
|
||||
}
|
||||
};
|
||||
|
||||
Promise.all = function(promises){
|
||||
var Class = this;
|
||||
|
||||
if (!isArray(promises))
|
||||
throw new TypeError('You must pass an array to Promise.all().');
|
||||
|
||||
return new Class(function(resolve, reject){
|
||||
var results = [];
|
||||
var remaining = 0;
|
||||
|
||||
function resolver(index){
|
||||
remaining++;
|
||||
return function(value){
|
||||
results[index] = value;
|
||||
if (!--remaining)
|
||||
resolve(results);
|
||||
};
|
||||
}
|
||||
|
||||
for (var i = 0, promise; i < promises.length; i++)
|
||||
{
|
||||
promise = promises[i];
|
||||
|
||||
if (promise && typeof promise.then === 'function')
|
||||
promise.then(resolver(i), reject);
|
||||
else
|
||||
results[i] = promise;
|
||||
}
|
||||
|
||||
if (!remaining)
|
||||
resolve(results);
|
||||
});
|
||||
};
|
||||
|
||||
Promise.race = function(promises){
|
||||
var Class = this;
|
||||
|
||||
if (!isArray(promises))
|
||||
throw new TypeError('You must pass an array to Promise.race().');
|
||||
|
||||
return new Class(function(resolve, reject) {
|
||||
for (var i = 0, promise; i < promises.length; i++)
|
||||
{
|
||||
promise = promises[i];
|
||||
|
||||
if (promise && typeof promise.then === 'function')
|
||||
promise.then(resolve, reject);
|
||||
else
|
||||
resolve(promise);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Promise.resolve = function(value){
|
||||
var Class = this;
|
||||
|
||||
if (value && typeof value === 'object' && value.constructor === Class)
|
||||
return value;
|
||||
|
||||
return new Class(function(resolve){
|
||||
resolve(value);
|
||||
});
|
||||
};
|
||||
|
||||
Promise.reject = function(reason){
|
||||
var Class = this;
|
||||
|
||||
return new Class(function(resolve, reject){
|
||||
reject(reason);
|
||||
});
|
||||
};
|
||||
|
||||
})(typeof window != 'undefined' ? window : typeof global != 'undefined' ? global : typeof self != 'undefined' ? self : this);
|
6
vendors/es6-promise-polyfill/promise.min.js
vendored
Normal file
6
vendors/es6-promise-polyfill/promise.min.js
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
(function(t){function z(){for(var a=0;a<g.length;a++)g[a][0](g[a][1]);g=[];m=!1}function n(a,b){g.push([a,b]);m||(m=!0,A(z,0))}function B(a,b){function c(a){p(b,a)}function h(a){k(b,a)}try{a(c,h)}catch(d){h(d)}}function u(a){var b=a.owner,c=b.state_,b=b.data_,h=a[c];a=a.then;if("function"===typeof h){c=l;try{b=h(b)}catch(d){k(a,d)}}v(a,b)||(c===l&&p(a,b),c===q&&k(a,b))}function v(a,b){var c;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(b&&("function"===
|
||||
typeof b||"object"===typeof b)){var h=b.then;if("function"===typeof h)return h.call(b,function(d){c||(c=!0,b!==d?p(a,d):w(a,d))},function(b){c||(c=!0,k(a,b))}),!0}}catch(d){return c||k(a,d),!0}return!1}function p(a,b){a!==b&&v(a,b)||w(a,b)}function w(a,b){a.state_===r&&(a.state_=x,a.data_=b,n(C,a))}function k(a,b){a.state_===r&&(a.state_=x,a.data_=b,n(D,a))}function y(a){var b=a.then_;a.then_=void 0;for(a=0;a<b.length;a++)u(b[a])}function C(a){a.state_=l;y(a)}function D(a){a.state_=q;y(a)}function e(a){if("function"!==
|
||||
typeof a)throw new TypeError("Promise constructor takes a function argument");if(!1===this instanceof e)throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this.then_=[];B(a,this)}var f=t.Promise,s=f&&"resolve"in f&&"reject"in f&&"all"in f&&"race"in f&&function(){var a;new f(function(b){a=b});return"function"===typeof a}();"undefined"!==typeof exports&&exports?(exports.Promise=s?f:e,exports.Polyfill=e):"function"==
|
||||
typeof define&&define.amd?define(function(){return s?f:e}):s||(t.Promise=e);var r="pending",x="sealed",l="fulfilled",q="rejected",E=function(){},A="undefined"!==typeof setImmediate?setImmediate:setTimeout,g=[],m;e.prototype={constructor:e,state_:r,then_:null,data_:void 0,then:function(a,b){var c={owner:this,then:new this.constructor(E),fulfilled:a,rejected:b};this.state_===l||this.state_===q?n(u,c):this.then_.push(c);return c.then},"catch":function(a){return this.then(null,a)}};e.all=function(a){if("[object Array]"!==
|
||||
Object.prototype.toString.call(a))throw new TypeError("You must pass an array to Promise.all().");return new this(function(b,c){function h(a){e++;return function(c){d[a]=c;--e||b(d)}}for(var d=[],e=0,f=0,g;f<a.length;f++)(g=a[f])&&"function"===typeof g.then?g.then(h(f),c):d[f]=g;e||b(d)})};e.race=function(a){if("[object Array]"!==Object.prototype.toString.call(a))throw new TypeError("You must pass an array to Promise.race().");return new this(function(b,c){for(var e=0,d;e<a.length;e++)(d=a[e])&&"function"===
|
||||
typeof d.then?d.then(b,c):b(d)})};e.resolve=function(a){return a&&"object"===typeof a&&a.constructor===this?a:new this(function(b){b(a)})};e.reject=function(a){return new this(function(b,c){c(a)})}})("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this);
|
22
vendors/es6-promise-polyfill/test/test-adapter.js
vendored
Normal file
22
vendors/es6-promise-polyfill/test/test-adapter.js
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
var assert = require('assert');
|
||||
var Promise = require('../promise').Polyfill;
|
||||
var resolve = Promise.resolve;
|
||||
var reject = Promise.reject;
|
||||
|
||||
function defer(){
|
||||
var deferred = {};
|
||||
|
||||
deferred.promise = new Promise(function(resolve, reject){
|
||||
deferred.resolve = resolve;
|
||||
deferred.reject = reject;
|
||||
});
|
||||
|
||||
return deferred;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
resolved: function(a){ return Promise.resolve(a); },
|
||||
rejected: function(a){ return Promise.reject(a); },
|
||||
deferred: defer,
|
||||
Promise: Promise
|
||||
};
|
2
vendors/rl/rl-1.5.min.js
vendored
2
vendors/rl/rl-1.5.min.js
vendored
|
@ -1,2 +0,0 @@
|
|||
/*! RainLoop Index Helper v1.5 (c) 2015 RainLoop Team; Licensed under MIT */
|
||||
!function(t,e,n){function r(){}r.prototype.s=t.sessionStorage,r.prototype.t=t.top||t,r.prototype.getHash=function(){var t=null;if(this.s)t=this.s.getItem("__rlA")||null;else if(this.t){var e=this.t.name&&n&&"{"===this.t.name.toString().substr(0,1)?n.parse(this.t.name.toString()):null;t=e?e.__rlA||null:null}return t},r.prototype.setHash=function(){var e=t.rainloopAppData,r=null;this.s?this.s.setItem("__rlA",e&&e.AuthAccountHash?e.AuthAccountHash:""):this.t&&n&&(r={},r.__rlA=e&&e.AuthAccountHash?e.AuthAccountHash:"",this.t.name=n.stringify(r))},r.prototype.clearHash=function(){this.s?this.s.setItem("__rlA",""):this.t&&(this.t.name="")},t._rlhh=new r,t.__rlah=function(){return t._rlhh?t._rlhh.getHash():null},t.__rlah_set=function(){t._rlhh&&t._rlhh.setHash()},t.__rlah_clear=function(){t._rlhh&&t._rlhh.clearHash()},t.__includeScr=function(t){e.write(unescape('%3Cscript data-cfasync="false" type="text/javascript" src="'+t+'"%3E%3C/script%3E'))},t.__includeStyle=function(t){e.write(unescape("%3Cstyle%3E"+t+'"%3E%3C/style%3E'))},t.__showError=function(n){var r=e.getElementById("rl-loading"),s=e.getElementById("rl-loading-error"),l=e.getElementById("rl-loading-error-additional");r&&(r.style.display="none"),s&&(s.style.display="block"),l&&n&&(l.style.display="block",l.innerHTML=n),t.SimplePace&&t.SimplePace.set(100)},t.__simplePace=function(e){t.SimplePace&&t.SimplePace.add(e)},t.__runBoot=function(e,n){t.__APP_BOOT&&!e?t.__APP_BOOT(function(t){t||__showError(n)}):__showError(n)}}(window,window.document,window.JSON);
|
105
vendors/rl/rl.js
vendored
105
vendors/rl/rl.js
vendored
|
@ -1,105 +0,0 @@
|
|||
/*! RainLoop Index Helper v1.5 (c) 2015 RainLoop Team; Licensed under MIT */
|
||||
(function (window, document, JSON, undefined) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function CRLTopDriver() {}
|
||||
|
||||
CRLTopDriver.prototype.s = window['sessionStorage'] || null;
|
||||
|
||||
CRLTopDriver.prototype.t = window['top'] || window;
|
||||
|
||||
/**
|
||||
* @return {(string|null)}
|
||||
*/
|
||||
CRLTopDriver.prototype['getHash'] = function() {
|
||||
var mR = null;
|
||||
if (this.s) {
|
||||
mR = this.s['getItem']('__rlA') || null;
|
||||
} else if (this.t) {
|
||||
var mData = this.t['name'] && JSON && '{' === this.t['name']['toString']()['substr'](0, 1) ? JSON['parse'](this.t['name']['toString']()) : null;
|
||||
mR = mData ? (mData['__rlA'] || null) : null;
|
||||
}
|
||||
return mR;
|
||||
};
|
||||
|
||||
CRLTopDriver.prototype['setHash'] = function() {
|
||||
var mData = window['rainloopAppData'], mRes = null;
|
||||
if (this.s) {
|
||||
this.s['setItem']('__rlA', mData && mData['AuthAccountHash'] ? mData['AuthAccountHash'] : '');
|
||||
} else if (this.t && JSON) {
|
||||
mRes = {};
|
||||
mRes['__rlA'] = mData && mData['AuthAccountHash'] ? mData['AuthAccountHash'] : '';
|
||||
this.t['name'] = JSON['stringify'](mRes);
|
||||
}
|
||||
};
|
||||
|
||||
CRLTopDriver.prototype['clearHash'] = function() {
|
||||
if (this.s) {
|
||||
this.s['setItem']('__rlA', '');
|
||||
} else if (this.t) {
|
||||
this.t['name'] = '';
|
||||
}
|
||||
};
|
||||
|
||||
window['_rlhh'] = new CRLTopDriver();
|
||||
|
||||
/**
|
||||
* @returns {(string|null)}
|
||||
*/
|
||||
window['__rlah'] = function () {
|
||||
return window['_rlhh'] ? window['_rlhh']['getHash']() : null;
|
||||
};
|
||||
|
||||
window['__rlah_set'] = function () {
|
||||
if (window['_rlhh']) {
|
||||
window['_rlhh']['setHash']();
|
||||
}
|
||||
};
|
||||
|
||||
window['__rlah_clear'] = function () {
|
||||
if (window['_rlhh']) {
|
||||
window['_rlhh']['clearHash']();
|
||||
}
|
||||
};
|
||||
|
||||
// index function
|
||||
window['__includeScr'] = function (sSrc) {
|
||||
document.write(unescape('%3Csc' + 'ript data-cfasync="false" type="text/jav' + 'ascr' + 'ipt" sr' + 'c="' + sSrc + '"%3E%3C/' + 'scr' + 'ipt%3E'));
|
||||
};
|
||||
|
||||
window['__includeStyle'] = function (sStyles) {
|
||||
document.write(unescape('%3Csty' + 'le%3E' + sStyles + '"%3E%3C/' + 'sty' + 'le%3E'));
|
||||
};
|
||||
|
||||
window['__showError'] = function (sAdditionalError) {
|
||||
var oR = document.getElementById('rl-loading'),
|
||||
oL = document.getElementById('rl-loading-error'),
|
||||
oLA = document.getElementById('rl-loading-error-additional');
|
||||
|
||||
if (oR) {oR.style.display = 'none';}
|
||||
if (oL) {oL.style.display = 'block';}
|
||||
if (oLA && sAdditionalError) { oLA.style.display = 'block'; oLA.innerHTML = sAdditionalError; }
|
||||
if (window.SimplePace) {window.SimplePace.set(100);}
|
||||
};
|
||||
|
||||
window['__simplePace'] = function (nVal) {
|
||||
if (window.SimplePace) {
|
||||
window.SimplePace.add(nVal);
|
||||
}
|
||||
};
|
||||
|
||||
window['__runBoot'] = function (bWithError, sAdditionalError) {
|
||||
if (window.__APP_BOOT && !bWithError) {
|
||||
window.__APP_BOOT(function (bV) {
|
||||
if (!bV) {
|
||||
__showError(sAdditionalError);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
__showError(sAdditionalError);
|
||||
}
|
||||
};
|
||||
|
||||
}(window, window.document, window.JSON));
|
|
@ -32,6 +32,10 @@ module.exports = {
|
|||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.html$/,
|
||||
loader: 'raw'
|
||||
},
|
||||
{
|
||||
test: /\.jsx$/,
|
||||
loader: 'babel',
|
||||
|
@ -49,7 +53,7 @@ module.exports = {
|
|||
'JSON': 'window.JSON',
|
||||
'JSEncrypt': 'window.JSEncrypt',
|
||||
'$LAB': 'window.$LAB',
|
||||
'progressJs': 'window.rainloopProgressJs',
|
||||
'progressJs': 'window.progressJs',
|
||||
'queue': 'window.queue',
|
||||
'moment': 'window.moment',
|
||||
'ifvisible': 'window.ifvisible',
|
||||
|
|
Loading…
Reference in a new issue