116 lines
3.8 KiB
JavaScript
116 lines
3.8 KiB
JavaScript
import { useLocalStorage } from './useLocalStorage'
|
|
|
|
export function useUrlCleaner() {
|
|
const cleanedHistory = useLocalStorage('url-cleaner-history', [])
|
|
const isWatchEnabled = useLocalStorage('url-cleaner-watch-enabled', false)
|
|
|
|
const defaultExceptions = [
|
|
{ id: 'yt', domainPattern: '*.youtube.com', keepParams: ['v', 't'], keepHash: false, keepAllParams: false, isEnabled: true, isDefault: true },
|
|
{ id: 'yt-short', domainPattern: 'youtu.be', keepParams: ['t'], keepHash: false, keepAllParams: false, isEnabled: true, isDefault: true }
|
|
]
|
|
const exceptions = useLocalStorage('url-cleaner-exceptions', defaultExceptions)
|
|
|
|
const matchDomain = (pattern, domain) => {
|
|
// Escape regex chars except *
|
|
const regexString = '^' + pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*') + '$'
|
|
return new RegExp(regexString, 'i').test(domain)
|
|
}
|
|
|
|
const processUrl = (text, autoClipboard = false, writeClipboardFn = null) => {
|
|
try {
|
|
// Basic URL validation
|
|
if (!text.match(/^https?:\/\//i)) {
|
|
if (autoClipboard) return text
|
|
}
|
|
|
|
const originalLength = text.length
|
|
let cleanedUrl = text
|
|
|
|
try {
|
|
const urlObj = new URL(text)
|
|
const hostname = urlObj.hostname
|
|
|
|
const matchedRule = exceptions.value.find(rule =>
|
|
rule.isEnabled && matchDomain(rule.domainPattern, hostname)
|
|
)
|
|
|
|
if (matchedRule) {
|
|
if (!matchedRule.keepAllParams) {
|
|
const params = new URLSearchParams(urlObj.search)
|
|
const keys = Array.from(params.keys())
|
|
|
|
for (const key of keys) {
|
|
if (!matchedRule.keepParams.includes(key)) {
|
|
params.delete(key)
|
|
}
|
|
}
|
|
urlObj.search = params.toString()
|
|
}
|
|
|
|
if (!matchedRule.keepHash) {
|
|
urlObj.hash = ''
|
|
}
|
|
} else {
|
|
if (urlObj.search || urlObj.hash) {
|
|
urlObj.search = ''
|
|
urlObj.hash = ''
|
|
}
|
|
}
|
|
|
|
cleanedUrl = urlObj.toString()
|
|
} catch (e) {
|
|
return text
|
|
}
|
|
|
|
if (cleanedUrl === text && autoClipboard) {
|
|
return text
|
|
}
|
|
|
|
const newLength = cleanedUrl.length
|
|
const savedChars = originalLength - newLength
|
|
const savedPercent = originalLength > 0 ? Math.round((savedChars / originalLength) * 100) : 0
|
|
|
|
const entry = {
|
|
id: Date.now(),
|
|
original: text,
|
|
cleaned: cleanedUrl,
|
|
savedPercent,
|
|
timestamp: new Date().toLocaleTimeString()
|
|
}
|
|
|
|
cleanedHistory.value.unshift(entry)
|
|
|
|
if (cleanedHistory.value.length > 50) {
|
|
cleanedHistory.value.pop()
|
|
}
|
|
|
|
if (autoClipboard && savedChars > 0 && writeClipboardFn) {
|
|
writeClipboardFn(cleanedUrl)
|
|
}
|
|
|
|
return cleanedUrl
|
|
} catch (e) {
|
|
console.error('Error processing URL:', e)
|
|
return text
|
|
}
|
|
}
|
|
|
|
const removeEntry = (id) => {
|
|
cleanedHistory.value = cleanedHistory.value.filter(item => item.id !== id)
|
|
}
|
|
|
|
const clearHistory = () => {
|
|
cleanedHistory.value = []
|
|
}
|
|
|
|
return {
|
|
cleanedHistory,
|
|
isWatchEnabled,
|
|
exceptions,
|
|
defaultExceptions,
|
|
processUrl,
|
|
removeEntry,
|
|
clearHistory
|
|
}
|
|
}
|