\ No newline at end of file
diff --git a/build/owncloud/rainloop-app/templates/empty.php b/build/owncloud/rainloop-app/templates/empty.php
deleted file mode 100755
index fa0c45f25..000000000
--- a/build/owncloud/rainloop-app/templates/empty.php
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/build/owncloud/rainloop-app/templates/index-empty.php b/build/owncloud/rainloop-app/templates/index-empty.php
deleted file mode 100755
index fc401ff32..000000000
--- a/build/owncloud/rainloop-app/templates/index-empty.php
+++ /dev/null
@@ -1,3 +0,0 @@
-
- t('RainLoop Webmail is not configured yet.')); ?>
-
\ No newline at end of file
diff --git a/build/owncloud/rainloop-app/templates/index.php b/build/owncloud/rainloop-app/templates/index.php
deleted file mode 100755
index cb4bb0290..000000000
--- a/build/owncloud/rainloop-app/templates/index.php
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/dev/App/Abstract.js b/dev/App/Abstract.js
index 86745081d..4772649e7 100644
--- a/dev/App/Abstract.js
+++ b/dev/App/Abstract.js
@@ -26,7 +26,6 @@ import * as Settings from 'Storage/Settings';
import LanguageStore from 'Stores/Language';
import ThemeStore from 'Stores/Theme';
-import SocialStore from 'Stores/Social';
import { routeOff, setHash } from 'Knoin/Knoin';
import { AbstractBoot } from 'Knoin/AbstractBoot';
@@ -38,7 +37,6 @@ class AbstractApp extends AbstractBoot {
constructor() {
super();
- this.googlePreviewSupportedCache = null;
this.isLocalAutocomplete = true;
this.iframe = null;
this.lastErrorTime = 0;
@@ -140,18 +138,6 @@ class AbstractApp extends AbstractBoot {
return true;
}
- /**
- * @returns {boolean}
- */
- googlePreviewSupported() {
- if (null === this.googlePreviewSupportedCache) {
- this.googlePreviewSupportedCache =
- !!Settings.settingsGet('AllowGoogleSocial') && !!Settings.settingsGet('AllowGoogleSocialPreview');
- }
-
- return this.googlePreviewSupportedCache;
- }
-
/**
* @param {string} title
*/
@@ -345,7 +331,6 @@ class AbstractApp extends AbstractBoot {
LanguageStore.populate();
ThemeStore.populate();
- SocialStore.populate();
}
}
diff --git a/dev/App/User.js b/dev/App/User.js
index 427a14a5d..606a84c71 100644
--- a/dev/App/User.js
+++ b/dev/App/User.js
@@ -56,17 +56,13 @@ import {
mailBox,
root,
openPgpWorkerJs,
- openPgpJs,
- socialGoogle,
- socialTwitter,
- socialFacebook
+ openPgpJs
} from 'Common/Links';
import * as Events from 'Common/Events';
import { getNotification, i18n } from 'Common/Translator';
-import SocialStore from 'Stores/Social';
import AppStore from 'Stores/User/App';
import SettingsStore from 'Stores/User/Settings';
import NotificationStore from 'Stores/User/Notification';
@@ -160,8 +156,6 @@ class AppUser extends AbstractApp {
.removeAttr('style');
}, Magics.Time1s);
}
-
- this.socialUsers = _.bind(this.socialUsers, this);
}
remote() {
@@ -854,72 +848,6 @@ class AppUser extends AbstractApp {
}
}
- googleConnect() {
- window.open(
- socialGoogle(),
- 'Google',
- 'left=200,top=100,width=650,height=600,menubar=no,status=no,resizable=yes,scrollbars=yes'
- );
- }
-
- twitterConnect() {
- window.open(
- socialTwitter(),
- 'Twitter',
- 'left=200,top=100,width=650,height=350,menubar=no,status=no,resizable=yes,scrollbars=yes'
- );
- }
-
- facebookConnect() {
- window.open(
- socialFacebook(),
- 'Facebook',
- 'left=200,top=100,width=650,height=335,menubar=no,status=no,resizable=yes,scrollbars=yes'
- );
- }
-
- /**
- * @param {boolean=} fireAllActions = false
- */
- socialUsers(fireAllActions = false) {
- if (true === fireAllActions) {
- SocialStore.google.loading(true);
- SocialStore.facebook.loading(true);
- SocialStore.twitter.loading(true);
- }
-
- Remote.socialUsers((result, data) => {
- if (StorageResultType.Success === result && data && data.Result) {
- SocialStore.google.userName(data.Result.Google || '');
- SocialStore.facebook.userName(data.Result.Facebook || '');
- SocialStore.twitter.userName(data.Result.Twitter || '');
- } else {
- SocialStore.google.userName('');
- SocialStore.facebook.userName('');
- SocialStore.twitter.userName('');
- }
-
- SocialStore.google.loading(false);
- SocialStore.facebook.loading(false);
- SocialStore.twitter.loading(false);
- });
- }
-
- googleDisconnect() {
- SocialStore.google.loading(true);
- Remote.googleDisconnect(this.socialUsers);
- }
-
- facebookDisconnect() {
- SocialStore.facebook.loading(true);
- Remote.facebookDisconnect(this.socialUsers);
- }
-
- twitterDisconnect() {
- SocialStore.twitter.loading(true);
- Remote.twitterDisconnect(this.socialUsers);
- }
-
/**
* @param {string} query
* @param {Function} autocompleteCallback
@@ -1198,10 +1126,7 @@ class AppUser extends AbstractApp {
let contactsSyncInterval = pInt(Settings.settingsGet('ContactsSyncInterval'));
const jsHash = Settings.appSettingsGet('jsHash'),
- startupUrl = pString(Settings.settingsGet('StartupUrl')),
- allowGoogle = Settings.settingsGet('AllowGoogleSocial'),
- allowFacebook = Settings.settingsGet('AllowFacebookSocial'),
- allowTwitter = Settings.settingsGet('AllowTwitterSocial');
+ startupUrl = pString(Settings.settingsGet('StartupUrl'));
if (progressJs) {
progressJs.set(90);
@@ -1276,10 +1201,6 @@ class AppUser extends AbstractApp {
// false ? AboutUserScreen : null
]);
- if (allowGoogle || allowFacebook || allowTwitter) {
- this.socialUsers(true);
- }
-
Events.sub('interval.2m', () => this.folderInformation(getFolderInboxName()));
Events.sub('interval.3m', () => {
const sF = FolderStore.currentFolderFullNameRaw();
@@ -1356,27 +1277,6 @@ class AppUser extends AbstractApp {
this.bootstartLoginScreen();
}
- if (allowGoogle) {
- window['rl_' + jsHash + '_google_service'] = () => {
- SocialStore.google.loading(true);
- this.socialUsers();
- };
- }
-
- if (allowFacebook) {
- window['rl_' + jsHash + '_facebook_service'] = () => {
- SocialStore.facebook.loading(true);
- this.socialUsers();
- };
- }
-
- if (allowTwitter) {
- window['rl_' + jsHash + '_twitter_service'] = () => {
- SocialStore.twitter.loading(true);
- this.socialUsers();
- };
- }
-
Events.sub('interval.1m', () => momentReload());
runHook('rl-start-screens');
diff --git a/dev/Common/Links.js b/dev/Common/Links.js
index 1c45f7826..7f88b30c8 100644
--- a/dev/Common/Links.js
+++ b/dev/Common/Links.js
@@ -255,35 +255,6 @@ export function exportContactsCsv() {
return SERVER_PREFIX + '/Raw/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/ContactsCsv/';
}
-/**
- * @param {boolean} xauth = false
- * @returns {string}
- */
-export function socialGoogle(xauth = false) {
- return (
- SERVER_PREFIX +
- 'SocialGoogle' +
- ('' !== AUTH_PREFIX ? '/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/' : '') +
- (xauth ? '&xauth=1' : '')
- );
-}
-
-/**
- * @returns {string}
- */
-export function socialTwitter() {
- return SERVER_PREFIX + 'SocialTwitter' + ('' !== AUTH_PREFIX ? '/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/' : '');
-}
-
-/**
- * @returns {string}
- */
-export function socialFacebook() {
- return (
- SERVER_PREFIX + 'SocialFacebook' + ('' !== AUTH_PREFIX ? '/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/' : '')
- );
-}
-
/**
* @param {string} path
* @returns {string}
diff --git a/dev/Remote/User/Ajax.js b/dev/Remote/User/Ajax.js
index 4234976bc..0b5917f65 100644
--- a/dev/Remote/User/Ajax.js
+++ b/dev/Remote/User/Ajax.js
@@ -909,55 +909,6 @@ class RemoteUserAjax extends AbstractAjaxRemote {
clearUserBackground(fCallback) {
this.defaultRequest(fCallback, 'ClearUserBackground');
}
-
- /**
- * @param {?Function} fCallback
- */
- facebookUser(fCallback) {
- this.defaultRequest(fCallback, 'SocialFacebookUserInformation');
- }
-
- /**
- * @param {?Function} fCallback
- */
- facebookDisconnect(fCallback) {
- this.defaultRequest(fCallback, 'SocialFacebookDisconnect');
- }
-
- /**
- * @param {?Function} fCallback
- */
- twitterUser(fCallback) {
- this.defaultRequest(fCallback, 'SocialTwitterUserInformation');
- }
-
- /**
- * @param {?Function} fCallback
- */
- twitterDisconnect(fCallback) {
- this.defaultRequest(fCallback, 'SocialTwitterDisconnect');
- }
-
- /**
- * @param {?Function} fCallback
- */
- googleUser(fCallback) {
- this.defaultRequest(fCallback, 'SocialGoogleUserInformation');
- }
-
- /**
- * @param {?Function} fCallback
- */
- googleDisconnect(fCallback) {
- this.defaultRequest(fCallback, 'SocialGoogleDisconnect');
- }
-
- /**
- * @param {?Function} fCallback
- */
- socialUsers(fCallback) {
- this.defaultRequest(fCallback, 'SocialUsers');
- }
}
export default new RemoteUserAjax();
diff --git a/dev/Screen/Admin/Settings.js b/dev/Screen/Admin/Settings.js
index 4ee1489d2..ed5899c3d 100644
--- a/dev/Screen/Admin/Settings.js
+++ b/dev/Screen/Admin/Settings.js
@@ -8,7 +8,6 @@ import { DomainsAdminSettings } from 'Settings/Admin/Domains';
import { LoginAdminSettings } from 'Settings/Admin/Login';
import { ContactsAdminSettings } from 'Settings/Admin/Contacts';
import { SecurityAdminSettings } from 'Settings/Admin/Security';
-import { SocialAdminSettings } from 'Settings/Admin/Social';
import { PluginsAdminSettings } from 'Settings/Admin/Plugins';
import { PackagesAdminSettings } from 'Settings/Admin/Packages';
import { AboutAdminSettings } from 'Settings/Admin/About';
@@ -57,13 +56,6 @@ class SettingsAdminScreen extends AbstractSettingsScreen {
addSettingsViewModel(SecurityAdminSettings, 'AdminSettingsSecurity', 'TABS_LABELS/LABEL_SECURITY_NAME', 'security');
- addSettingsViewModel(
- SocialAdminSettings,
- 'AdminSettingsSocial',
- 'TABS_LABELS/LABEL_INTEGRATION_NAME',
- 'integrations'
- );
-
addSettingsViewModel(PluginsAdminSettings, 'AdminSettingsPlugins', 'TABS_LABELS/LABEL_PLUGINS_NAME', 'plugins');
addSettingsViewModel(PackagesAdminSettings, 'AdminSettingsPackages', 'TABS_LABELS/LABEL_PACKAGES_NAME', 'packages');
diff --git a/dev/Screen/User/Settings.js b/dev/Screen/User/Settings.js
index 18700cf38..59a905fe2 100644
--- a/dev/Screen/User/Settings.js
+++ b/dev/Screen/User/Settings.js
@@ -16,7 +16,6 @@ import { ContactsUserSettings } from 'Settings/User/Contacts';
import { AccountsUserSettings } from 'Settings/User/Accounts';
import { FiltersUserSettings } from 'Settings/User/Filters';
import { SecurityUserSettings } from 'Settings/User/Security';
-import { SocialUserSettings } from 'Settings/User/Social';
import { ChangePasswordUserSettings } from 'Settings/User/ChangePassword';
import { TemplatesUserSettings } from 'Settings/User/Templates';
import { FoldersUserSettings } from 'Settings/User/Folders';
@@ -80,15 +79,6 @@ class SettingsUserScreen extends AbstractSettingsScreen {
addSettingsViewModel(SecurityUserSettings, 'SettingsSecurity', 'SETTINGS_LABELS/LABEL_SECURITY_NAME', 'security');
}
- if (
- AccountStore.isRootAccount() &&
- ((Settings.settingsGet('AllowGoogleSocial') && Settings.settingsGet('AllowGoogleSocialAuth')) ||
- Settings.settingsGet('AllowFacebookSocial') ||
- Settings.settingsGet('AllowTwitterSocial'))
- ) {
- addSettingsViewModel(SocialUserSettings, 'SettingsSocial', 'SETTINGS_LABELS/LABEL_SOCIAL_NAME', 'social');
- }
-
if (Settings.settingsGet('ChangePasswordIsAllowed')) {
addSettingsViewModel(
ChangePasswordUserSettings,
diff --git a/dev/Settings/Admin/Social.js b/dev/Settings/Admin/Social.js
deleted file mode 100644
index 74c7ec760..000000000
--- a/dev/Settings/Admin/Social.js
+++ /dev/null
@@ -1,105 +0,0 @@
-import _ from '_';
-import ko from 'ko';
-
-import { SaveSettingsStep, Magics } from 'Common/Enums';
-import { settingsSaveHelperSimpleFunction, trim, boolToAjax } from 'Common/Utils';
-
-import SocialStore from 'Stores/Social';
-
-import Remote from 'Remote/Admin/Ajax';
-
-class SocialAdminSettings {
- constructor() {
- this.googleEnable = SocialStore.google.enabled;
- this.googleEnableAuth = SocialStore.google.capa.auth;
- this.googleEnableAuthGmail = SocialStore.google.capa.authGmail;
- this.googleEnableDrive = SocialStore.google.capa.drive;
- this.googleEnablePreview = SocialStore.google.capa.preview;
-
- this.googleEnableRequireClientSettings = SocialStore.google.require.clientSettings;
- this.googleEnableRequireApiKey = SocialStore.google.require.apiKeySettings;
-
- this.googleClientID = SocialStore.google.clientID;
- this.googleClientSecret = SocialStore.google.clientSecret;
- this.googleApiKey = SocialStore.google.apiKey;
-
- this.googleTrigger1 = ko.observable(SaveSettingsStep.Idle);
- this.googleTrigger2 = ko.observable(SaveSettingsStep.Idle);
- this.googleTrigger3 = ko.observable(SaveSettingsStep.Idle);
-
- this.facebookSupported = SocialStore.facebook.supported;
- this.facebookEnable = SocialStore.facebook.enabled;
- this.facebookAppID = SocialStore.facebook.appID;
- this.facebookAppSecret = SocialStore.facebook.appSecret;
-
- this.facebookTrigger1 = ko.observable(SaveSettingsStep.Idle);
- this.facebookTrigger2 = ko.observable(SaveSettingsStep.Idle);
-
- this.twitterEnable = SocialStore.twitter.enabled;
- this.twitterConsumerKey = SocialStore.twitter.consumerKey;
- this.twitterConsumerSecret = SocialStore.twitter.consumerSecret;
-
- this.twitterTrigger1 = ko.observable(SaveSettingsStep.Idle);
- this.twitterTrigger2 = ko.observable(SaveSettingsStep.Idle);
-
- this.dropboxEnable = SocialStore.dropbox.enabled;
- this.dropboxApiKey = SocialStore.dropbox.apiKey;
-
- this.dropboxTrigger1 = ko.observable(SaveSettingsStep.Idle);
- }
-
- onBuild() {
- _.delay(() => {
- const f1 = settingsSaveHelperSimpleFunction(this.facebookTrigger1, this),
- f2 = settingsSaveHelperSimpleFunction(this.facebookTrigger2, this),
- f3 = settingsSaveHelperSimpleFunction(this.twitterTrigger1, this),
- f4 = settingsSaveHelperSimpleFunction(this.twitterTrigger2, this),
- f5 = settingsSaveHelperSimpleFunction(this.googleTrigger1, this),
- f6 = settingsSaveHelperSimpleFunction(this.googleTrigger2, this),
- f7 = settingsSaveHelperSimpleFunction(this.googleTrigger3, this),
- f8 = settingsSaveHelperSimpleFunction(this.dropboxTrigger1, this);
-
- this.facebookEnable.subscribe((value) => {
- if (this.facebookSupported()) {
- Remote.saveAdminConfig(null, {
- 'FacebookEnable': boolToAjax(value)
- });
- }
- });
-
- this.facebookAppID.subscribe((value) => {
- if (this.facebookSupported()) {
- Remote.saveAdminConfig(f1, {
- 'FacebookAppID': trim(value)
- });
- }
- });
-
- this.facebookAppSecret.subscribe((value) => {
- if (this.facebookSupported()) {
- Remote.saveAdminConfig(f2, {
- 'FacebookAppSecret': trim(value)
- });
- }
- });
-
- this.twitterEnable.subscribe(Remote.saveAdminConfigHelper('TwitterEnable', boolToAjax));
- this.twitterConsumerKey.subscribe(Remote.saveAdminConfigHelper('TwitterConsumerKey', trim, f3));
- this.twitterConsumerSecret.subscribe(Remote.saveAdminConfigHelper('TwitterConsumerSecret', trim, f4));
-
- this.googleEnable.subscribe(Remote.saveAdminConfigHelper('GoogleEnable', boolToAjax));
- this.googleEnableAuth.subscribe(Remote.saveAdminConfigHelper('GoogleEnableAuth', boolToAjax));
- this.googleEnableAuthGmail.subscribe(Remote.saveAdminConfigHelper('GoogleEnableAuthGmail', boolToAjax));
- this.googleEnableDrive.subscribe(Remote.saveAdminConfigHelper('GoogleEnableDrive', boolToAjax));
- this.googleEnablePreview.subscribe(Remote.saveAdminConfigHelper('GoogleEnablePreview', boolToAjax));
- this.googleClientID.subscribe(Remote.saveAdminConfigHelper('GoogleClientID', trim, f5));
- this.googleClientSecret.subscribe(Remote.saveAdminConfigHelper('GoogleClientSecret', trim, f6));
- this.googleApiKey.subscribe(Remote.saveAdminConfigHelper('GoogleApiKey', trim, f7));
-
- this.dropboxEnable.subscribe(Remote.saveAdminConfigHelper('DropboxEnable', boolToAjax));
- this.dropboxApiKey.subscribe(Remote.saveAdminConfigHelper('DropboxApiKey', trim, f8));
- }, Magics.Time50ms);
- }
-}
-
-export { SocialAdminSettings, SocialAdminSettings as default };
diff --git a/dev/Settings/User/Social.js b/dev/Settings/User/Social.js
deleted file mode 100644
index 8439f752c..000000000
--- a/dev/Settings/User/Social.js
+++ /dev/null
@@ -1,69 +0,0 @@
-import SocialStore from 'Stores/Social';
-
-import { getApp } from 'Helper/Apps/User';
-
-import { command } from 'Knoin/Knoin';
-
-class SocialUserSettings {
- constructor() {
- this.googleEnable = SocialStore.google.enabled;
- this.googleEnableAuth = SocialStore.google.capa.auth;
- this.googleEnableAuthGmail = SocialStore.google.capa.authGmail;
- this.googleEnableDrive = SocialStore.google.capa.drive;
- this.googleEnablePreview = SocialStore.google.capa.preview;
-
- this.googleActions = SocialStore.google.loading;
- this.googleLoggined = SocialStore.google.loggined;
- this.googleUserName = SocialStore.google.userName;
-
- this.facebookEnable = SocialStore.facebook.enabled;
-
- this.facebookActions = SocialStore.facebook.loading;
- this.facebookLoggined = SocialStore.facebook.loggined;
- this.facebookUserName = SocialStore.facebook.userName;
-
- this.twitterEnable = SocialStore.twitter.enabled;
-
- this.twitterActions = SocialStore.twitter.loading;
- this.twitterLoggined = SocialStore.twitter.loggined;
- this.twitterUserName = SocialStore.twitter.userName;
- }
-
- @command((self) => !self.googleLoggined() && !self.googleActions())
- connectGoogleCommand() {
- if (!this.googleLoggined()) {
- getApp().googleConnect();
- }
- }
-
- @command()
- disconnectGoogleCommand() {
- getApp().googleDisconnect();
- }
-
- @command((self) => !self.facebookLoggined() && !self.facebookActions())
- connectFacebookCommand() {
- if (!this.facebookLoggined()) {
- getApp().facebookConnect();
- }
- }
-
- @command()
- disconnectFacebookCommand() {
- getApp().facebookDisconnect();
- }
-
- @command((self) => !self.twitterLoggined() && !self.twitterActions())
- connectTwitterCommand() {
- if (!this.twitterLoggined()) {
- getApp().twitterConnect();
- }
- }
-
- @command()
- disconnectTwitterCommand() {
- getApp().twitterDisconnect();
- }
-}
-
-export { SocialUserSettings, SocialUserSettings as default };
diff --git a/dev/Stores/Social.js b/dev/Stores/Social.js
deleted file mode 100644
index 150a767c1..000000000
--- a/dev/Stores/Social.js
+++ /dev/null
@@ -1,103 +0,0 @@
-import window from 'window';
-import ko from 'ko';
-import $ from '$';
-import * as Settings from 'Storage/Settings';
-
-class SocialStore {
- constructor() {
- this.google = {};
- this.twitter = {};
- this.facebook = {};
- this.dropbox = {};
-
- // Google
- this.google.enabled = ko.observable(false);
-
- this.google.clientID = ko.observable('');
- this.google.clientSecret = ko.observable('');
- this.google.apiKey = ko.observable('');
-
- this.google.loading = ko.observable(false);
- this.google.userName = ko.observable('');
-
- this.google.loggined = ko.computed(() => '' !== this.google.userName());
-
- this.google.capa = {};
- this.google.capa.auth = ko.observable(false);
- this.google.capa.authGmail = ko.observable(false);
- this.google.capa.drive = ko.observable(false);
- this.google.capa.preview = ko.observable(false);
-
- this.google.require = {};
- this.google.require.clientSettings = ko.computed(
- () =>
- this.google.enabled() && (this.google.capa.auth() || this.google.capa.authGmail() || this.google.capa.drive())
- );
-
- this.google.require.apiKeySettings = ko.computed(() => this.google.enabled() && this.google.capa.drive());
-
- // Facebook
- this.facebook.enabled = ko.observable(false);
- this.facebook.appID = ko.observable('');
- this.facebook.appSecret = ko.observable('');
- this.facebook.loading = ko.observable(false);
- this.facebook.userName = ko.observable('');
- this.facebook.supported = ko.observable(false);
-
- this.facebook.loggined = ko.computed(() => '' !== this.facebook.userName());
-
- // Twitter
- this.twitter.enabled = ko.observable(false);
- this.twitter.consumerKey = ko.observable('');
- this.twitter.consumerSecret = ko.observable('');
- this.twitter.loading = ko.observable(false);
- this.twitter.userName = ko.observable('');
-
- this.twitter.loggined = ko.computed(() => '' !== this.twitter.userName());
-
- // Dropbox
- this.dropbox.enabled = ko.observable(false);
- this.dropbox.apiKey = ko.observable('');
- }
-
- populate() {
- this.google.enabled(!!Settings.settingsGet('AllowGoogleSocial'));
- this.google.clientID(Settings.settingsGet('GoogleClientID'));
- this.google.clientSecret(Settings.settingsGet('GoogleClientSecret'));
- this.google.apiKey(Settings.settingsGet('GoogleApiKey'));
-
- this.google.capa.auth(!!Settings.settingsGet('AllowGoogleSocialAuth'));
- this.google.capa.authGmail(!!Settings.settingsGet('AllowGoogleSocialAuthGmail'));
- this.google.capa.drive(!!Settings.settingsGet('AllowGoogleSocialDrive'));
- this.google.capa.preview(!!Settings.settingsGet('AllowGoogleSocialPreview'));
-
- this.facebook.enabled(!!Settings.settingsGet('AllowFacebookSocial'));
- this.facebook.appID(Settings.settingsGet('FacebookAppID'));
- this.facebook.appSecret(Settings.settingsGet('FacebookAppSecret'));
- this.facebook.supported(!!Settings.settingsGet('SupportedFacebookSocial'));
-
- this.twitter.enabled = ko.observable(!!Settings.settingsGet('AllowTwitterSocial'));
- this.twitter.consumerKey = ko.observable(Settings.settingsGet('TwitterConsumerKey'));
- this.twitter.consumerSecret = ko.observable(Settings.settingsGet('TwitterConsumerSecret'));
-
- this.dropbox.enabled(!!Settings.settingsGet('AllowDropboxSocial'));
- this.dropbox.apiKey(Settings.settingsGet('DropboxApiKey'));
- }
-
- appendDropbox() {
- if (!window.Dropbox && this.dropbox.enabled() && this.dropbox.apiKey()) {
- if (!window.document.getElementById('dropboxjs')) {
- const script = window.document.createElement('script');
- script.type = 'text/javascript';
- script.src = 'https://www.dropbox.com/static/api/2/dropins.js';
- $(script)
- .attr('id', 'dropboxjs')
- .attr('data-app-key', this.dropbox.apiKey());
-
- window.document.body.appendChild(script);
- }
- }
- }
-}
-
-export default new SocialStore();
diff --git a/dev/Styles/_social.css b/dev/Styles/_social.css
deleted file mode 100644
index 1dce84e33..000000000
--- a/dev/Styles/_social.css
+++ /dev/null
@@ -1,47 +0,0 @@
-@keyframes redirectingRotation {
- to {
- transform: rotate(1turn);
- }
-}
-
-html, body {
- padding: 0;
- margin: 0;
- overflow: hidden;
-}
-
-.social-icon-wrp {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
-}
-
-.social-icon {
- position: absolute;
- top: 50%;
- left: 50%;
- font-size: 140px;
- margin: -60px 0 0 -60px;
- color: #999;
-}
-
-.redirecting:after{
- content: '';
- position: absolute;
- width: 240px;
- height: 240px;
- top: 50%;
- left: 50%;
- margin-top: -120px;
- margin-left: -120px;
-
- border: 8px solid transparent;
- border-color: transparent;
- border-top-color: #999;
- animation: redirectingRotation 1s infinite ease-in-out;
-
- border-radius: 50%;
- z-index: 1;
-}
diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js
index 3e63ae20f..d66f0b73f 100644
--- a/dev/View/Popup/Compose.js
+++ b/dev/View/Popup/Compose.js
@@ -49,7 +49,6 @@ import AccountStore from 'Stores/User/Account';
import FolderStore from 'Stores/User/Folder';
import PgpStore from 'Stores/User/Pgp';
import MessageStore from 'Stores/User/Message';
-import SocialStore from 'Stores/Social';
import Remote from 'Remote/User/Ajax';
@@ -329,21 +328,6 @@ class ComposePopupView extends AbstractViewNext {
this.showBcc.subscribe(this.resizerTrigger);
this.showReplyTo.subscribe(this.resizerTrigger);
- this.dropboxEnabled = SocialStore.dropbox.enabled;
- this.dropboxApiKey = SocialStore.dropbox.apiKey;
-
- this.driveEnabled = ko.observable(
- bXMLHttpRequestSupported &&
- !!Settings.settingsGet('AllowGoogleSocial') &&
- !!Settings.settingsGet('AllowGoogleSocialDrive') &&
- !!Settings.settingsGet('GoogleClientID') &&
- !!Settings.settingsGet('GoogleApiKey')
- );
-
- this.driveVisible = ko.observable(false);
-
- this.driveCallback = _.bind(this.driveCallback, this);
-
this.onMessageUploadAttachments = _.bind(this.onMessageUploadAttachments, this);
this.bDisabeCloseOnEsc = true;
@@ -530,28 +514,6 @@ class ComposePopupView extends AbstractViewNext {
}
}
- @command((self) => self.dropboxEnabled())
- dropboxCommand() {
- if (window.Dropbox) {
- window.Dropbox.choose({
- success: (files) => {
- if (files && files[0] && files[0].link) {
- this.addDropboxAttachment(files[0]);
- }
- },
- linkType: 'direct',
- multiselect: false
- });
- }
- return true;
- }
-
- @command((self) => self.driveEnabled())
- driveCommand() {
- this.driveOpenPopup();
- return true;
- }
-
autosaveFunction() {
if (
this.modalVisibility() &&
@@ -1289,16 +1251,6 @@ class ComposePopupView extends AbstractViewNext {
Events.sub('window.resize.real', this.resizerTrigger);
Events.sub('window.resize.real', _.debounce(this.resizerTrigger, Magics.Time50ms));
- SocialStore.appendDropbox();
-
- if (this.driveEnabled()) {
- $.getScript('https://apis.google.com/js/api.js', () => {
- if (window.gapi) {
- this.driveVisible(true);
- }
- });
- }
-
window.setInterval(() => {
if (this.modalVisibility() && this.oEditor) {
this.oEditor.resize();
@@ -1306,137 +1258,6 @@ class ComposePopupView extends AbstractViewNext {
}, Magics.Time5s);
}
- driveCallback(accessToken, data) {
- if (
- data &&
- window.XMLHttpRequest &&
- window.google &&
- data[window.google.picker.Response.ACTION] === window.google.picker.Action.PICKED &&
- data[window.google.picker.Response.DOCUMENTS] &&
- data[window.google.picker.Response.DOCUMENTS][0] &&
- data[window.google.picker.Response.DOCUMENTS][0].id
- ) {
- const request = new window.XMLHttpRequest();
- request.open(
- 'GET',
- 'https://www.googleapis.com/drive/v2/files/' + data[window.google.picker.Response.DOCUMENTS][0].id
- );
- request.setRequestHeader('Authorization', 'Bearer ' + accessToken);
- request.addEventListener('load', () => {
- if (request && request.responseText) {
- const response = window.JSON.parse(request.responseText),
- fExport = (item, mimeType, ext) => {
- if (item && item.exportLinks) {
- if (item.exportLinks[mimeType]) {
- response.downloadUrl = item.exportLinks[mimeType];
- response.title = item.title + '.' + ext;
- response.mimeType = mimeType;
- } else if (item.exportLinks['application/pdf']) {
- response.downloadUrl = item.exportLinks['application/pdf'];
- response.title = item.title + '.pdf';
- response.mimeType = 'application/pdf';
- }
- }
- };
-
- if (response && !response.downloadUrl && response.mimeType && response.exportLinks) {
- switch (response.mimeType.toString().toLowerCase()) {
- case 'application/vnd.google-apps.document':
- fExport(response, 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'docx');
- break;
- case 'application/vnd.google-apps.spreadsheet':
- fExport(response, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xlsx');
- break;
- case 'application/vnd.google-apps.drawing':
- fExport(response, 'image/png', 'png');
- break;
- case 'application/vnd.google-apps.presentation':
- fExport(response, 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'pptx');
- break;
- default:
- fExport(response, 'application/pdf', 'pdf');
- break;
- }
- }
-
- if (response && response.downloadUrl) {
- this.addDriveAttachment(response, accessToken);
- }
- }
- });
-
- request.send();
- }
- }
-
- driveCreatePiker(authToken) {
- if (window.gapi && authToken && authToken.access_token) {
- window.gapi.load('picker', {
- callback: () => {
- if (window.google && window.google.picker) {
- const drivePicker = new window.google.picker.PickerBuilder()
- // .addView(window.google.picker.ViewId.FOLDERS)
- .addView(window.google.picker.ViewId.DOCS)
- .setAppId(Settings.settingsGet('GoogleClientID'))
- .setOAuthToken(authToken.access_token)
- .setCallback(_.bind(this.driveCallback, this, authToken.access_token))
- .enableFeature(window.google.picker.Feature.NAV_HIDDEN)
- // .setOrigin(window.location.protocol + '//' + window.location.host)
- .build();
-
- drivePicker.setVisible(true);
- }
- }
- });
- }
- }
-
- driveOpenPopup() {
- if (window.gapi) {
- window.gapi.load('auth', {
- callback: () => {
- const authToken = window.gapi.auth.getToken(),
- fResult = (authResult) => {
- if (authResult && !authResult.error) {
- const token = window.gapi.auth.getToken();
- if (token) {
- this.driveCreatePiker(token);
- }
-
- return true;
- }
-
- return false;
- };
-
- if (!authToken) {
- window.gapi.auth.authorize(
- {
- 'client_id': Settings.settingsGet('GoogleClientID'),
- 'scope': 'https://www.googleapis.com/auth/drive.readonly',
- 'immediate': true
- },
- (authResult) => {
- if (!fResult(authResult)) {
- window.gapi.auth.authorize(
- {
- 'client_id': Settings.settingsGet('GoogleClientID'),
- 'scope': 'https://www.googleapis.com/auth/drive.readonly',
- 'immediate': false
- },
- fResult
- );
- }
- }
- );
- } else {
- this.driveCreatePiker(authToken);
- }
- }
- });
- }
- }
-
/**
* @param {string} id
* @returns {?Object}
@@ -1643,83 +1464,6 @@ class ComposePopupView extends AbstractViewNext {
return attachment;
}
- /**
- * @param {Object} dropboxFile
- * @returns {boolean}
- */
- addDropboxAttachment(dropboxFile) {
- const attachmentSizeLimit = pInt(Settings.settingsGet('AttachmentLimit')),
- mSize = dropboxFile.bytes,
- attachment = this.addAttachmentHelper(dropboxFile.link, dropboxFile.name, mSize);
-
- if (0 < mSize && 0 < attachmentSizeLimit && attachmentSizeLimit < mSize) {
- attachment.uploading(false).complete(true);
- attachment.error(i18n('UPLOAD/ERROR_FILE_IS_TOO_BIG'));
- return false;
- }
-
- Remote.composeUploadExternals(
- (statusResult, data) => {
- let result = false;
- attachment.uploading(false).complete(true);
-
- if (StorageResultType.Success === statusResult && data && data.Result) {
- if (data.Result[attachment.id]) {
- result = true;
- attachment.tempName(data.Result[attachment.id]);
- }
- }
-
- if (!result) {
- attachment.error(getUploadErrorDescByCode(UploadErrorCode.FileNoUploaded));
- }
- },
- [dropboxFile.link]
- );
-
- return true;
- }
-
- /**
- * @param {Object} driveFile
- * @param {string} accessToken
- * @returns {boolean}
- */
- addDriveAttachment(driveFile, accessToken) {
- const attachmentSizeLimit = pInt(Settings.settingsGet('AttachmentLimit')),
- size = driveFile.fileSize ? pInt(driveFile.fileSize) : 0,
- attachment = this.addAttachmentHelper(driveFile.downloadUrl, driveFile.title, size);
-
- if (0 < size && 0 < attachmentSizeLimit && attachmentSizeLimit < size) {
- attachment.uploading(false).complete(true);
- attachment.error(i18n('UPLOAD/ERROR_FILE_IS_TOO_BIG'));
- return false;
- }
-
- Remote.composeUploadDrive(
- (statusResult, data) => {
- let result = false;
- attachment.uploading(false).complete(true);
-
- if (StorageResultType.Success === statusResult && data && data.Result) {
- if (data.Result[attachment.id]) {
- result = true;
- attachment.tempName(data.Result[attachment.id][0]);
- attachment.size(pInt(data.Result[attachment.id][1]));
- }
- }
-
- if (!result) {
- attachment.error(getUploadErrorDescByCode(UploadErrorCode.FileNoUploaded));
- }
- },
- driveFile.downloadUrl,
- accessToken
- );
-
- return true;
- }
-
/**
* @param {MessageModel} message
* @param {string} type
diff --git a/dev/View/User/Login.js b/dev/View/User/Login.js
index d9879466a..599e8d06b 100644
--- a/dev/View/User/Login.js
+++ b/dev/View/User/Login.js
@@ -14,7 +14,6 @@ import {
import { trim, inArray, pInt, convertLangName, triggerAutocompleteInputChange } from 'Common/Utils';
import { $win } from 'Common/Globals';
-import { socialFacebook, socialGoogle, socialTwitter } from 'Common/Links';
import { getNotification, getNotificationFromResponse, reload as translatorReload } from 'Common/Translator';
import * as Plugins from 'Common/Plugins';
@@ -141,19 +140,6 @@ class LoginUserView extends AbstractViewNext {
this.signMeVisibility = ko.computed(() => LoginSignMeType.Unused !== this.signMeType());
- this.facebookLoginEnabled = ko.observable(false);
- this.googleLoginEnabled = ko.observable(false);
- this.googleGmailLoginEnabled = ko.observable(false);
- this.twitterLoginEnabled = ko.observable(false);
-
- this.socialLoginEnabled = ko.computed(() => {
- const bF = this.facebookLoginEnabled(),
- bG = this.googleLoginEnabled(),
- bT = this.twitterLoginEnabled();
-
- return bF || bG || bT;
- });
-
if (Settings.settingsGet('AdditionalLoginError') && !this.submitError()) {
this.submitError(Settings.settingsGet('AdditionalLoginError'));
}
@@ -163,30 +149,6 @@ class LoginUserView extends AbstractViewNext {
return `left=200,top=100,width=${wh},height=${wh},menubar=no,status=no,resizable=yes,scrollbars=yes`;
}
- @command((self) => !self.submitRequest() && self.facebookLoginEnabled())
- facebookCommand() {
- window.open(socialFacebook(), 'Facebook', this.windowOpenFeatures(500));
- return true;
- }
-
- @command((self) => !self.submitRequest() && self.googleLoginEnabled())
- googleCommand() {
- window.open(socialGoogle(), 'Google', this.windowOpenFeatures(550));
- return true;
- }
-
- @command((self) => !self.submitRequest() && self.googleGmailLoginEnabled())
- googleGmailCommand() {
- window.open(socialGoogle(true), 'Google', this.windowOpenFeatures(550));
- return true;
- }
-
- @command((self) => !self.submitRequest() && self.twitterLoginEnabled())
- twitterCommand() {
- window.open(socialTwitter(), 'Twitter', this.windowOpenFeatures(500));
- return true;
- }
-
@command((self) => !self.submitRequest())
submitCommand() {
triggerAutocompleteInputChange();
@@ -328,25 +290,7 @@ class LoginUserView extends AbstractViewNext {
onBuild() {
const signMeLocal = Local.get(ClientSideKeyName.LastSignMe),
signMe = (Settings.settingsGet('SignMe') || 'unused').toLowerCase(),
- jsHash = Settings.appSettingsGet('jsHash'),
- fSocial = (iErrorCode) => {
- iErrorCode = pInt(iErrorCode);
- if (0 === iErrorCode) {
- this.submitRequest(true);
- getApp().loginAndLogoutReload(false);
- } else {
- this.submitError(getNotification(iErrorCode));
- }
- };
-
- this.facebookLoginEnabled(!!Settings.settingsGet('AllowFacebookSocial'));
- this.twitterLoginEnabled(!!Settings.settingsGet('AllowTwitterSocial'));
- this.googleLoginEnabled(
- !!Settings.settingsGet('AllowGoogleSocial') && !!Settings.settingsGet('AllowGoogleSocialAuth')
- );
- this.googleGmailLoginEnabled(
- !!Settings.settingsGet('AllowGoogleSocial') && !!Settings.settingsGet('AllowGoogleSocialAuthGmail')
- );
+ jsHash = Settings.appSettingsGet('jsHash');
switch (signMe) {
case LoginSignMeTypeAsString.DefaultOff:
@@ -375,18 +319,6 @@ class LoginUserView extends AbstractViewNext {
this.email(AppStore.devEmail);
this.password(AppStore.devPassword);
- if (this.googleLoginEnabled() || this.googleGmailLoginEnabled()) {
- window['rl_' + jsHash + '_google_login_service'] = fSocial;
- }
-
- if (this.facebookLoginEnabled()) {
- window['rl_' + jsHash + '_facebook_login_service'] = fSocial;
- }
-
- if (this.twitterLoginEnabled()) {
- window['rl_' + jsHash + '_twitter_login_service'] = fSocial;
- }
-
_.delay(() => {
LanguageStore.language.subscribe((value) => {
this.langRequest(true);
diff --git a/dev/View/User/MailBox/MessageView.js b/dev/View/User/MailBox/MessageView.js
index 6179e9bc9..a91bc3b86 100644
--- a/dev/View/User/MailBox/MessageView.js
+++ b/dev/View/User/MailBox/MessageView.js
@@ -43,7 +43,6 @@ import { attachmentDownload } from 'Common/Links';
import { getUserPic, storeMessageFlagsToCache } from 'Common/Cache';
-import SocialStore from 'Stores/Social';
import AppStore from 'Stores/User/App';
import SettingsStore from 'Stores/User/Settings';
import AccountStore from 'Stores/User/Account';
@@ -144,46 +143,6 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
this.downloadAsZipLoading = ko.observable(false);
this.downloadAsZipError = ko.observable(false).extend({ falseTimeout: 7000 });
- this.saveToOwnCloudAllowed = ko.computed(
- () => -1 < inArray('owncloud', this.attachmentsActions()) && this.allowAttachmnetControls()
- );
-
- this.saveToOwnCloudLoading = ko.observable(false);
- this.saveToOwnCloudSuccess = ko.observable(false).extend({ falseTimeout: 2000 });
- this.saveToOwnCloudError = ko.observable(false).extend({ falseTimeout: 7000 });
-
- this.saveToOwnCloudSuccess.subscribe((v) => {
- if (v) {
- this.saveToOwnCloudError(false);
- }
- });
-
- this.saveToOwnCloudError.subscribe((v) => {
- if (v) {
- this.saveToOwnCloudSuccess(false);
- }
- });
-
- this.saveToDropboxAllowed = ko.computed(
- () => -1 < inArray('dropbox', this.attachmentsActions()) && this.allowAttachmnetControls()
- );
-
- this.saveToDropboxLoading = ko.observable(false);
- this.saveToDropboxSuccess = ko.observable(false).extend({ falseTimeout: 2000 });
- this.saveToDropboxError = ko.observable(false).extend({ falseTimeout: 7000 });
-
- this.saveToDropboxSuccess.subscribe((v) => {
- if (v) {
- this.saveToDropboxError(false);
- }
- });
-
- this.saveToDropboxError.subscribe((v) => {
- if (v) {
- this.saveToDropboxSuccess(false);
- }
- });
-
this.showAttachmnetControls.subscribe((v) => {
if (this.message()) {
_.each(this.message().attachments(), (item) => {
@@ -243,9 +202,6 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
this.spamCommand = createCommandActionHelper(FolderType.Spam, true);
this.notSpamCommand = createCommandActionHelper(FolderType.NotSpam, true);
- this.dropboxEnabled = SocialStore.dropbox.enabled;
- this.dropboxApiKey = SocialStore.dropbox.apiKey;
-
// viewer
this.viewBodyTopValue = ko.observable(0);
@@ -606,8 +562,6 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
Local.set(ClientSideKeyName.MessageHeaderFullInfo, value ? '1' : '0');
});
- SocialStore.appendDropbox();
-
this.oHeaderDom = $('.messageItemHeader', dom);
this.oHeaderDom = this.oHeaderDom[0] ? this.oHeaderDom : null;
@@ -956,77 +910,6 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
}
}
- saveToOwnCloud() {
- const hashes = this.getAttachmentsHashes();
- if (0 < hashes.length) {
- Promises.attachmentsActions('OwnCloud', hashes, this.saveToOwnCloudLoading)
- .then((result) => {
- if (result && result.Result) {
- this.saveToOwnCloudSuccess(true);
- } else {
- this.saveToOwnCloudError(true);
- }
- })
- .catch(() => {
- this.saveToOwnCloudError(true);
- });
- } else {
- this.highlightUnselectedAttachments(true);
- }
- }
-
- saveToDropbox() {
- const files = [],
- hashes = this.getAttachmentsHashes();
-
- if (0 < hashes.length) {
- if (window.Dropbox) {
- Promises.attachmentsActions('Dropbox', hashes, this.saveToDropboxLoading)
- .then((result) => {
- if (result && result.Result && result.Result.Url && result.Result.ShortLife && result.Result.Files) {
- if (window.Dropbox && isArray(result.Result.Files)) {
- _.each(result.Result.Files, (item) => {
- files.push({
- url: result.Result.Url + attachmentDownload(item.Hash, result.Result.ShortLife),
- filename: item.FileName
- });
- });
-
- window.Dropbox.save({
- files: files,
- progress: () => {
- this.saveToDropboxLoading(true);
- this.saveToDropboxError(false);
- this.saveToDropboxSuccess(false);
- },
- cancel: () => {
- this.saveToDropboxSuccess(false);
- this.saveToDropboxError(false);
- this.saveToDropboxLoading(false);
- },
- success: () => {
- this.saveToDropboxSuccess(true);
- this.saveToDropboxLoading(false);
- },
- error: () => {
- this.saveToDropboxError(true);
- this.saveToDropboxLoading(false);
- }
- });
- } else {
- this.saveToDropboxError(true);
- }
- }
- })
- .catch(() => {
- this.saveToDropboxError(true);
- });
- }
- } else {
- this.highlightUnselectedAttachments(true);
- }
- }
-
/**
* @param {MessageModel} oMessage
* @returns {void}
diff --git a/dev/boot.js b/dev/boot.js
index 40fef1062..71257f00c 100644
--- a/dev/boot.js
+++ b/dev/boot.js
@@ -21,7 +21,6 @@ window.progressJs.onbeforeend(() => {
}
});
-require('../vendors/modernizr/modernizr-custom.js');
require('Common/Booter');
if (window.__runBoot) {
diff --git a/gulpfile.js b/gulpfile.js
index e78aabdef..1c6628169 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -8,7 +8,6 @@ const { css, cssLint } = require('./tasks/css');
const { vendors } = require('./tasks/vendors');
const { watchCss } = require('./tasks/watch');
const { rainloop } = require('./tasks/rainloop');
-const { owncloud } = require('./tasks/owncloud');
const clean = gulp.series(cleanStatic);
@@ -27,5 +26,4 @@ exports.default = build;
exports.watchCss = watchCss;
exports.rainloop = gulp.series(build, rainloop);
-exports.owncloud = gulp.series(build, owncloud);
-exports.all = gulp.series(exports.rainloop, exports.owncloud);
+exports.all = gulp.series(exports.rainloop);
diff --git a/package.json b/package.json
index 3b696bc2e..a1114eb16 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,6 @@
"description": "Simple, modern & fast web-based email client",
"private": true,
"version": "1.14.0",
- "ownCloudVersion": "5.3.0",
"homepage": "https://www.rainloop.net",
"author": {
"name": "RainLoop Team",
diff --git a/plugins/_depricated/convert-headers-styles/CssToInlineStyles.php b/plugins/_depricated/convert-headers-styles/CssToInlineStyles.php
deleted file mode 100644
index 1d19bca35..000000000
--- a/plugins/_depricated/convert-headers-styles/CssToInlineStyles.php
+++ /dev/null
@@ -1,700 +0,0 @@
-
- * @version 1.1.0
- * @copyright Copyright (c), Tijs Verkoyen. All rights reserved.
- * @license BSD License
- */
-class CssToInlineStyles
-{
- /**
- * The CSS to use
- *
- * @var string
- */
- private $css;
-
- /**
- * The processed CSS rules
- *
- * @var array
- */
- private $cssRules;
-
- /**
- * Should the generated HTML be cleaned
- *
- * @var bool
- */
- private $cleanup = false;
-
- /**
- * The encoding to use.
- *
- * @var string
- */
- private $encoding = 'UTF-8';
-
- /**
- * The HTML to process
- *
- * @var string
- */
- private $html;
-
- /**
- * Use inline-styles block as CSS
- *
- * @var bool
- */
- private $useInlineStylesBlock = false;
-
- /*
- * Strip original style tags
- *
- * @var bool
- */
- private $stripOriginalStyleTags = false;
-
- /**
- * Creates an instance, you could set the HTML and CSS here, or load it
- * later.
- *
- * @return void
- * @param string[optional] $html The HTML to process.
- * @param string[optional] $css The CSS to use.
- */
- public function __construct($html = null, $css = null)
- {
- if($html !== null) $this->setHTML($html);
- if($css !== null) $this->setCSS($css);
- }
-
- /**
- * Convert a CSS-selector into an xPath-query
- *
- * @return string
- * @param string $selector The CSS-selector.
- */
- private function buildXPathQuery($selector)
- {
- // redefine
- $selector = (string) $selector;
-
- // the CSS selector
- $cssSelector = array(
- // E F, Matches any F element that is a descendant of an E element
- '/(\w)\s+(\w)/',
- // E > F, Matches any F element that is a child of an element E
- '/(\w)\s*>\s*(\w)/',
- // E:first-child, Matches element E when E is the first child of its parent
- '/(\w):first-child/',
- // E + F, Matches any F element immediately preceded by an element
- '/(\w)\s*\+\s*(\w)/',
- // E[foo], Matches any E element with the "foo" attribute set (whatever the value)
- '/(\w)\[([\w\-]+)]/',
- // E[foo="warning"], Matches any E element whose "foo" attribute value is exactly equal to "warning"
- '/(\w)\[([\w\-]+)\=\"(.*)\"]/',
- // div.warning, HTML only. The same as DIV[class~="warning"]
- '/(\w+|\*)+\.([\w\-]+)+/',
- // .warning, HTML only. The same as *[class~="warning"]
- '/\.([\w\-]+)/',
- // E#myid, Matches any E element with id-attribute equal to "myid"
- '/(\w+)+\#([\w\-]+)/',
- // #myid, Matches any element with id-attribute equal to "myid"
- '/\#([\w\-]+)/'
- );
-
- // the xPath-equivalent
- $xPathQuery = array(
- // E F, Matches any F element that is a descendant of an E element
- '\1//\2',
- // E > F, Matches any F element that is a child of an element E
- '\1/\2',
- // E:first-child, Matches element E when E is the first child of its parent
- '*[1]/self::\1',
- // E + F, Matches any F element immediately preceded by an element
- '\1/following-sibling::*[1]/self::\2',
- // E[foo], Matches any E element with the "foo" attribute set (whatever the value)
- '\1 [ @\2 ]',
- // E[foo="warning"], Matches any E element whose "foo" attribute value is exactly equal to "warning"
- '\1[ contains( concat( " ", @\2, " " ), concat( " ", "\3", " " ) ) ]',
- // div.warning, HTML only. The same as DIV[class~="warning"]
- '\1[ contains( concat( " ", @class, " " ), concat( " ", "\2", " " ) ) ]',
- // .warning, HTML only. The same as *[class~="warning"]
- '*[ contains( concat( " ", @class, " " ), concat( " ", "\1", " " ) ) ]',
- // E#myid, Matches any E element with id-attribute equal to "myid"
- '\1[ @id = "\2" ]',
- // #myid, Matches any element with id-attribute equal to "myid"
- '*[ @id = "\1" ]'
- );
-
- // return
- $xPath = (string) '//' . preg_replace($cssSelector, $xPathQuery, $selector);
-
- return str_replace('] *', ']//*', $xPath);
- }
-
- /**
- * Calculate the specifity for the CSS-selector
- *
- * @return int
- * @param string $selector The selector to calculate the specifity for.
- */
- private function calculateCSSSpecifity($selector)
- {
- // cleanup selector
- $selector = str_replace(array('>', '+'), array(' > ', ' + '), $selector);
-
- // init var
- $specifity = 0;
-
- // split the selector into chunks based on spaces
- $chunks = explode(' ', $selector);
-
- // loop chunks
- foreach ($chunks as $chunk) {
- // an ID is important, so give it a high specifity
- if(strstr($chunk, '#') !== false) $specifity += 100;
-
- // classes are more important than a tag, but less important then an ID
- elseif(strstr($chunk, '.')) $specifity += 10;
-
- // anything else isn't that important
- else $specifity += 1;
- }
-
- // return
- return $specifity;
- }
-
-
- /**
- * Cleanup the generated HTML
- *
- * @return string
- * @param string $html The HTML to cleanup.
- */
- private function cleanupHTML($html)
- {
- // remove classes
- $html = preg_replace('/(\s)+class="(.*)"(\s)+/U', ' ', $html);
-
- // remove IDs
- $html = preg_replace('/(\s)+id="(.*)"(\s)+/U', ' ', $html);
-
- // return
- return $html;
- }
-
-
- /**
- * Converts the loaded HTML into an HTML-string with inline styles based on the loaded CSS
- *
- * @return string
- * @param bool[optional] $outputXHTML Should we output valid XHTML?
- */
- public function convert($outputXHTML = false)
- {
- // redefine
- $outputXHTML = (bool) $outputXHTML;
-
- // validate
- if($this->html == null) throw new Exception('No HTML provided.');
-
- // should we use inline style-block
- if ($this->useInlineStylesBlock) {
- // init var
- $matches = array();
-
- // match the style blocks
- preg_match_all('||isU', $this->html, $matches);
-
- // any style-blocks found?
- if (!empty($matches[2])) {
- // add
- foreach($matches[2] as $match) $this->css .= trim($match) ."\n";
- }
- }
-
- // process css
- $this->processCSS();
-
- // create new DOMDocument
- $document = new \DOMDocument('1.0', $this->getEncoding());
-
- // set error level
- libxml_use_internal_errors(true);
-
- // load HTML
-// $document->loadHTML($this->html);
- $document->loadHTML('<'.'?xml version="1.0" encoding="'.$this->getEncoding().'"?'.'>'.$this->html);
-
- // create new XPath
- $xPath = new \DOMXPath($document);
-
- // any rules?
- if (!empty($this->cssRules)) {
- // loop rules
- foreach ($this->cssRules as $rule) {
- // init var
- $query = $this->buildXPathQuery($rule['selector']);
-
- // validate query
- if($query === false) continue;
-
- // search elements
- $elements = $xPath->query($query);
-
- // validate elements
- if($elements === false) continue;
-
- // loop found elements
- foreach ($elements as $element) {
- // no styles stored?
- if ($element->attributes->getNamedItem(
- 'data-css-to-inline-styles-original-styles'
- ) == null) {
- // init var
- $originalStyle = '';
- if ($element->attributes->getNamedItem('style') !== null) {
- $originalStyle = $element->attributes->getNamedItem('style')->value;
- }
-
- // store original styles
- $element->setAttribute(
- 'data-css-to-inline-styles-original-styles',
- $originalStyle
- );
-
- // clear the styles
- $element->setAttribute('style', '');
- }
-
- // init var
- $properties = array();
-
- // get current styles
- $stylesAttribute = $element->attributes->getNamedItem('style');
-
- // any styles defined before?
- if ($stylesAttribute !== null) {
- // get value for the styles attribute
- $definedStyles = (string) $stylesAttribute->value;
-
- // split into properties
- $definedProperties = (array) explode(';', $definedStyles);
-
- // loop properties
- foreach ($definedProperties as $property) {
- // validate property
- if($property == '') continue;
-
- // split into chunks
- $chunks = (array) explode(':', trim($property), 2);
-
- // validate
- if(!isset($chunks[1])) continue;
-
- // loop chunks
- $properties[$chunks[0]] = trim($chunks[1]);
- }
- }
-
- // add new properties into the list
- foreach ($rule['properties'] as $key => $value) {
- $properties[$key] = $value;
- }
-
- // build string
- $propertyChunks = array();
-
- // build chunks
- foreach ($properties as $key => $values) {
- foreach ((array) $values as $value) {
- $propertyChunks[] = $key . ': ' . $value . ';';
- }
- }
-
- // build properties string
- $propertiesString = implode(' ', $propertyChunks);
-
- // set attribute
- if ($propertiesString != '') {
- $element->setAttribute('style', $propertiesString);
- }
- }
- }
-
- // reapply original styles
- $query = $this->buildXPathQuery(
- '*[@data-css-to-inline-styles-original-styles]'
- );
-
- // validate query
- if($query === false) return;
-
- // search elements
- $elements = $xPath->query($query);
-
- // loop found elements
- foreach ($elements as $element) {
- // get the original styles
- $originalStyle = $element->attributes->getNamedItem(
- 'data-css-to-inline-styles-original-styles'
- )->value;
-
- if ($originalStyle != '') {
- $originalProperties = array();
- $originalStyles = (array) explode(';', $originalStyle);
-
- foreach ($originalStyles as $property) {
- // validate property
- if($property == '') continue;
-
- // split into chunks
- $chunks = (array) explode(':', trim($property), 2);
-
- // validate
- if(!isset($chunks[1])) continue;
-
- // loop chunks
- $originalProperties[$chunks[0]] = trim($chunks[1]);
- }
-
- // get current styles
- $stylesAttribute = $element->attributes->getNamedItem('style');
- $properties = array();
-
- // any styles defined before?
- if ($stylesAttribute !== null) {
- // get value for the styles attribute
- $definedStyles = (string) $stylesAttribute->value;
-
- // split into properties
- $definedProperties = (array) explode(';', $definedStyles);
-
- // loop properties
- foreach ($definedProperties as $property) {
- // validate property
- if($property == '') continue;
-
- // split into chunks
- $chunks = (array) explode(':', trim($property), 2);
-
- // validate
- if(!isset($chunks[1])) continue;
-
- // loop chunks
- $properties[$chunks[0]] = trim($chunks[1]);
- }
- }
-
- // add new properties into the list
- foreach ($originalProperties as $key => $value) {
- $properties[$key] = $value;
- }
-
- // build string
- $propertyChunks = array();
-
- // build chunks
- foreach ($properties as $key => $values) {
- foreach ((array) $values as $value) {
- $propertyChunks[] = $key . ': ' . $value . ';';
- }
- }
-
- // build properties string
- $propertiesString = implode(' ', $propertyChunks);
-
- // set attribute
- if($propertiesString != '') $element->setAttribute(
- 'style', $propertiesString
- );
- }
-
- // remove placeholder
- $element->removeAttribute(
- 'data-css-to-inline-styles-original-styles'
- );
- }
- }
-
- // should we output XHTML?
- if ($outputXHTML) {
- // set formating
- $document->formatOutput = true;
-
- // get the HTML as XML
- $html = $document->saveXML(null, LIBXML_NOEMPTYTAG);
-
- // get start of the XML-declaration
- $startPosition = strpos($html, '', $startPosition);
-
- // remove the XML-header
- $html = ltrim(substr($html, $endPosition + 1));
- }
- }
-
- // just regular HTML 4.01 as it should be used in newsletters
- else {
- // get the HTML
- $html = $document->saveHTML();
- }
-
- // cleanup the HTML if we need to
- if($this->cleanup) $html = $this->cleanupHTML($html);
-
- // strip original style tags if we need to
- if ($this->stripOriginalStyleTags) {
- $html = $this->stripOriginalStyleTags($html);
- }
-
- // return
- return $html;
- }
-
-
- /**
- * Get the encoding to use
- *
- * @return string
- */
- private function getEncoding()
- {
- return $this->encoding;
- }
-
-
- /**
- * Process the loaded CSS
- *
- * @return void
- */
- private function processCSS()
- {
- // init vars
- $css = (string) $this->css;
-
- // remove newlines
- $css = str_replace(array("\r", "\n"), '', $css);
-
- // replace double quotes by single quotes
- $css = str_replace('"', '\'', $css);
-
- // remove comments
- $css = preg_replace('|/\*.*?\*/|', '', $css);
-
- // remove spaces
- $css = preg_replace('/\s\s+/', ' ', $css);
-
- // rules are splitted by }
- $rules = (array) explode('}', $css);
-
- // init var
- $i = 1;
-
- // loop rules
- foreach ($rules as $rule) {
- // split into chunks
- $chunks = explode('{', $rule);
-
- // invalid rule?
- if(!isset($chunks[1])) continue;
-
- // set the selectors
- $selectors = trim($chunks[0]);
-
- // get cssProperties
- $cssProperties = trim($chunks[1]);
-
- // split multiple selectors
- $selectors = (array) explode(',', $selectors);
-
- // loop selectors
- foreach ($selectors as $selector) {
- // cleanup
- $selector = trim($selector);
-
- // build an array for each selector
- $ruleSet = array();
-
- // store selector
- $ruleSet['selector'] = $selector;
-
- // process the properties
- $ruleSet['properties'] = $this->processCSSProperties(
- $cssProperties
- );
-
- // calculate specifity
- $ruleSet['specifity'] = $this->calculateCSSSpecifity(
- $selector
- ) + $i;
-
- // add into global rules
- $this->cssRules[] = $ruleSet;
- }
-
- // increment
- $i++;
- }
-
- // sort based on specifity
- if (!empty($this->cssRules)) {
- usort($this->cssRules, array(__CLASS__, 'sortOnSpecifity'));
- }
- }
-
- /**
- * Process the CSS-properties
- *
- * @return array
- * @param string $propertyString The CSS-properties.
- */
- private function processCSSProperties($propertyString)
- {
- // split into chunks
- $properties = (array) explode(';', $propertyString);
-
- // init var
- $pairs = array();
-
- // loop properties
- foreach ($properties as $property) {
- // split into chunks
- $chunks = (array) explode(':', $property, 2);
-
- // validate
- if(!isset($chunks[1])) continue;
-
- // cleanup
- $chunks[0] = trim($chunks[0]);
- $chunks[1] = trim($chunks[1]);
-
- // add to pairs array
- if(!isset($pairs[$chunks[0]]) ||
- !in_array($chunks[1], $pairs[$chunks[0]])) {
- $pairs[$chunks[0]][] = $chunks[1];
- }
- }
-
- // sort the pairs
- ksort($pairs);
-
- // return
- return $pairs;
- }
-
- /**
- * Should the IDs and classes be removed?
- *
- * @return void
- * @param bool[optional] $on Should we enable cleanup?
- */
- public function setCleanup($on = true)
- {
- $this->cleanup = (bool) $on;
- }
-
- /**
- * Set CSS to use
- *
- * @return void
- * @param string $css The CSS to use.
- */
- public function setCSS($css)
- {
- $this->css = (string) $css;
- }
-
- /**
- * Set the encoding to use with the DOMDocument
- *
- * @return void
- * @param string $encoding The encoding to use.
- */
- public function setEncoding($encoding)
- {
- $this->encoding = (string) $encoding;
- }
-
- /**
- * Set HTML to process
- *
- * @return void
- * @param string $html The HTML to process.
- */
- public function setHTML($html)
- {
- $this->html = (string) $html;
- }
-
- /**
- * Set use of inline styles block
- * If this is enabled the class will use the style-block in the HTML.
- *
- * @return void
- * @param bool[optional] $on Should we process inline styles?
- */
- public function setUseInlineStylesBlock($on = true)
- {
- $this->useInlineStylesBlock = (bool) $on;
- }
-
- /**
- * Set strip original style tags
- * If this is enabled the class will remove all style tags in the HTML.
- *
- * @return void
- * @param bool[optional] $onShould we process inline styles?
- */
- public function setStripOriginalStyleTags($on = true)
- {
- $this->stripOriginalStyleTags = (bool) $on;
- }
-
- /**
- * Strip style tags into the generated HTML
- *
- * @return string
- * @param string $html The HTML to strip style tags.
- */
- private function stripOriginalStyleTags($html)
- {
- return preg_replace('||isU', '', $html);
- }
-
- /**
- * Sort an array on the specifity element
- *
- * @return int
- * @param array $e1 The first element.
- * @param array $e2 The second element.
- */
- private static function sortOnSpecifity($e1, $e2)
- {
- // validate
- if(!isset($e1['specifity']) || !isset($e2['specifity'])) return 0;
-
- // lower
- if($e1['specifity'] < $e2['specifity']) return -1;
-
- // higher
- if($e1['specifity'] > $e2['specifity']) return 1;
-
- // fallback
- return 0;
- }
-}
diff --git a/plugins/_depricated/convert-headers-styles/LICENSE b/plugins/_depricated/convert-headers-styles/LICENSE
deleted file mode 100644
index 271342337..000000000
--- a/plugins/_depricated/convert-headers-styles/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 RainLoop Team
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/plugins/_depricated/convert-headers-styles/README b/plugins/_depricated/convert-headers-styles/README
deleted file mode 100644
index 746409f68..000000000
--- a/plugins/_depricated/convert-headers-styles/README
+++ /dev/null
@@ -1 +0,0 @@
-Plugin used for processing complex embedded styles in mail messages. In some cases, it can improve rendering HTML mails.
\ No newline at end of file
diff --git a/plugins/_depricated/convert-headers-styles/VERSION b/plugins/_depricated/convert-headers-styles/VERSION
deleted file mode 100644
index a58941b07..000000000
--- a/plugins/_depricated/convert-headers-styles/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-1.3
\ No newline at end of file
diff --git a/plugins/_depricated/convert-headers-styles/index.php b/plugins/_depricated/convert-headers-styles/index.php
deleted file mode 100644
index 249291d12..000000000
--- a/plugins/_depricated/convert-headers-styles/index.php
+++ /dev/null
@@ -1,29 +0,0 @@
-addHook('filter.result-message', 'FilterResultMessage');
- }
-
- /**
- * @param \MailSo\Mail\Message &$oMessage
- */
- public function FilterResultMessage(&$oMessage)
- {
- if ($oMessage)
- {
- $sHtml = $oMessage->Html();
- if ($sHtml && 0 < strlen($sHtml))
- {
- include_once __DIR__.'/CssToInlineStyles.php';
-
- $oCSSToInlineStyles = new \TijsVerkoyen\CssToInlineStyles\CssToInlineStyles($sHtml);
- $oCSSToInlineStyles->setEncoding('utf-8');
- $oCSSToInlineStyles->setUseInlineStylesBlock(true);
- $oMessage->SetHtml($oCSSToInlineStyles->convert().'');
- }
- }
- }
-}
diff --git a/plugins/_depricated/recaptcha/LICENSE b/plugins/_depricated/recaptcha/LICENSE
deleted file mode 100644
index 271342337..000000000
--- a/plugins/_depricated/recaptcha/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 RainLoop Team
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/plugins/_depricated/recaptcha/README b/plugins/_depricated/recaptcha/README
deleted file mode 100644
index 17e4ab032..000000000
--- a/plugins/_depricated/recaptcha/README
+++ /dev/null
@@ -1,3 +0,0 @@
-A CAPTCHA is a program that can generate and grade tests that humans can pass but current computer programs cannot.
-For example, humans can read distorted text as the one shown below, but current computer programs can't.
-More info at http://www.google.com/recaptcha
\ No newline at end of file
diff --git a/plugins/_depricated/recaptcha/VERSION b/plugins/_depricated/recaptcha/VERSION
deleted file mode 100644
index 872765e5f..000000000
--- a/plugins/_depricated/recaptcha/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-1.9
\ No newline at end of file
diff --git a/plugins/_depricated/recaptcha/index.php b/plugins/_depricated/recaptcha/index.php
deleted file mode 100644
index 2875839f7..000000000
--- a/plugins/_depricated/recaptcha/index.php
+++ /dev/null
@@ -1,139 +0,0 @@
-UseLangs(true);
-
- $this->addJs('js/recaptcha.js');
-
- $this->addHook('ajax.action-pre-call', 'AjaxActionPreCall');
- $this->addHook('filter.ajax-response', 'FilterAjaxResponse');
-
- $this->addTemplate('templates/PluginLoginReCaptchaGroup.html');
- $this->addTemplateHook('Login', 'BottomControlGroup', 'PluginLoginReCaptchaGroup');
- }
-
- /**
- * @return array
- */
- public function configMapping()
- {
- return array(
- \RainLoop\Plugins\Property::NewInstance('public_key')->SetLabel('Public Key')
- ->SetAllowedInJs(true)
- ->SetDefaultValue(''),
- \RainLoop\Plugins\Property::NewInstance('private_key')->SetLabel('Private Key')
- ->SetDefaultValue(''),
- \RainLoop\Plugins\Property::NewInstance('error_limit')->SetLabel('Limit')
- ->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
- ->SetDefaultValue(array(0, 1, 2, 3, 4, 5))
- ->SetDescription('')
- );
- }
-
- /**
- * @return string
- */
- private function getCaptchaCacherKey()
- {
- return 'Captcha/Login/'.\RainLoop\Utils::GetConnectionToken();
- }
-
- /**
- * @return int
- */
- private function getLimit()
- {
- $iConfigLimit = $this->Config()->Get('plugin', 'error_limit', 0);
- if (0 < $iConfigLimit)
- {
- $oCacher = $this->Manager()->Actions()->Cacher();
- $sLimit = $oCacher && $oCacher->IsInited() ? $oCacher->Get($this->getCaptchaCacherKey()) : '0';
-
- if (0 < strlen($sLimit) && is_numeric($sLimit))
- {
- $iConfigLimit -= (int) $sLimit;
- }
- }
-
- return $iConfigLimit;
- }
-
- /**
- * @return void
- */
- public function FilterAppDataPluginSection($bAdmin, $bAuth, &$aData)
- {
- if (!$bAdmin && !$bAuth && is_array($aData))
- {
- $aData['show_captcha_on_login'] = 1 > $this->getLimit();
- }
- }
-
- /**
- * @param string $sAction
- */
- public function AjaxActionPreCall($sAction)
- {
- if ('Login' === $sAction && 0 >= $this->getLimit())
- {
- require_once __DIR__.'/recaptchalib.php';
-
- $oResp = recaptcha_check_answer(
- $this->Config()->Get('plugin', 'private_key', ''),
- isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '',
- $this->Manager()->Actions()->GetActionParam('RecaptchaChallenge', ''),
- $this->Manager()->Actions()->GetActionParam('RecaptchaResponse', '')
- );
-
- if (!$oResp || !isset($oResp->is_valid) || !$oResp->is_valid)
- {
- $this->Manager()->Actions()->Logger()->WriteDump($oResp);
- throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CaptchaError);
- }
- }
- }
-
- /**
- * @param string $sAction
- * @param array $aResponseItem
- */
- public function FilterAjaxResponse($sAction, &$aResponseItem)
- {
- if ('Login' === $sAction && $aResponseItem && isset($aResponseItem['Result']))
- {
- $oCacher = $this->Manager()->Actions()->Cacher();
- $iConfigLimit = (int) $this->Config()->Get('plugin', 'error_limit', 0);
- $sKey = $this->getCaptchaCacherKey();
-
- if (0 < $iConfigLimit && $oCacher && $oCacher->IsInited())
- {
- if (false === $aResponseItem['Result'])
- {
- $iLimit = 0;
- $sLimut = $oCacher->Get($sKey);
- if (0 < strlen($sLimut) && is_numeric($sLimut))
- {
- $iLimit = (int) $sLimut;
- }
-
- $oCacher->Set($sKey, ++$iLimit);
-
- if ($iConfigLimit <= $iLimit)
- {
- $aResponseItem['Captcha'] = true;
- }
- }
- else
- {
- $oCacher->Delete($sKey);
- }
- }
- }
- }
-}
diff --git a/plugins/_depricated/recaptcha/js/recaptcha.js b/plugins/_depricated/recaptcha/js/recaptcha.js
deleted file mode 100644
index cbda2d216..000000000
--- a/plugins/_depricated/recaptcha/js/recaptcha.js
+++ /dev/null
@@ -1,78 +0,0 @@
-
-$(function () {
-
- var
- bStarted = false,
- bShown = false
- ;
-
- function ShowRecaptcha()
- {
- if (window.Recaptcha)
- {
- if (bShown)
- {
- window.Recaptcha.reload();
- }
- else
- {
- window.Recaptcha.create(window.rl.pluginSettingsGet('recaptcha', 'public_key'), 'recaptcha-place', {
- 'theme': 'custom',
- 'lang': window.rl.settingsGet('Language')
- });
- }
-
- bShown = true;
- }
- }
-
- function StartRecaptcha()
- {
- if (!window.Recaptcha)
- {
- $.getScript('//www.google.com/recaptcha/api/js/recaptcha_ajax.js', ShowRecaptcha);
- }
- else
- {
- ShowRecaptcha();
- }
- }
-
- if (window.rl)
- {
- window.rl.addHook('view-model-on-show', function (sName, oViewModel) {
- if (!bStarted && oViewModel &&
- ('View:RainLoop:Login' === sName || 'View/App/Login' === sName || 'LoginViewModel' === sName || 'LoginAppView' === sName) &&
- window.rl.pluginSettingsGet('recaptcha', 'show_captcha_on_login'))
- {
- bStarted = true;
- StartRecaptcha();
- }
- });
-
- window.rl.addHook('ajax-default-request', function (sAction, oParameters) {
- if ('Login' === sAction && oParameters && bShown && window.Recaptcha)
- {
- oParameters['RecaptchaChallenge'] = window.Recaptcha.get_challenge();
- oParameters['RecaptchaResponse'] = window.Recaptcha.get_response();
- }
- });
-
- window.rl.addHook('ajax-default-response', function (sAction, oData, sType) {
- if ('Login' === sAction)
- {
- if (!oData || 'success' !== sType || !oData['Result'])
- {
- if (bShown && window.Recaptcha)
- {
- window.Recaptcha.reload();
- }
- else if (oData && oData['Captcha'])
- {
- StartRecaptcha();
- }
- }
- }
- });
- }
-});
\ No newline at end of file
diff --git a/plugins/_depricated/recaptcha/langs/en.ini b/plugins/_depricated/recaptcha/langs/en.ini
deleted file mode 100644
index 87ed5f76c..000000000
--- a/plugins/_depricated/recaptcha/langs/en.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[PLUGIN]
-LABEL_ENTER_THE_WORDS_ABOVE = "Enter the words above"
\ No newline at end of file
diff --git a/plugins/_depricated/recaptcha/langs/ru.ini b/plugins/_depricated/recaptcha/langs/ru.ini
deleted file mode 100644
index 77329095c..000000000
--- a/plugins/_depricated/recaptcha/langs/ru.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[PLUGIN]
-LABEL_ENTER_THE_WORDS_ABOVE = "Введите слова с изображения"
\ No newline at end of file
diff --git a/plugins/_depricated/recaptcha/recaptchalib.php b/plugins/_depricated/recaptcha/recaptchalib.php
deleted file mode 100644
index 337fbc795..000000000
--- a/plugins/_depricated/recaptcha/recaptchalib.php
+++ /dev/null
@@ -1,280 +0,0 @@
- $value )
- $req .= $key . '=' . urlencode( stripslashes($value) ) . '&';
-
- // Cut the last '&'
- $req=substr($req,0,strlen($req)-1);
- return $req;
-}
-
-
-
-/**
- * Submits an HTTP POST to a reCAPTCHA server
- * @param string $host
- * @param string $path
- * @param array $data
- * @param int port
- * @return array response
- */
-function _recaptcha_http_post($host, $path, $data, $port = 80) {
-
- $req = _recaptcha_qsencode ($data);
-
- $http_request = "POST $path HTTP/1.0\r\n";
- $http_request .= "Host: $host\r\n";
- $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
- $http_request .= "Content-Length: " . strlen($req) . "\r\n";
- $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
- $http_request .= "\r\n";
- $http_request .= $req;
-
- $response = '';
- if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
- die ('Could not open socket');
- }
-
- fwrite($fs, $http_request);
-
- while ( !feof($fs) )
- $response .= fgets($fs, 1160); // One TCP-IP packet
- fclose($fs);
- $response = explode("\r\n\r\n", $response, 2);
-
- return $response;
-}
-
-
-
-/**
- * Gets the challenge HTML (javascript and non-javascript version).
- * This is called from the browser, and the resulting reCAPTCHA HTML widget
- * is embedded within the HTML form it was called from.
- * @param string $pubkey A public key for reCAPTCHA
- * @param string $error The error given by reCAPTCHA (optional, default is null)
- * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)
-
- * @return string - The HTML to be embedded in the user's form.
- */
-function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
-{
- if ($pubkey == null || $pubkey == '') {
- die ("To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create");
- }
-
- if ($use_ssl) {
- $server = RECAPTCHA_API_SECURE_SERVER;
- } else {
- $server = RECAPTCHA_API_SERVER;
- }
-
- $errorpart = "";
- if ($error) {
- $errorpart = "&error=" . $error;
- }
- return '
-
- ';
-}
-
-
-
-
-/**
- * A ReCaptchaResponse is returned from recaptcha_check_answer()
- */
-class ReCaptchaResponse {
- var $is_valid;
- var $error;
-}
-
-
-/**
- * Calls an HTTP POST function to verify if the user's guess was correct
- * @param string $privkey
- * @param string $remoteip
- * @param string $challenge
- * @param string $response
- * @param array $extra_params an array of extra variables to post to the server
- * @return ReCaptchaResponse
- */
-function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array())
-{
- if ($privkey == null || $privkey == '') {
- $recaptcha_response = new ReCaptchaResponse();
- $recaptcha_response->is_valid = false;
- $recaptcha_response->error = 'To use reCAPTCHA you must get an API key from https://www.google.com/recaptcha/admin/create';
- return $recaptcha_response;
- }
-
- if ($remoteip == null || $remoteip == '') {
- $recaptcha_response = new ReCaptchaResponse();
- $recaptcha_response->is_valid = false;
- $recaptcha_response->error = 'For security reasons, you must pass the remote ip to reCAPTCHA';
- return $recaptcha_response;
- }
-
- //discard spam submissions
- if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {
- $recaptcha_response = new ReCaptchaResponse();
- $recaptcha_response->is_valid = false;
- $recaptcha_response->error = 'incorrect-captcha-sol';
- return $recaptcha_response;
- }
-
- $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify",
- array (
- 'privatekey' => $privkey,
- 'remoteip' => $remoteip,
- 'challenge' => $challenge,
- 'response' => $response
- ) + $extra_params
- );
-
- $answers = explode ("\n", $response [1]);
- $recaptcha_response = new ReCaptchaResponse();
-
- if (trim ($answers [0]) == 'true') {
- $recaptcha_response->is_valid = true;
- }
- else {
- $recaptcha_response->is_valid = false;
- $recaptcha_response->error = $answers [1];
- }
- return $recaptcha_response;
-
-}
-
-/**
- * gets a URL where the user can sign up for reCAPTCHA. If your application
- * has a configuration page where you enter a key, you should provide a link
- * using this function.
- * @param string $domain The domain where the page is hosted
- * @param string $appname The name of your application
- */
-function recaptcha_get_signup_url ($domain = null, $appname = null) {
- return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname));
-}
-
-function _recaptcha_aes_pad($val) {
- $block_size = 16;
- $numpad = $block_size - (strlen ($val) % $block_size);
- return str_pad($val, strlen ($val) + $numpad, chr($numpad));
-}
-
-/* Mailhide related code */
-
-function _recaptcha_aes_encrypt($val,$ky) {
- if (! function_exists ("mcrypt_encrypt")) {
- die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.");
- }
- $mode=MCRYPT_MODE_CBC;
- $enc=MCRYPT_RIJNDAEL_128;
- $val=_recaptcha_aes_pad($val);
- return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
-}
-
-
-function _recaptcha_mailhide_urlbase64 ($x) {
- return strtr(base64_encode ($x), '+/', '-_');
-}
-
-/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
-function recaptcha_mailhide_url($pubkey, $privkey, $email) {
- if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {
- die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
- "you can do so at http://www.google.com/recaptcha/mailhide/apikey");
- }
-
-
- $ky = pack('H*', $privkey);
- $cryptmail = _recaptcha_aes_encrypt ($email, $ky);
-
- return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);
-}
-
-/**
- * gets the parts of the email to expose to the user.
- * eg, given johndoe@example,com return ["john", "example.com"].
- * the email is then displayed as john...@example.com
- */
-function _recaptcha_mailhide_email_parts ($email) {
- $arr = preg_split("/@/", $email );
-
- if (strlen ($arr[0]) <= 4) {
- $arr[0] = substr ($arr[0], 0, 1);
- } else if (strlen ($arr[0]) <= 6) {
- $arr[0] = substr ($arr[0], 0, 3);
- } else {
- $arr[0] = substr ($arr[0], 0, 4);
- }
- return $arr;
-}
-
-/**
- * Gets html to display an email address given a public an private key.
- * to get a key, go to:
- *
- * http://www.google.com/recaptcha/mailhide/apikey
- */
-function recaptcha_mailhide_html($pubkey, $privkey, $email) {
- $emailparts = _recaptcha_mailhide_email_parts ($email);
- $url = recaptcha_mailhide_url ($pubkey, $privkey, $email);
-
- return htmlentities($emailparts[0]) . "...@" . htmlentities ($emailparts [1]);
-
-}
-
-
diff --git a/plugins/_depricated/recaptcha/templates/PluginLoginReCaptchaGroup.html b/plugins/_depricated/recaptcha/templates/PluginLoginReCaptchaGroup.html
deleted file mode 100644
index 9af9b8aec..000000000
--- a/plugins/_depricated/recaptcha/templates/PluginLoginReCaptchaGroup.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Api.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Api.php
index 844261c78..4ddfd8c3a 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/Api.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Api.php
@@ -172,7 +172,7 @@ class Api
}
}
- protected static function Version() : string
+ public static function Version() : string
{
return APP_VERSION;
}
diff --git a/tasks/config.js b/tasks/config.js
index bea665628..718535547 100644
--- a/tasks/config.js
+++ b/tasks/config.js
@@ -64,10 +64,6 @@ config.paths.css = {
'vendors/Progress.js/minified/progressjs.min.css',
'dev/Styles/_progressjs.css'
]
- },
- social: {
- name: 'social.css',
- src: ['vendors/fontastic/styles.css', 'dev/Styles/_social.css']
}
};
diff --git a/tasks/css.js b/tasks/css.js
index 5a2d3e1ff..9c7b9e681 100644
--- a/tasks/css.js
+++ b/tasks/css.js
@@ -41,19 +41,6 @@ const cssMainBuild = () => {
.pipe(livereload());
};
-const cssSocialBuild = () => {
- const autoprefixer = require('gulp-autoprefixer'),
- src = config.paths.css.social.src;
- return gulp
- .src(src)
- .pipe(expect.real({ errorOnFailure: true }, src))
- .pipe(concat(config.paths.css.social.name))
- .pipe(autoprefixer())
- .pipe(replace(/\.\.\/(img|images|fonts|svg)\//g, '$1/'))
- .pipe(eol('\n', true))
- .pipe(gulp.dest(config.paths.staticCSS));
-};
-
const cssMainMin = () => {
const cleanCss = require('gulp-clean-css');
return gulp
@@ -64,18 +51,8 @@ const cssMainMin = () => {
.pipe(gulp.dest(config.paths.staticCSS));
};
-const cssSocialMin = () => {
- const cleanCss = require('gulp-clean-css');
- return gulp
- .src(config.paths.staticCSS + config.paths.css.social.name)
- .pipe(cleanCss())
- .pipe(rename({ suffix: '.min' }))
- .pipe(eol('\n', true))
- .pipe(gulp.dest(config.paths.staticCSS));
-};
-
-const cssBuild = gulp.parallel(cssMainBuild, cssSocialBuild);
-const cssMin = gulp.parallel(cssMainMin, cssSocialMin);
+const cssBuild = gulp.parallel(cssMainBuild);
+const cssMin = gulp.parallel(cssMainMin);
const cssLint = (done) => done();
diff --git a/tasks/owncloud.js b/tasks/owncloud.js
deleted file mode 100644
index 48ae9edd5..000000000
--- a/tasks/owncloud.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under AGPL 3 */
-/* eslint-disable consistent-return */
-
-const gulp = require('gulp');
-const fs = require('node-fs');
-
-const pkg = require('../package.json');
-const { config } = require('./config');
-const { copy, zip, del } = require('./common');
-const { rainloopBuild } = require('./rainloop');
-
-const owncloudCopy = () => {
- const versionFull = pkg.ownCloudVersion,
- dist = config.releasesPath + '/owncloud/' + versionFull + '/src/';
-
- fs.mkdirSync(dist, '0777', true);
- fs.mkdirSync(dist + 'rainloop', '0777', true);
-
- return gulp
- .src('build/owncloud/rainloop-app/**/*', { base: 'build/owncloud/rainloop-app/' })
- .pipe(gulp.dest(dist + 'rainloop'));
-};
-
-const owncloudCopyRainLoop = () => {
- const versionFull = pkg.ownCloudVersion,
- dist = config.releasesPath + '/owncloud/' + versionFull + '/src/rainloop/';
- if (config.rainloopBuilded && config.destPath) {
- return gulp.src(config.destPath + '/src/**/*', { base: config.destPath + '/src/' }).pipe(gulp.dest(dist + 'app/'));
- }
-
- return true;
-};
-
-const owncloudCopyRainLoopClean = (done) => {
- if (config.cleanPath) {
- return del(config.cleanPath);
- }
- done();
-};
-
-const owncloudSetup = (done) => {
- const versionFull = pkg.ownCloudVersion,
- dist = config.releasesPath + '/owncloud/' + versionFull + '/src/';
- fs.writeFileSync(
- dist + 'rainloop/appinfo/info.xml',
- fs
- .readFileSync(dist + 'rainloop/appinfo/info.xml', 'utf8')
- .replace('0.0', '' + versionFull + '')
- .replace(
- '',
- '' + (config.community ? 'AGPLv3' : 'RainLoop Software License') + ''
- )
- );
-
- fs.writeFileSync(dist + 'rainloop/appinfo/version', versionFull);
- fs.writeFileSync(dist + 'rainloop/VERSION', versionFull);
-
- config.destPath = config.releasesPath + '/owncloud/' + versionFull + '/';
- config.cleanPath = dist;
- config.zipSrcPath = dist;
- config.zipFile = 'rainloop-owncloud-app-' + (config.community ? '' : 'standard-') + versionFull + '.zip';
- config.zipFileShort = 'rainloop' + (config.community ? '' : '-standard') + '.zip';
-
- done();
-};
-
-const owncloudZip = (done) => {
- if (config.destPath && config.zipSrcPath && config.zipFile) {
- return zip(config.zipSrcPath, config.destPath, config.zipFile);
- }
-
- done();
-};
-
-const owncloudClean = (done) => {
- if (config.cleanPath) {
- return del(config.cleanPath);
- }
-
- done();
-};
-
-const owncloudShortname = (done) => {
- copy(config.destPath + config.zipFile, config.destPath + config.zipFileShort, done);
-};
-
-exports.owncloud = gulp.series(
- owncloudCopy,
- rainloopBuild,
- owncloudCopyRainLoop,
- owncloudCopyRainLoopClean,
- owncloudSetup,
- owncloudZip,
- owncloudClean,
- owncloudShortname
-);
diff --git a/vendors/modernizr/config.json b/vendors/modernizr/config.json
deleted file mode 100644
index cd532988f..000000000
--- a/vendors/modernizr/config.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "minify": false,
- "options": [
- "setClasses"
- ],
- "feature-detects": [
- "test/css/animations",
- "test/css/backgroundsize",
- "test/css/boxshadow",
- "test/css/rgba",
- "test/css/textshadow",
- "test/css/transitions"
- ]
-}
\ No newline at end of file
diff --git a/vendors/modernizr/modernizr-custom.js b/vendors/modernizr/modernizr-custom.js
deleted file mode 100644
index 059a6194a..000000000
--- a/vendors/modernizr/modernizr-custom.js
+++ /dev/null
@@ -1,905 +0,0 @@
-/*!
- * modernizr v3.3.1
- * Build http://modernizr.com/download?-backgroundsize-boxshadow-cssanimations-csstransitions-rgba-textshadow-setclasses-dontmin
- *
- * Copyright (c)
- * Faruk Ates
- * Paul Irish
- * Alex Sexton
- * Ryan Seddon
- * Patrick Kettner
- * Stu Cox
- * Richard Herrera
-
- * MIT License
- */
-
-/*
- * Modernizr tests which native CSS3 and HTML5 features are available in the
- * current UA and makes the results available to you in two ways: as properties on
- * a global `Modernizr` object, and as classes on the `` element. This
- * information allows you to progressively enhance your pages with a granular level
- * of control over the experience.
-*/
-
-;(function(window, document, undefined){
- var classes = [];
-
-
- var tests = [];
-
-
- /**
- *
- * ModernizrProto is the constructor for Modernizr
- *
- * @class
- * @access public
- */
-
- var ModernizrProto = {
- // The current version, dummy
- _version: '3.3.1',
-
- // Any settings that don't work as separate modules
- // can go in here as configuration.
- _config: {
- 'classPrefix': '',
- 'enableClasses': true,
- 'enableJSClass': true,
- 'usePrefixes': true
- },
-
- // Queue of tests
- _q: [],
-
- // Stub these for people who are listening
- on: function(test, cb) {
- // I don't really think people should do this, but we can
- // safe guard it a bit.
- // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests.
- // This is in case people listen to synchronous tests. I would leave it out,
- // but the code to *disallow* sync tests in the real version of this
- // function is actually larger than this.
- var self = this;
- setTimeout(function() {
- cb(self[test]);
- }, 0);
- },
-
- addTest: function(name, fn, options) {
- tests.push({name: name, fn: fn, options: options});
- },
-
- addAsyncTest: function(fn) {
- tests.push({name: null, fn: fn});
- }
- };
-
-
-
- // Fake some of Object.create so we can force non test results to be non "own" properties.
- var Modernizr = function() {};
- Modernizr.prototype = ModernizrProto;
-
- // Leak modernizr globally when you `require` it rather than force it here.
- // Overwrite name so constructor name is nicer :D
- Modernizr = new Modernizr();
-
-
-
- /**
- * is returns a boolean if the typeof an obj is exactly type.
- *
- * @access private
- * @function is
- * @param {*} obj - A thing we want to check the type of
- * @param {string} type - A string to compare the typeof against
- * @returns {boolean}
- */
-
- function is(obj, type) {
- return typeof obj === type;
- }
- ;
-
- /**
- * Run through all tests and detect their support in the current UA.
- *
- * @access private
- */
-
- function testRunner() {
- var featureNames;
- var feature;
- var aliasIdx;
- var result;
- var nameIdx;
- var featureName;
- var featureNameSplit;
-
- for (var featureIdx in tests) {
- if (tests.hasOwnProperty(featureIdx)) {
- featureNames = [];
- feature = tests[featureIdx];
- // run the test, throw the return value into the Modernizr,
- // then based on that boolean, define an appropriate className
- // and push it into an array of classes we'll join later.
- //
- // If there is no name, it's an 'async' test that is run,
- // but not directly added to the object. That should
- // be done with a post-run addTest call.
- if (feature.name) {
- featureNames.push(feature.name.toLowerCase());
-
- if (feature.options && feature.options.aliases && feature.options.aliases.length) {
- // Add all the aliases into the names list
- for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) {
- featureNames.push(feature.options.aliases[aliasIdx].toLowerCase());
- }
- }
- }
-
- // Run the test, or use the raw value if it's not a function
- result = is(feature.fn, 'function') ? feature.fn() : feature.fn;
-
-
- // Set each of the names on the Modernizr object
- for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) {
- featureName = featureNames[nameIdx];
- // Support dot properties as sub tests. We don't do checking to make sure
- // that the implied parent tests have been added. You must call them in
- // order (either in the test, or make the parent test a dependency).
- //
- // Cap it to TWO to make the logic simple and because who needs that kind of subtesting
- // hashtag famous last words
- featureNameSplit = featureName.split('.');
-
- if (featureNameSplit.length === 1) {
- Modernizr[featureNameSplit[0]] = result;
- } else {
- // cast to a Boolean, if not one already
- /* jshint -W053 */
- if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
- Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
- }
-
- Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result;
- }
-
- classes.push((result ? '' : 'no-') + featureNameSplit.join('-'));
- }
- }
- }
- }
- ;
-
- /**
- * docElement is a convenience wrapper to grab the root element of the document
- *
- * @access private
- * @returns {HTMLElement|SVGElement} The root element of the document
- */
-
- var docElement = document.documentElement;
-
-
- /**
- * A convenience helper to check if the document we are running in is an SVG document
- *
- * @access private
- * @returns {boolean}
- */
-
- var isSVG = docElement.nodeName.toLowerCase() === 'svg';
-
-
- /**
- * setClasses takes an array of class names and adds them to the root element
- *
- * @access private
- * @function setClasses
- * @param {string[]} classes - Array of class names
- */
-
- // Pass in an and array of class names, e.g.:
- // ['no-webp', 'borderradius', ...]
- function setClasses(classes) {
- var className = docElement.className;
- var classPrefix = Modernizr._config.classPrefix || '';
-
- if (isSVG) {
- className = className.baseVal;
- }
-
- // Change `no-js` to `js` (independently of the `enableClasses` option)
- // Handle classPrefix on this too
- if (Modernizr._config.enableJSClass) {
- var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)');
- className = className.replace(reJS, '$1' + classPrefix + 'js$2');
- }
-
- if (Modernizr._config.enableClasses) {
- // Add the new classes
- className += ' ' + classPrefix + classes.join(' ' + classPrefix);
- isSVG ? docElement.className.baseVal = className : docElement.className = className;
- }
-
- }
-
- ;
-
- /**
- * createElement is a convenience wrapper around document.createElement. Since we
- * use createElement all over the place, this allows for (slightly) smaller code
- * as well as abstracting away issues with creating elements in contexts other than
- * HTML documents (e.g. SVG documents).
- *
- * @access private
- * @function createElement
- * @returns {HTMLElement|SVGElement} An HTML or SVG element
- */
-
- function createElement() {
- if (typeof document.createElement !== 'function') {
- // This is the case in IE7, where the type of createElement is "object".
- // For this reason, we cannot call apply() as Object is not a Function.
- return document.createElement(arguments[0]);
- } else if (isSVG) {
- return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]);
- } else {
- return document.createElement.apply(document, arguments);
- }
- }
-
- ;
-/*!
-{
- "name": "CSS rgba",
- "caniuse": "css3-colors",
- "property": "rgba",
- "tags": ["css"],
- "notes": [{
- "name": "CSSTricks Tutorial",
- "href": "https://css-tricks.com/rgba-browser-support/"
- }]
-}
-!*/
-
- Modernizr.addTest('rgba', function() {
- var style = createElement('a').style;
- style.cssText = 'background-color:rgba(150,255,150,.5)';
-
- return ('' + style.backgroundColor).indexOf('rgba') > -1;
- });
-
-
-
- /**
- * contains checks to see if a string contains another string
- *
- * @access private
- * @function contains
- * @param {string} str - The string we want to check for substrings
- * @param {string} substr - The substring we want to search the first string for
- * @returns {boolean}
- */
-
- function contains(str, substr) {
- return !!~('' + str).indexOf(substr);
- }
-
- ;
-
- /**
- * cssToDOM takes a kebab-case string and converts it to camelCase
- * e.g. box-sizing -> boxSizing
- *
- * @access private
- * @function cssToDOM
- * @param {string} name - String name of kebab-case prop we want to convert
- * @returns {string} The camelCase version of the supplied name
- */
-
- function cssToDOM(name) {
- return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) {
- return m1 + m2.toUpperCase();
- }).replace(/^-/, '');
- }
- ;
-
- /**
- * If the browsers follow the spec, then they would expose vendor-specific style as:
- * elem.style.WebkitBorderRadius
- * instead of something like the following, which would be technically incorrect:
- * elem.style.webkitBorderRadius
-
- * Webkit ghosts their properties in lowercase but Opera & Moz do not.
- * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
- * erik.eae.net/archives/2008/03/10/21.48.10/
-
- * More here: github.com/Modernizr/Modernizr/issues/issue/21
- *
- * @access private
- * @returns {string} The string representing the vendor-specific style properties
- */
-
- var omPrefixes = 'Moz O ms Webkit';
-
-
- var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []);
- ModernizrProto._cssomPrefixes = cssomPrefixes;
-
-
- /**
- * List of JavaScript DOM values used for tests
- *
- * @memberof Modernizr
- * @name Modernizr._domPrefixes
- * @optionName Modernizr._domPrefixes
- * @optionProp domPrefixes
- * @access public
- * @example
- *
- * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather
- * than kebab-case properties, all properties are their Capitalized variant
- *
- * ```js
- * Modernizr._domPrefixes === [ "Moz", "O", "ms", "Webkit" ];
- * ```
- */
-
- var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []);
- ModernizrProto._domPrefixes = domPrefixes;
-
-
- /**
- * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill.
- *
- * @access private
- * @function fnBind
- * @param {function} fn - a function you want to change `this` reference to
- * @param {object} that - the `this` you want to call the function with
- * @returns {function} The wrapped version of the supplied function
- */
-
- function fnBind(fn, that) {
- return function() {
- return fn.apply(that, arguments);
- };
- }
-
- ;
-
- /**
- * testDOMProps is a generic DOM property test; if a browser supports
- * a certain property, it won't return undefined for it.
- *
- * @access private
- * @function testDOMProps
- * @param {array.} props - An array of properties to test for
- * @param {object} obj - An object or Element you want to use to test the parameters again
- * @param {boolean|object} elem - An Element to bind the property lookup again. Use `false` to prevent the check
- */
- function testDOMProps(props, obj, elem) {
- var item;
-
- for (var i in props) {
- if (props[i] in obj) {
-
- // return the property name as a string
- if (elem === false) {
- return props[i];
- }
-
- item = obj[props[i]];
-
- // let's bind a function
- if (is(item, 'function')) {
- // bind to obj unless overriden
- return fnBind(item, elem || obj);
- }
-
- // return the unbound function or obj or value
- return item;
- }
- }
- return false;
- }
-
- ;
-
- /**
- * Create our "modernizr" element that we do most feature tests on.
- *
- * @access private
- */
-
- var modElem = {
- elem: createElement('modernizr')
- };
-
- // Clean up this element
- Modernizr._q.push(function() {
- delete modElem.elem;
- });
-
-
-
- var mStyle = {
- style: modElem.elem.style
- };
-
- // kill ref for gc, must happen before mod.elem is removed, so we unshift on to
- // the front of the queue.
- Modernizr._q.unshift(function() {
- delete mStyle.style;
- });
-
-
-
- /**
- * domToCSS takes a camelCase string and converts it to kebab-case
- * e.g. boxSizing -> box-sizing
- *
- * @access private
- * @function domToCSS
- * @param {string} name - String name of camelCase prop we want to convert
- * @returns {string} The kebab-case version of the supplied name
- */
-
- function domToCSS(name) {
- return name.replace(/([A-Z])/g, function(str, m1) {
- return '-' + m1.toLowerCase();
- }).replace(/^ms-/, '-ms-');
- }
- ;
-
- /**
- * getBody returns the body of a document, or an element that can stand in for
- * the body if a real body does not exist
- *
- * @access private
- * @function getBody
- * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an
- * artificially created element that stands in for the body
- */
-
- function getBody() {
- // After page load injecting a fake body doesn't work so check if body exists
- var body = document.body;
-
- if (!body) {
- // Can't use the real body create a fake one.
- body = createElement(isSVG ? 'svg' : 'body');
- body.fake = true;
- }
-
- return body;
- }
-
- ;
-
- /**
- * injectElementWithStyles injects an element with style element and some CSS rules
- *
- * @access private
- * @function injectElementWithStyles
- * @param {string} rule - String representing a css rule
- * @param {function} callback - A function that is used to test the injected element
- * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
- * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes
- * @returns {boolean}
- */
-
- function injectElementWithStyles(rule, callback, nodes, testnames) {
- var mod = 'modernizr';
- var style;
- var ret;
- var node;
- var docOverflow;
- var div = createElement('div');
- var body = getBody();
-
- if (parseInt(nodes, 10)) {
- // In order not to give false positives we create a node for each test
- // This also allows the method to scale for unspecified uses
- while (nodes--) {
- node = createElement('div');
- node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
- div.appendChild(node);
- }
- }
-
- style = createElement('style');
- style.type = 'text/css';
- style.id = 's' + mod;
-
- // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
- // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
- (!body.fake ? div : body).appendChild(style);
- body.appendChild(div);
-
- if (style.styleSheet) {
- style.styleSheet.cssText = rule;
- } else {
- style.appendChild(document.createTextNode(rule));
- }
- div.id = mod;
-
- if (body.fake) {
- //avoid crashing IE8, if background image is used
- body.style.background = '';
- //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
- body.style.overflow = 'hidden';
- docOverflow = docElement.style.overflow;
- docElement.style.overflow = 'hidden';
- docElement.appendChild(body);
- }
-
- ret = callback(div, rule);
- // If this is done after page load we don't want to remove the body so check if body exists
- if (body.fake) {
- body.parentNode.removeChild(body);
- docElement.style.overflow = docOverflow;
- // Trigger layout so kinetic scrolling isn't disabled in iOS6+
- docElement.offsetHeight;
- } else {
- div.parentNode.removeChild(div);
- }
-
- return !!ret;
-
- }
-
- ;
-
- /**
- * nativeTestProps allows for us to use native feature detection functionality if available.
- * some prefixed form, or false, in the case of an unsupported rule
- *
- * @access private
- * @function nativeTestProps
- * @param {array} props - An array of property names
- * @param {string} value - A string representing the value we want to check via @supports
- * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise
- */
-
- // Accepts a list of property names and a single value
- // Returns `undefined` if native detection not available
- function nativeTestProps(props, value) {
- var i = props.length;
- // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface
- if ('CSS' in window && 'supports' in window.CSS) {
- // Try every prefixed variant of the property
- while (i--) {
- if (window.CSS.supports(domToCSS(props[i]), value)) {
- return true;
- }
- }
- return false;
- }
- // Otherwise fall back to at-rule (for Opera 12.x)
- else if ('CSSSupportsRule' in window) {
- // Build a condition string for every prefixed variant
- var conditionText = [];
- while (i--) {
- conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')');
- }
- conditionText = conditionText.join(' or ');
- return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) {
- return getComputedStyle(node, null).position == 'absolute';
- });
- }
- return undefined;
- }
- ;
-
- // testProps is a generic CSS / DOM property test.
-
- // In testing support for a given CSS property, it's legit to test:
- // `elem.style[styleName] !== undefined`
- // If the property is supported it will return an empty string,
- // if unsupported it will return undefined.
-
- // We'll take advantage of this quick test and skip setting a style
- // on our modernizr element, but instead just testing undefined vs
- // empty string.
-
- // Property names can be provided in either camelCase or kebab-case.
-
- function testProps(props, prefixed, value, skipValueTest) {
- skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest;
-
- // Try native detect first
- if (!is(value, 'undefined')) {
- var result = nativeTestProps(props, value);
- if (!is(result, 'undefined')) {
- return result;
- }
- }
-
- // Otherwise do it properly
- var afterInit, i, propsLength, prop, before;
-
- // If we don't have a style element, that means we're running async or after
- // the core tests, so we'll need to create our own elements to use
-
- // inside of an SVG element, in certain browsers, the `style` element is only
- // defined for valid tags. Therefore, if `modernizr` does not have one, we
- // fall back to a less used element and hope for the best.
- var elems = ['modernizr', 'tspan'];
- while (!mStyle.style) {
- afterInit = true;
- mStyle.modElem = createElement(elems.shift());
- mStyle.style = mStyle.modElem.style;
- }
-
- // Delete the objects if we created them.
- function cleanElems() {
- if (afterInit) {
- delete mStyle.style;
- delete mStyle.modElem;
- }
- }
-
- propsLength = props.length;
- for (i = 0; i < propsLength; i++) {
- prop = props[i];
- before = mStyle.style[prop];
-
- if (contains(prop, '-')) {
- prop = cssToDOM(prop);
- }
-
- if (mStyle.style[prop] !== undefined) {
-
- // If value to test has been passed in, do a set-and-check test.
- // 0 (integer) is a valid property value, so check that `value` isn't
- // undefined, rather than just checking it's truthy.
- if (!skipValueTest && !is(value, 'undefined')) {
-
- // Needs a try catch block because of old IE. This is slow, but will
- // be avoided in most cases because `skipValueTest` will be used.
- try {
- mStyle.style[prop] = value;
- } catch (e) {}
-
- // If the property value has changed, we assume the value used is
- // supported. If `value` is empty string, it'll fail here (because
- // it hasn't changed), which matches how browsers have implemented
- // CSS.supports()
- if (mStyle.style[prop] != before) {
- cleanElems();
- return prefixed == 'pfx' ? prop : true;
- }
- }
- // Otherwise just return true, or the property name if this is a
- // `prefixed()` call
- else {
- cleanElems();
- return prefixed == 'pfx' ? prop : true;
- }
- }
- }
- cleanElems();
- return false;
- }
-
- ;
-
- /**
- * testProp() investigates whether a given style property is recognized
- * Property names can be provided in either camelCase or kebab-case.
- *
- * @memberof Modernizr
- * @name Modernizr.testProp
- * @access public
- * @optionName Modernizr.testProp()
- * @optionProp testProp
- * @function testProp
- * @param {string} prop - Name of the CSS property to check
- * @param {string} [value] - Name of the CSS value to check
- * @param {boolean} [useValue] - Whether or not to check the value if @supports isn't supported
- * @returns {boolean}
- * @example
- *
- * Just like [testAllProps](#modernizr-testallprops), only it does not check any vendor prefixed
- * version of the string.
- *
- * Note that the property name must be provided in camelCase (e.g. boxSizing not box-sizing)
- *
- * ```js
- * Modernizr.testProp('pointerEvents') // true
- * ```
- *
- * You can also provide a value as an optional second argument to check if a
- * specific value is supported
- *
- * ```js
- * Modernizr.testProp('pointerEvents', 'none') // true
- * Modernizr.testProp('pointerEvents', 'penguin') // false
- * ```
- */
-
- var testProp = ModernizrProto.testProp = function(prop, value, useValue) {
- return testProps([prop], undefined, value, useValue);
- };
-
-/*!
-{
- "name": "CSS textshadow",
- "property": "textshadow",
- "caniuse": "css-textshadow",
- "tags": ["css"],
- "knownBugs": ["FF3.0 will false positive on this test"]
-}
-!*/
-
- Modernizr.addTest('textshadow', testProp('textShadow', '1px 1px'));
-
-
- /**
- * testPropsAll tests a list of DOM properties we want to check against.
- * We specify literally ALL possible (known and/or likely) properties on
- * the element including the non-vendor prefixed one, for forward-
- * compatibility.
- *
- * @access private
- * @function testPropsAll
- * @param {string} prop - A string of the property to test for
- * @param {string|object} [prefixed] - An object to check the prefixed properties on. Use a string to skip
- * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against
- * @param {string} [value] - A string of a css value
- * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set
- */
- function testPropsAll(prop, prefixed, elem, value, skipValueTest) {
-
- var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
- props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
-
- // did they call .prefixed('boxSizing') or are we just testing a prop?
- if (is(prefixed, 'string') || is(prefixed, 'undefined')) {
- return testProps(props, prefixed, value, skipValueTest);
-
- // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
- } else {
- props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
- return testDOMProps(props, prefixed, elem);
- }
- }
-
- // Modernizr.testAllProps() investigates whether a given style property,
- // or any of its vendor-prefixed variants, is recognized
- //
- // Note that the property names must be provided in the camelCase variant.
- // Modernizr.testAllProps('boxSizing')
- ModernizrProto.testAllProps = testPropsAll;
-
-
-
- /**
- * testAllProps determines whether a given CSS property is supported in the browser
- *
- * @memberof Modernizr
- * @name Modernizr.testAllProps
- * @optionName Modernizr.testAllProps()
- * @optionProp testAllProps
- * @access public
- * @function testAllProps
- * @param {string} prop - String naming the property to test (either camelCase or kebab-case)
- * @param {string} [value] - String of the value to test
- * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection
- * @example
- *
- * testAllProps determines whether a given CSS property, in some prefixed form,
- * is supported by the browser.
- *
- * ```js
- * testAllProps('boxSizing') // true
- * ```
- *
- * It can optionally be given a CSS value in string form to test if a property
- * value is valid
- *
- * ```js
- * testAllProps('display', 'block') // true
- * testAllProps('display', 'penguin') // false
- * ```
- *
- * A boolean can be passed as a third parameter to skip the value check when
- * native detection (@supports) isn't available.
- *
- * ```js
- * testAllProps('shapeOutside', 'content-box', true);
- * ```
- */
-
- function testAllProps(prop, value, skipValueTest) {
- return testPropsAll(prop, undefined, undefined, value, skipValueTest);
- }
- ModernizrProto.testAllProps = testAllProps;
-
-/*!
-{
- "name": "CSS Animations",
- "property": "cssanimations",
- "caniuse": "css-animation",
- "polyfills": ["transformie", "csssandpaper"],
- "tags": ["css"],
- "warnings": ["Android < 4 will pass this test, but can only animate a single property at a time"],
- "notes": [{
- "name" : "Article: 'Dispelling the Android CSS animation myths'",
- "href": "https://goo.gl/OGw5Gm"
- }]
-}
-!*/
-/* DOC
-Detects whether or not elements can be animated using CSS
-*/
-
- Modernizr.addTest('cssanimations', testAllProps('animationName', 'a', true));
-
-/*!
-{
- "name": "Background Size",
- "property": "backgroundsize",
- "tags": ["css"],
- "knownBugs": ["This will false positive in Opera Mini - https://github.com/Modernizr/Modernizr/issues/396"],
- "notes": [{
- "name": "Related Issue",
- "href": "https://github.com/Modernizr/Modernizr/issues/396"
- }]
-}
-!*/
-
- Modernizr.addTest('backgroundsize', testAllProps('backgroundSize', '100%', true));
-
-/*!
-{
- "name": "CSS Transitions",
- "property": "csstransitions",
- "caniuse": "css-transitions",
- "tags": ["css"]
-}
-!*/
-
- Modernizr.addTest('csstransitions', testAllProps('transition', 'all', true));
-
-/*!
-{
- "name": "Box Shadow",
- "property": "boxshadow",
- "caniuse": "css-boxshadow",
- "tags": ["css"],
- "knownBugs": [
- "WebOS false positives on this test.",
- "The Kindle Silk browser false positives"
- ]
-}
-!*/
-
- Modernizr.addTest('boxshadow', testAllProps('boxShadow', '1px 1px', true));
-
-
- // Run each test
- testRunner();
-
- // Remove the "no-js" class if it exists
- setClasses(classes);
-
- delete ModernizrProto.addTest;
- delete ModernizrProto.addAsyncTest;
-
- // Run the things that are supposed to run after the tests
- for (var i = 0; i < Modernizr._q.length; i++) {
- Modernizr._q[i]();
- }
-
- // Leak Modernizr namespace
- window.Modernizr = Modernizr;
-
-
-;
-
-})(window, document);
\ No newline at end of file