diff --git a/build/owncloud/rainloop-app/INSTALL b/build/owncloud/rainloop-app/INSTALL deleted file mode 100755 index 55e0ad3ee..000000000 --- a/build/owncloud/rainloop-app/INSTALL +++ /dev/null @@ -1,28 +0,0 @@ -************************************************************************ -* -* ownCloud/Nextcloud - RainLoop Webmail package -* -* @author RainLoop Team -* @copyright 2019 RainLoop Team -* -* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud -* -************************************************************************ - -REQUIREMENTS: -- ownCloud version 6 or higher -or -- Nextcloud version 10 or higher - - -INSTALL: -- Unpack the RainLoop Webmail application package in the apps directory of your ownCloud or Nextcloud instance -- Make sure the rights are appropriately set - -CONFIGURATION: -- ownCloud: - 1) In the Apps > Enable 'RainLoop' plugin - 2) In the Settings > Personal > Type your email server login and password -- Nextcloud: - 1) In the Apps > Enable 'RainLoop' plugin after checking 'Enable experimental apps' - 2) In the Settings > Personal > Type your email server login and password diff --git a/build/owncloud/rainloop-app/VERSION b/build/owncloud/rainloop-app/VERSION deleted file mode 100644 index 171538eb0..000000000 --- a/build/owncloud/rainloop-app/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.0 \ No newline at end of file diff --git a/build/owncloud/rainloop-app/admin.php b/build/owncloud/rainloop-app/admin.php deleted file mode 100644 index 492e848cf..000000000 --- a/build/owncloud/rainloop-app/admin.php +++ /dev/null @@ -1,18 +0,0 @@ -assign('rainloop-admin-panel-link', OC_RainLoop_Helper::getAppUrl().'?admin'); -$oTemplate->assign('rainloop-autologin', OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false)); -return $oTemplate->fetchPage(); diff --git a/build/owncloud/rainloop-app/ajax/admin.php b/build/owncloud/rainloop-app/ajax/admin.php deleted file mode 100644 index a8343c23f..000000000 --- a/build/owncloud/rainloop-app/ajax/admin.php +++ /dev/null @@ -1,35 +0,0 @@ - 'Invalid Argument(s)')); - return false; -} - -sleep(1); -OCP\JSON::success(array('Message' => 'Saved successfully')); -return true; diff --git a/build/owncloud/rainloop-app/ajax/personal.php b/build/owncloud/rainloop-app/ajax/personal.php deleted file mode 100644 index 02252b750..000000000 --- a/build/owncloud/rainloop-app/ajax/personal.php +++ /dev/null @@ -1,46 +0,0 @@ - 'Invalid argument(s)', 'Email' => $sEmail)); - return false; -} - -sleep(1); -OCP\JSON::success(array('Message' => 'Saved successfully', 'Email' => $sEmail)); -return true; diff --git a/build/owncloud/rainloop-app/app.php b/build/owncloud/rainloop-app/app.php deleted file mode 100644 index 94569d475..000000000 --- a/build/owncloud/rainloop-app/app.php +++ /dev/null @@ -1,36 +0,0 @@ - 'rainloop_index', - 'order' => 10, - 'href' => OCP\Util::linkToRoute('rainloop_index'), - 'icon' => OCP\Util::imagePath('rainloop', 'mail.png'), - 'name' => 'Email' -)); - diff --git a/build/owncloud/rainloop-app/appinfo/info.xml b/build/owncloud/rainloop-app/appinfo/info.xml deleted file mode 100644 index a71679ce7..000000000 --- a/build/owncloud/rainloop-app/appinfo/info.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - rainloop - RainLoop - RainLoop Webmail - Simple, modern and fast web-based email client. - 0.0 - - RainLoop Team - 6.0 - 165254 - - - - - - tools - https://www.rainloop.net/ - https://github.com/RainLoop/rainloop-webmail/issues - diff --git a/build/owncloud/rainloop-app/appinfo/routes.php b/build/owncloud/rainloop-app/appinfo/routes.php deleted file mode 100644 index 7716e0a74..000000000 --- a/build/owncloud/rainloop-app/appinfo/routes.php +++ /dev/null @@ -1,13 +0,0 @@ -create('rainloop_index', '/') - ->actionInclude('rainloop/index.php'); - -$this->create('rainloop_app', '/app/') - ->actionInclude('rainloop/app.php'); - -$this->create('rainloop_ajax_personal', 'ajax/personal.php') - ->actionInclude('rainloop/ajax/personal.php'); - -$this->create('rainloop_ajax_admin', 'ajax/admin.php') - ->actionInclude('rainloop/ajax/admin.php'); diff --git a/build/owncloud/rainloop-app/css/style.css b/build/owncloud/rainloop-app/css/style.css deleted file mode 100644 index 462226253..000000000 --- a/build/owncloud/rainloop-app/css/style.css +++ /dev/null @@ -1,6 +0,0 @@ -/* -Empty style sheet! -Only needed to give you the opportunity to theme the owncloud part -of the rainloop app with the theming system integrated in ownCoud -if the rainloop app is activated. -*/ \ No newline at end of file diff --git a/build/owncloud/rainloop-app/img/logo-64x64.png b/build/owncloud/rainloop-app/img/logo-64x64.png deleted file mode 100755 index ce1dd1a88..000000000 Binary files a/build/owncloud/rainloop-app/img/logo-64x64.png and /dev/null differ diff --git a/build/owncloud/rainloop-app/img/mail.png b/build/owncloud/rainloop-app/img/mail.png deleted file mode 100755 index 285cabee3..000000000 Binary files a/build/owncloud/rainloop-app/img/mail.png and /dev/null differ diff --git a/build/owncloud/rainloop-app/index.php b/build/owncloud/rainloop-app/index.php deleted file mode 100644 index da5c17717..000000000 --- a/build/owncloud/rainloop-app/index.php +++ /dev/null @@ -1,26 +0,0 @@ -assign('rainloop-iframe-url', OC_RainLoop_Helper::normalizeUrl($sUrl).'?OwnCloudAuth'); - -$oTemplate->printpage(); diff --git a/build/owncloud/rainloop-app/js/admin.js b/build/owncloud/rainloop-app/js/admin.js deleted file mode 100755 index f807fef41..000000000 --- a/build/owncloud/rainloop-app/js/admin.js +++ /dev/null @@ -1,12 +0,0 @@ - -/** - * ownCloud - RainLoop mail plugin - * - * @author RainLoop Team - * - * https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud - */ - -$(function() { - RainLoopFormHelper('#mail-rainloop-admin-form', 'admin.php'); -}); diff --git a/build/owncloud/rainloop-app/js/personal.js b/build/owncloud/rainloop-app/js/personal.js deleted file mode 100755 index 8211594c8..000000000 --- a/build/owncloud/rainloop-app/js/personal.js +++ /dev/null @@ -1,12 +0,0 @@ - -/** - * ownCloud - RainLoop mail plugin - * - * @author RainLoop Team - * - * https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud - */ - -$(function() { - RainLoopFormHelper('#mail-rainloop-personal-form', 'personal.php'); -}); diff --git a/build/owncloud/rainloop-app/js/rainloop.js b/build/owncloud/rainloop-app/js/rainloop.js deleted file mode 100755 index 944131171..000000000 --- a/build/owncloud/rainloop-app/js/rainloop.js +++ /dev/null @@ -1,76 +0,0 @@ - -function RainLoopFormHelper(sID, sAjaxFile, fCallback) -{ - try - { - var - oForm = $(sID), - oSubmit = $('#rainloop-save-button', oForm), - sSubmitValue = oSubmit.val(), - oDesc = oForm.find('.rainloop-result-desc') - ; - - oSubmit.click(function (oEvent) { - - var oDefAjax = null; - - oEvent.preventDefault(); - - oForm - .addClass('rainloop-ajax') - .removeClass('rainloop-error') - .removeClass('rainloop-success') - ; - - oDesc.text(''); - oSubmit.val('...'); - - oDefAjax = $.ajax({ - 'type': 'POST', - 'async': true, - 'url': OC.filePath('rainloop', 'ajax', sAjaxFile), - 'data': oForm.serialize(), - 'dataType': 'json', - 'global': true - }); - - oDefAjax.always(function (oData) { - - var bResult = false; - - oForm.removeClass('rainloop-ajax'); - oSubmit.val(sSubmitValue); - - if (oData) - { - bResult = 'success' === oData['status']; - if (oData['Message']) - { - oDesc.text(oData['Message']); - } - } - - if (bResult) - { - oForm.addClass('rainloop-success'); - } - else - { - oForm.addClass('rainloop-error'); - if ('' === oDesc.text()) - { - oDesc.text('Error'); - } - } - - if (fCallback) - { - fCallback(bResult, oData); - } - }); - - return false; - }); - } - catch(e) {} -} diff --git a/build/owncloud/rainloop-app/js/resize.js b/build/owncloud/rainloop-app/js/resize.js deleted file mode 100755 index 78476b611..000000000 --- a/build/owncloud/rainloop-app/js/resize.js +++ /dev/null @@ -1,26 +0,0 @@ -$(function (window, document) { - - var - buffer = 5, - ifr = document.getElementById('rliframe') - ; - - - function pageY(elem) { - return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop; - } - - function resizeIframe() { - var height = document.documentElement.clientHeight; - height -= pageY(ifr) + buffer; - height = (height < 0) ? 0 : height; - ifr.style.height = height + 'px'; - } - - if (ifr) - { - ifr.onload = resizeIframe; - window.onresize = resizeIframe; - } - -}(window, document)); \ No newline at end of file diff --git a/build/owncloud/rainloop-app/lib/RainLoopHelper.php b/build/owncloud/rainloop-app/lib/RainLoopHelper.php deleted file mode 100644 index e38f260fa..000000000 --- a/build/owncloud/rainloop-app/lib/RainLoopHelper.php +++ /dev/null @@ -1,352 +0,0 @@ -getSystemConfig()->getValue( - 'datadirectory', - isset(\OC::$SERVERROOT) ? \OC::$SERVERROOT.'/data' : '' - ) - ), '\\/').'/'; - } - - return @is_dir($sData) ? $sData.'rainloop-storage' : ''; - } - } - } - - public static function mimeContentType($filename) { - - $mime_types = array( - - 'woff' => 'application/font-woff', - - 'txt' => 'text/plain', - 'htm' => 'text/html', - 'html' => 'text/html', - 'php' => 'text/html', - 'css' => 'text/css', - 'js' => 'application/javascript', - 'json' => 'application/json', - 'xml' => 'application/xml', - 'swf' => 'application/x-shockwave-flash', - 'flv' => 'video/x-flv', - - // images - 'png' => 'image/png', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'gif' => 'image/gif', - 'bmp' => 'image/bmp', - 'ico' => 'image/vnd.microsoft.icon', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'svg' => 'image/svg+xml', - 'svgz' => 'image/svg+xml', - - // archives - 'zip' => 'application/zip', - 'rar' => 'application/x-rar-compressed', - 'exe' => 'application/x-msdownload', - 'msi' => 'application/x-msdownload', - 'cab' => 'application/vnd.ms-cab-compressed', - - // audio/video - 'mp3' => 'audio/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - - // adobe - 'pdf' => 'application/pdf', - 'psd' => 'image/vnd.adobe.photoshop', - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - - // ms office - 'doc' => 'application/msword', - 'rtf' => 'application/rtf', - 'xls' => 'application/vnd.ms-excel', - 'ppt' => 'application/vnd.ms-powerpoint', - - // open office - 'odt' => 'application/vnd.oasis.opendocument.text', - 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', - ); - - if (0 < strpos($filename, '.')) - { - $ext = strtolower(array_pop(explode('.',$filename))); - if (array_key_exists($ext, $mime_types)) - { - return $mime_types[$ext]; - } - else if (function_exists('finfo_open')) - { - $finfo = finfo_open(FILEINFO_MIME); - $mimetype = finfo_file($finfo, $filename); - finfo_close($finfo); - return $mimetype; - } - } - - return 'application/octet-stream'; - } -} diff --git a/build/owncloud/rainloop-app/personal.php b/build/owncloud/rainloop-app/personal.php deleted file mode 100644 index 449505116..000000000 --- a/build/owncloud/rainloop-app/personal.php +++ /dev/null @@ -1,33 +0,0 @@ -assign('rainloop-email', $sEmail); - $oTemplate->assign('rainloop-password', 0 === strlen($sPass) && 0 === strlen($sEmail) ? '' : '******'); -} - -return $oTemplate->fetchPage(); diff --git a/build/owncloud/rainloop-app/templates/admin-local.php b/build/owncloud/rainloop-app/templates/admin-local.php deleted file mode 100644 index 27a90acf2..000000000 --- a/build/owncloud/rainloop-app/templates/admin-local.php +++ /dev/null @@ -1,29 +0,0 @@ -
-
- - - -
-

t('RainLoop Webmail')); ?>

-
- -

- - t('Go to RainLoop Webmail admin panel')); ?> - -

-
- -

- checked="checked" /> - -
-
- -    -

-
-
-
\ 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 @@ -
-
- - - -
-

t('RainLoop Webmail')); ?>

-

- - - - - -    -

-
-
- \ 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