mirror of https://github.com/nextcloud/server.git
Cleanup ie and old edge properties
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>pull/26358/head
parent
d5edcf8c95
commit
bd303388e3
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OC\Core\Controller;
|
||||
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IRequest;
|
||||
use OCP\Util;
|
||||
|
||||
class UnsupportedBrowserController extends Controller {
|
||||
public function __construct(IRequest $request) {
|
||||
parent::__construct('core', $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index(): Response {
|
||||
Util::addScript('core', 'unsupported-browser');
|
||||
Util::addStyle('core', 'icons');
|
||||
return new TemplateResponse('core', 'unsupportedbrowser', [], TemplateResponse::RENDER_AS_ERROR);
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/**
|
||||
* @copyright Copyright (c) 2016 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license AGPL-3.0-or-later
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
|
||||
|
||||
if (!Element.prototype.matches) {
|
||||
Element.prototype.matches
|
||||
= Element.prototype.msMatchesSelector
|
||||
|| Element.prototype.webkitMatchesSelector
|
||||
}
|
||||
|
||||
if (!Element.prototype.closest) {
|
||||
Element.prototype.closest = function(s) {
|
||||
let el = this
|
||||
|
||||
do {
|
||||
if (el.matches(s)) return el
|
||||
el = el.parentElement || el.parentNode
|
||||
} while (el !== null && el.nodeType === 1)
|
||||
return null
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
import { getUserAgentRegExp } from 'browserslist-useragent-regexp'
|
||||
// eslint-disable-next-line node/no-extraneous-import
|
||||
import browserslist from 'browserslist'
|
||||
import browserslistConfig from '@nextcloud/browserslist-config'
|
||||
|
||||
// Generate a regex that matches user agents to detect incompatible browsers
|
||||
export const supportedBrowsersRegExp = getUserAgentRegExp({ allowHigherVersions: true, browsers: browserslistConfig })
|
||||
export const supportedBrowsers = browserslist(browserslistConfig)
|
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import Vue from 'vue'
|
||||
|
||||
import { browserStorageKey } from './utils/RedirectUnsupportedBrowsers.js'
|
||||
import browserStorage from './services/BrowserStorageService.js'
|
||||
import UnsupportedBrowser from './views/UnsupportedBrowser.vue'
|
||||
|
||||
// If the ignore token is set, redirect
|
||||
if (browserStorage.getItem(browserStorageKey) === 'true') {
|
||||
window.location = generateUrl('/')
|
||||
}
|
||||
|
||||
export default new Vue({
|
||||
el: '#unsupported-browser',
|
||||
// eslint-disable-next-line vue/match-component-file-name
|
||||
name: 'UnsupportedBrowserRoot',
|
||||
render: h => h(UnsupportedBrowser),
|
||||
})
|
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
|
||||
import { supportedBrowsersRegExp } from '../services/BrowsersListService.js'
|
||||
import browserStorage from '../services/BrowserStorageService.js'
|
||||
import logger from '../services/LoggerService.js'
|
||||
|
||||
const redirectPath = '/unsupported'
|
||||
export const browserStorageKey = 'unsupported-browser-ignore'
|
||||
|
||||
const isBrowserOverridden = browserStorage.getItem(browserStorageKey) === 'true'
|
||||
|
||||
/**
|
||||
* Test the current browser user agent against our official browserslist config
|
||||
* and redirect if unsupported
|
||||
*/
|
||||
export const testSupportedBrowser = function() {
|
||||
if (supportedBrowsersRegExp.test(navigator.userAgent)) {
|
||||
logger.debug('this browser is officially supported ! 🚀')
|
||||
return
|
||||
}
|
||||
|
||||
// If incompatible BUT ignored, let's keep going
|
||||
if (isBrowserOverridden) {
|
||||
logger.debug('this browser is NOT supported but has been manually overridden ! ⚠️')
|
||||
return
|
||||
}
|
||||
|
||||
// If incompatible, NOT overridden AND NOT already on the warning page,
|
||||
// redirect to the unsupported warning page
|
||||
if (window.location.pathname.indexOf(redirectPath) === -1) {
|
||||
window.location = generateUrl(redirectPath)
|
||||
}
|
||||
}
|
@ -0,0 +1,191 @@
|
||||
<!--
|
||||
- @copyright Copyright (c) 2021 John Molakvoæ <skjnldsv@protonmail.com>
|
||||
-
|
||||
- @author John Molakvoæ <skjnldsv@protonmail.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
<template>
|
||||
<div class="content-unsupported-browser guest-box">
|
||||
<NcEmptyContent>
|
||||
{{ t('core', 'This browser is not supported') }}
|
||||
<template #icon>
|
||||
<Web />
|
||||
</template>
|
||||
<template #action>
|
||||
<div>
|
||||
<h2>
|
||||
{{ t('core', 'Please upgrade to a more recent browser') }}
|
||||
</h2>
|
||||
<NcButton class="content-unsupported-browser__continue" type="primary" @click="forceBrowsing">
|
||||
{{ t('core', 'Continue with this outdated browser') }}
|
||||
</NcButton>
|
||||
</div>
|
||||
|
||||
<ul class="content-unsupported-browser__list">
|
||||
<h3>{{ t('core', 'Supported versions') }}</h3>
|
||||
<li v-for="browser in formattedBrowsersList" :key="browser">
|
||||
{{ browser }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</NcEmptyContent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
|
||||
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
|
||||
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent'
|
||||
import Web from 'vue-material-design-icons/Web'
|
||||
|
||||
import { browserStorageKey } from '../utils/RedirectUnsupportedBrowsers.js'
|
||||
import { supportedBrowsers } from '../services/BrowsersListService.js'
|
||||
import browserStorage from '../services/BrowserStorageService.js'
|
||||
import logger from '../services/LoggerService.js'
|
||||
|
||||
logger.debug('Supported browsers', { supportedBrowsers })
|
||||
|
||||
export default {
|
||||
name: 'UnsupportedBrowser',
|
||||
components: {
|
||||
Web,
|
||||
NcButton,
|
||||
NcEmptyContent,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
agents: {},
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isMobile() {
|
||||
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter out or include mobile/desktop browsers depending
|
||||
* on the current user platform/device
|
||||
*/
|
||||
filteredSupportedBrowsers() {
|
||||
return supportedBrowsers.filter(browser => {
|
||||
if (!browser) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.isMobile) {
|
||||
return this.isMobileBrowser(browser)
|
||||
}
|
||||
return !this.isMobileBrowser(browser)
|
||||
})
|
||||
},
|
||||
|
||||
formattedBrowsersList() {
|
||||
const list = {}
|
||||
|
||||
// supportedBrowsers is generated by webpack at compilation time
|
||||
this.filteredSupportedBrowsers.forEach(browser => {
|
||||
const [id, version] = browser.split(' ')
|
||||
if (!list[id] || list[id] < parseFloat(version, 10)) {
|
||||
list[id] = parseFloat(version, 10)
|
||||
}
|
||||
})
|
||||
|
||||
return Object.keys(list).map(id => {
|
||||
if (!this.agents[id]?.browser) {
|
||||
return null
|
||||
}
|
||||
|
||||
const version = list[id]
|
||||
const name = this.agents[id]?.browser
|
||||
return this.t('core', '{name} version {version} and above', {
|
||||
name, version,
|
||||
})
|
||||
}).filter(entry => entry !== null)
|
||||
},
|
||||
},
|
||||
|
||||
async beforeMount() {
|
||||
// Dynamic load big list of user agents
|
||||
// eslint-disable-next-line node/no-extraneous-import
|
||||
const { agents } = await import('caniuse-lite')
|
||||
this.agents = agents
|
||||
},
|
||||
|
||||
methods: {
|
||||
t,
|
||||
n,
|
||||
|
||||
// Set the flag allowing this browser and redirect to home
|
||||
forceBrowsing() {
|
||||
browserStorage.setItem(browserStorageKey, true)
|
||||
window.location = generateUrl('/')
|
||||
},
|
||||
|
||||
/**
|
||||
* Detect if the browserslist browser is a mobile one
|
||||
* https://github.com/browserslist/browserslist#query-composition
|
||||
*
|
||||
* @param {string} browser a valid browserlist browser. e.g `and_chr 90`
|
||||
*/
|
||||
isMobileBrowser(browser) {
|
||||
browser = browser.toLowerCase()
|
||||
return browser.includes('and_')
|
||||
|| browser.includes('android')
|
||||
|| browser.includes('ios_')
|
||||
|| browser.includes('mobile')
|
||||
|| browser.includes('_mob')
|
||||
|| browser.includes('samsung')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content-unsupported-browser {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 400px;
|
||||
max-width: 90vw;
|
||||
margin: auto;
|
||||
padding: 30px;
|
||||
|
||||
.empty-content {
|
||||
margin: 0;
|
||||
&::v-deep .empty-content__icon {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&__continue {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
&__list {
|
||||
margin-top: 60px;
|
||||
margin-bottom: 30px;
|
||||
li {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -0,0 +1 @@
|
||||
<div id="unsupported-browser"></div>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue