kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
fix(front): ensure compatibility with 94% of browsers in the wild #2501
rodzic
351db1fd5b
commit
7ff624b51b
|
@ -0,0 +1,24 @@
|
|||
# Browser support targeting 95% coverage while enabling modern features
|
||||
# This targets browsers that support ES2020+ and modern CSS features
|
||||
|
||||
# Cover 95% of global usage
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
||||
|
||||
# Exclude problematic browsers
|
||||
not ie 11
|
||||
not op_mini all
|
||||
not android <= 4.4
|
||||
not samsung <= 4
|
||||
|
||||
# Ensure modern browser support for ES2020+ features
|
||||
chrome >= 87
|
||||
firefox >= 78
|
||||
safari >= 14
|
||||
edge >= 88
|
||||
|
||||
# Mobile browsers
|
||||
ios >= 14
|
||||
and_chr >= 87
|
||||
and_ff >= 78
|
|
@ -100,6 +100,7 @@
|
|||
"@vue/eslint-config-typescript": "12.0.0",
|
||||
"@vue/test-utils": "2.4.1",
|
||||
"@vue/tsconfig": "0.6.0",
|
||||
"autoprefixer": "10.4.21",
|
||||
"cypress": "13.6.4",
|
||||
"eslint": "8.57.0",
|
||||
"eslint-config-standard": "17.1.0",
|
||||
|
@ -115,6 +116,7 @@
|
|||
"msw-auto-mock": "0.18.0",
|
||||
"openapi-typescript": "7.6.0",
|
||||
"patch-package": "8.0.0",
|
||||
"postcss": "8.5.6",
|
||||
"rollup-plugin-visualizer": "5.9.0",
|
||||
"sass": "1.68.0",
|
||||
"sinon": "15.0.2",
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
export default {
|
||||
plugins: {
|
||||
autoprefixer: {
|
||||
overrideBrowserslist: [
|
||||
'> 1%',
|
||||
'last 2 versions',
|
||||
'not dead',
|
||||
'not ie 11',
|
||||
'not op_mini all',
|
||||
'chrome >= 87',
|
||||
'firefox >= 78',
|
||||
'safari >= 14',
|
||||
'edge >= 88',
|
||||
'ios >= 14'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,19 +3,9 @@ export interface Token {
|
|||
value: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a query string by splitting it into tokens while respecting quoted phrases.
|
||||
*
|
||||
* @param query - The input query string to normalize
|
||||
* @returns Array of normalized tokens with quoted phrases preserved as single tokens
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* normalizeQuery('this is "my query" go')
|
||||
* // Returns: ['this', 'is', 'my query', 'go']
|
||||
* ```
|
||||
*/
|
||||
export function normalizeQuery (query: string): string[] {
|
||||
// given a string such as 'this is "my query" go', returns
|
||||
// an array of tokens like this: ['this', 'is', 'my query', 'go']
|
||||
if (!query) return []
|
||||
|
||||
const match = query.match(/\\?.|^$/g)
|
||||
|
@ -42,46 +32,51 @@ const unquote = (str: string) => {
|
|||
return str
|
||||
}
|
||||
|
||||
const quoteIfNecessary = (str: string) =>
|
||||
str.includes(' ')
|
||||
? `"${str}"`
|
||||
: str
|
||||
|
||||
/**
|
||||
* Parses an array of normalized query tokens into structured Token objects.
|
||||
*
|
||||
* @param normalizedQuery - Array of tokens as returned by normalizeQuery
|
||||
* @returns Array of Token objects with field and value properties
|
||||
*
|
||||
* @example
|
||||
* ```
|
||||
* parseTokens(['status:pending', 'hello'])
|
||||
* // Returns:
|
||||
* // [
|
||||
* // { field: 'status', value: 'pending' },
|
||||
* // { field: null, value: 'hello' }
|
||||
* // ]
|
||||
* ```
|
||||
*/
|
||||
export const parseTokens = (normalizedQuery: string[]): Token[] =>
|
||||
normalizedQuery.map(t => {
|
||||
// Split the token on ":" to separate field from value
|
||||
export function parseTokens (normalizedQuery: string[]): Token[] {
|
||||
// given an array of tokens as returned by normalizeQuery,
|
||||
// returns a list of objects such as [
|
||||
// {
|
||||
// field: 'status',
|
||||
// value: 'pending'
|
||||
// },
|
||||
// {
|
||||
// field: null,
|
||||
// value: 'hello'
|
||||
// }
|
||||
// ]
|
||||
return normalizedQuery.map(t => {
|
||||
// we split the token on ":"
|
||||
const parts = t.split(/:(.+)/)
|
||||
return parts.length === 1
|
||||
? { field: null, value: t } // No field specified
|
||||
: { field: parts[0], value: unquote(parts[1]) } // Field:value format, remove quotes
|
||||
if (parts.length === 1) {
|
||||
// no field specified
|
||||
return { field: null, value: t }
|
||||
}
|
||||
|
||||
// first item is the field, second is the value, possibly quoted
|
||||
const [field, value] = parts
|
||||
|
||||
// we remove surrounding quotes if any
|
||||
return { field, value: unquote(value) }
|
||||
})
|
||||
}
|
||||
|
||||
export function compileTokens (tokens: Token[]) {
|
||||
// given a list of tokens as returned by parseTokens,
|
||||
// returns a string query
|
||||
const parts = tokens.map(token => {
|
||||
const { field } = token
|
||||
let { value } = token
|
||||
|
||||
if (value.includes(' ')) {
|
||||
value = `"${value}"`
|
||||
}
|
||||
|
||||
if (field) {
|
||||
return `${field}:${value}`
|
||||
}
|
||||
|
||||
return value
|
||||
})
|
||||
|
||||
/**
|
||||
* Compiles an array of Token objects back into a query string.
|
||||
*
|
||||
* @param tokens - Array of Token objects as returned by parseTokens
|
||||
* @returns A formatted query string
|
||||
*/
|
||||
export const compileTokens = (tokens: Token[]) =>
|
||||
tokens.map(({field, value}) =>{
|
||||
field
|
||||
? `${field}:${quoteIfNecessary(value)}`
|
||||
: quoteIfNecessary(value)
|
||||
})
|
||||
.join(' ')
|
||||
return parts.join(' ')
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"noUnusedLocals": true,
|
||||
"noImplicitAny": true,
|
||||
"experimentalDecorators": true,
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"lib": ["ES2023", "DOM", "DOM.Iterable"],
|
||||
"typeRoots": ["node_modules", "node_modules/@types"],
|
||||
"types": [
|
||||
"vitest/globals",
|
||||
|
|
|
@ -4,6 +4,7 @@ import { VitePWA } from 'vite-plugin-pwa'
|
|||
import { fileURLToPath, URL } from 'node:url'
|
||||
import UnoCSS from 'unocss/vite'
|
||||
|
||||
|
||||
import manifest from './pwa-manifest.json'
|
||||
|
||||
import VueI18n from '@intlify/unplugin-vue-i18n/vite'
|
||||
|
@ -93,7 +94,14 @@ export default defineConfig(({ mode }) => ({
|
|||
}
|
||||
}
|
||||
},
|
||||
esbuild: {
|
||||
target: 'es2020',
|
||||
supported: {
|
||||
'top-level-await': true
|
||||
}
|
||||
},
|
||||
build: {
|
||||
target: ['es2020', 'chrome87', 'firefox78', 'safari14', 'edge88'],
|
||||
sourcemap: true,
|
||||
// https://rollupjs.org/configuration-options/
|
||||
rollupOptions: {
|
||||
|
|
|
@ -4434,6 +4434,18 @@ automation-events@^7.0.9:
|
|||
"@babel/runtime" "^7.27.6"
|
||||
tslib "^2.8.1"
|
||||
|
||||
autoprefixer@10.4.21:
|
||||
version "10.4.21"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.21.tgz#77189468e7a8ad1d9a37fbc08efc9f480cf0a95d"
|
||||
integrity sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==
|
||||
dependencies:
|
||||
browserslist "^4.24.4"
|
||||
caniuse-lite "^1.0.30001702"
|
||||
fraction.js "^4.3.7"
|
||||
normalize-range "^0.1.2"
|
||||
picocolors "^1.1.1"
|
||||
postcss-value-parser "^4.2.0"
|
||||
|
||||
available-typed-arrays@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846"
|
||||
|
@ -4647,7 +4659,7 @@ browserify-zlib@^0.2.0:
|
|||
dependencies:
|
||||
pako "~1.0.5"
|
||||
|
||||
browserslist@^4.24.0, browserslist@^4.25.1:
|
||||
browserslist@^4.24.0, browserslist@^4.24.4, browserslist@^4.25.1:
|
||||
version "4.25.1"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.1.tgz#ba9e8e6f298a1d86f829c9b975e07948967bb111"
|
||||
integrity sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==
|
||||
|
@ -4783,6 +4795,11 @@ callsites@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
||||
|
||||
caniuse-lite@^1.0.30001702:
|
||||
version "1.0.30001731"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz#277c07416ea4613ec564e5b0ffb47e7b60f32e2f"
|
||||
integrity sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==
|
||||
|
||||
caniuse-lite@^1.0.30001726:
|
||||
version "1.0.30001727"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz#22e9706422ad37aa50556af8c10e40e2d93a8b85"
|
||||
|
@ -6411,6 +6428,11 @@ form-data@^4.0.0, form-data@~4.0.0:
|
|||
hasown "^2.0.2"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fraction.js@^4.3.7:
|
||||
version "4.3.7"
|
||||
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
|
||||
integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
|
||||
|
||||
fs-extra@^11.2.0:
|
||||
version "11.3.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.0.tgz#0daced136bbaf65a555a326719af931adc7a314d"
|
||||
|
@ -8215,6 +8237,11 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
normalize-range@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
|
||||
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
|
||||
|
||||
npm-run-path@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
|
||||
|
@ -8790,7 +8817,12 @@ postcss-selector-parser@^6.0.15:
|
|||
cssesc "^3.0.0"
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
postcss@^8.4.32, postcss@^8.4.38, postcss@^8.4.43, postcss@^8.4.48, postcss@^8.5.6:
|
||||
postcss-value-parser@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
|
||||
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
|
||||
|
||||
postcss@8.5.6, postcss@^8.4.32, postcss@^8.4.38, postcss@^8.4.43, postcss@^8.4.48, postcss@^8.5.6:
|
||||
version "8.5.6"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c"
|
||||
integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==
|
||||
|
|
Ładowanie…
Reference in New Issue