mirror of
https://github.com/Jonnyan404/memos-bber.git
synced 2026-04-25 03:58:37 +09:00
Firefox: add icons, rewrite viewer, update manifest
Add Firefox icon assets and update manifest to use the new icon files and opt-out data_collection_permissions. Replace minified view-image.js with a modern, readable implementation (style injection, accessible controls, keyboard navigation, and better DOM handling). Simplify background popup logic to call chrome.browserAction.openPopup directly. Remove the packaging section from README to clean up docs.
This commit is contained in:
+172
-12
@@ -1,12 +1,172 @@
|
||||
/**
|
||||
* ViewImage.min.js 2.0.2
|
||||
* MIT License - http://www.opensource.org/licenses/mit-license.php
|
||||
* https://tokinx.github.io/ViewImage/
|
||||
*/
|
||||
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.createTemplateTagFirstArg=function(b){return b.raw=b};$jscomp.createTemplateTagFirstArgWithRaw=function(b,a){b.raw=a;return b};$jscomp.arrayIteratorImpl=function(b){var a=0;return function(){return a<b.length?{done:!1,value:b[a++]}:{done:!0}}};$jscomp.arrayIterator=function(b){return{next:$jscomp.arrayIteratorImpl(b)}};$jscomp.makeIterator=function(b){var a="undefined"!=typeof Symbol&&Symbol.iterator&&b[Symbol.iterator];return a?a.call(b):$jscomp.arrayIterator(b)};
|
||||
$jscomp.arrayFromIterator=function(b){for(var a,d=[];!(a=b.next()).done;)d.push(a.value);return d};$jscomp.arrayFromIterable=function(b){return b instanceof Array?b:$jscomp.arrayFromIterator($jscomp.makeIterator(b))};
|
||||
(function(){window.ViewImage=new function(){var b=this;this.target="[view-image] img";this.listener=function(a){if(!(a.ctrlKey||a.metaKey||a.shiftKey||a.altKey)){var d=String(b.target.split(",").map(function(g){return g.trim()+":not([no-view])"})),c=a.target.closest(d);if(c){var e=c.closest("[view-image]")||document.body;d=[].concat($jscomp.arrayFromIterable(e.querySelectorAll(d))).map(function(g){return g.href||g.src});b.display(d,c.href||c.src);a.stopPropagation();a.preventDefault()}}};this.init=
|
||||
function(a){a&&(b.target=a);["removeEventListener","addEventListener"].forEach(function(d){document[d]("click",b.listener,!1)})};this.display=function(a,d){var c=a.indexOf(d),e=(new DOMParser).parseFromString('\n <div class="view-image">\n <style>.view-image{position:fixed;inset:0;z-index:500;padding:1rem;display:flex;flex-direction:column;animation:view-image-in 300ms;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}.view-image__out{animation:view-image-out 300ms}@keyframes view-image-in{0%{opacity:0}}@keyframes view-image-out{100%{opacity:0}}.view-image-btn{width:32px;height:32px;display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:3px;background-color:rgba(255,255,255,0.2)}.view-image-btn:hover{background-color:rgba(255,255,255,0.5)}.view-image-close__full{position:absolute;inset:0;background-color:rgba(48,55,66,0.3);z-index:unset;cursor:zoom-out;margin:0}.view-image-container{height:0;flex:1;display:flex;align-items:center;justify-content:center;}.view-image-lead{display:contents}.view-image-lead img{position:relative;z-index:1;max-width:100%;max-height:100%;object-fit:contain;border-radius:3px}.view-image-lead__in img{animation:view-image-lead-in 300ms}.view-image-lead__out img{animation:view-image-lead-out 300ms forwards}@keyframes view-image-lead-in{0%{opacity:0;transform:translateY(-20px)}}@keyframes view-image-lead-out{100%{opacity:0;transform:translateY(20px)}}[class*=__out] ~ .view-image-loading{display:block}.view-image-loading{position:absolute;inset:50%;width:8rem;height:2rem;color:#aab2bd;overflow:hidden;text-align:center;margin:-1rem -4rem;z-index:1;display:none}.view-image-loading::after{content:"";position:absolute;inset:50% 0;width:100%;height:3px;background:rgba(255,255,255,0.5);transform:translateX(-100%) translateY(-50%);animation:view-image-loading 800ms -100ms ease-in-out infinite}@keyframes view-image-loading{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}.view-image-tools{position:relative;display:flex;justify-content:space-between;align-content:center;color:#fff;max-width:600px;position: absolute; bottom: 5%; left: 1rem; right: 1rem; backdrop-filter: blur(10px);margin:0 auto;padding:10px;border-radius:5px;background:rgba(0,0,0,0.1);margin-bottom:constant(safe-area-inset-bottom);margin-bottom:env(safe-area-inset-bottom);z-index:1}.view-image-tools__count{width:60px;display:flex;align-items:center;justify-content:center}.view-image-tools__flip{display:flex;gap:10px}.view-image-tools [class*=-close]{margin:0 10px}</style>\n <div class="view-image-container">\n <div class="view-image-lead"></div>\n <div class="view-image-loading"></div>\n <div class="view-image-close view-image-close__full"></div>\n </div>\n <div class="view-image-tools">\n <div class="view-image-tools__count">\n <span><b class="view-image-index">'+
|
||||
(c+1)+"</b>/"+a.length+'</span>\n </div>\n <div class="view-image-tools__flip">\n <div class="view-image-btn view-image-tools__flip-prev">\n <svg width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M31 36L19 24L31 12" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>\n </div>\n <div class="view-image-btn view-image-tools__flip-next">\n <svg width="20" height="20" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M19 12L31 24L19 36" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>\n </div>\n </div>\n <div class="view-image-btn view-image-close">\n <svg width="16" height="16" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="48" height="48" fill="white" fill-opacity="0.01"/><path d="M8 8L40 40" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 40L40 8" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>\n </div>\n </div>\n </div>\n ',
|
||||
"text/html").body.firstChild,g=function(f){var h={Escape:"close",ArrowLeft:"tools__flip-prev",ArrowRight:"tools__flip-next"};h[f.key]&&e.querySelector(".view-image-"+h[f.key]).click()},l=function(f){var h=new Image,k=e.querySelector(".view-image-lead");k.className="view-image-lead view-image-lead__out";setTimeout(function(){k.innerHTML="";h.onload=function(){setTimeout(function(){k.innerHTML='<img src="'+h.src+'" alt="ViewImage" no-view/>';k.className="view-image-lead view-image-lead__in"},100)};
|
||||
h.src=f},300)};document.body.appendChild(e);l(d);window.addEventListener("keydown",g);e.onclick=function(f){f.target.closest(".view-image-close")?(window.removeEventListener("keydown",g),e.onclick=null,e.classList.add("view-image__out"),setTimeout(function(){return e.remove()},290)):f.target.closest(".view-image-tools__flip")&&(c=f.target.closest(".view-image-tools__flip-prev")?0===c?a.length-1:c-1:c===a.length-1?0:c+1,l(a[c]),e.querySelector(".view-image-index").innerHTML=c+1)}}}})();
|
||||
;(function () {
|
||||
const STYLE_ID = 'view-image-style'
|
||||
const STYLE_TEXT = `
|
||||
.view-image{position:fixed;inset:0;z-index:500;padding:1rem;display:flex;flex-direction:column;animation:view-image-in 300ms;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}
|
||||
.view-image__out{animation:view-image-out 300ms}
|
||||
@keyframes view-image-in{0%{opacity:0}}
|
||||
@keyframes view-image-out{100%{opacity:0}}
|
||||
.view-image-btn{width:32px;height:32px;display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:3px;background-color:rgba(255,255,255,0.2);color:#fff;font-size:20px;line-height:1}
|
||||
.view-image-btn:hover{background-color:rgba(255,255,255,0.5)}
|
||||
.view-image-close__full{position:absolute;inset:0;background-color:rgba(48,55,66,0.3);cursor:zoom-out;margin:0}
|
||||
.view-image-container{height:0;flex:1;display:flex;align-items:center;justify-content:center}
|
||||
.view-image-lead{position:relative;z-index:1;display:flex;align-items:center;justify-content:center;max-width:100%;max-height:100%}
|
||||
.view-image-lead img{max-width:100%;max-height:100%;object-fit:contain;border-radius:3px}
|
||||
.view-image-lead__in img{animation:view-image-lead-in 300ms}
|
||||
.view-image-lead__out img{animation:view-image-lead-out 300ms forwards}
|
||||
@keyframes view-image-lead-in{0%{opacity:0;transform:translateY(-20px)}}
|
||||
@keyframes view-image-lead-out{100%{opacity:0;transform:translateY(20px)}}
|
||||
[class*=__out] ~ .view-image-loading{display:block}
|
||||
.view-image-loading{position:absolute;inset:50%;width:8rem;height:2rem;color:#aab2bd;overflow:hidden;text-align:center;margin:-1rem -4rem;z-index:1;display:none}
|
||||
.view-image-loading::after{content:"";position:absolute;inset:50% 0;width:100%;height:3px;background:rgba(255,255,255,0.5);transform:translateX(-100%) translateY(-50%);animation:view-image-loading 800ms -100ms ease-in-out infinite}
|
||||
@keyframes view-image-loading{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}
|
||||
.view-image-tools{position:absolute;bottom:5%;left:1rem;right:1rem;display:flex;justify-content:space-between;align-content:center;color:#fff;max-width:600px;backdrop-filter:blur(10px);margin:0 auto;padding:10px;border-radius:5px;background:rgba(0,0,0,0.1);margin-bottom:constant(safe-area-inset-bottom);margin-bottom:env(safe-area-inset-bottom);z-index:1}
|
||||
.view-image-tools__count{width:60px;display:flex;align-items:center;justify-content:center}
|
||||
.view-image-tools__flip{display:flex;gap:10px}
|
||||
.view-image-tools [class*=-close]{margin:0 10px}
|
||||
`
|
||||
|
||||
function ensureStyle() {
|
||||
if (document.getElementById(STYLE_ID)) return
|
||||
const style = document.createElement('style')
|
||||
style.id = STYLE_ID
|
||||
style.textContent = STYLE_TEXT
|
||||
document.head.appendChild(style)
|
||||
}
|
||||
|
||||
function createButton(className, label, ariaLabel) {
|
||||
const button = document.createElement('button')
|
||||
button.type = 'button'
|
||||
button.className = className
|
||||
button.setAttribute('aria-label', ariaLabel)
|
||||
button.textContent = label
|
||||
return button
|
||||
}
|
||||
|
||||
window.ViewImage = new (function () {
|
||||
const api = this
|
||||
api.target = '[view-image] img'
|
||||
api.listener = function (event) {
|
||||
if (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) return
|
||||
const selector = String(
|
||||
api.target
|
||||
.split(',')
|
||||
.map(function (item) {
|
||||
return item.trim() + ':not([no-view])'
|
||||
})
|
||||
.join(',')
|
||||
)
|
||||
const current = event.target.closest(selector)
|
||||
if (!current) return
|
||||
const root = current.closest('[view-image]') || document.body
|
||||
const sources = Array.from(root.querySelectorAll(selector)).map(function (item) {
|
||||
return item.href || item.src
|
||||
})
|
||||
api.display(sources, current.href || current.src)
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
api.init = function (target) {
|
||||
if (target) api.target = target
|
||||
document.removeEventListener('click', api.listener, false)
|
||||
document.addEventListener('click', api.listener, false)
|
||||
}
|
||||
|
||||
api.display = function (sources, currentSrc) {
|
||||
ensureStyle()
|
||||
|
||||
let currentIndex = Math.max(0, sources.indexOf(currentSrc))
|
||||
const overlay = document.createElement('div')
|
||||
overlay.className = 'view-image'
|
||||
|
||||
const container = document.createElement('div')
|
||||
container.className = 'view-image-container'
|
||||
|
||||
const lead = document.createElement('div')
|
||||
lead.className = 'view-image-lead'
|
||||
|
||||
const loading = document.createElement('div')
|
||||
loading.className = 'view-image-loading'
|
||||
|
||||
const backdrop = document.createElement('div')
|
||||
backdrop.className = 'view-image-close view-image-close__full'
|
||||
|
||||
container.appendChild(lead)
|
||||
container.appendChild(loading)
|
||||
container.appendChild(backdrop)
|
||||
|
||||
const tools = document.createElement('div')
|
||||
tools.className = 'view-image-tools'
|
||||
|
||||
const count = document.createElement('div')
|
||||
count.className = 'view-image-tools__count'
|
||||
const countText = document.createElement('span')
|
||||
count.appendChild(countText)
|
||||
|
||||
const flips = document.createElement('div')
|
||||
flips.className = 'view-image-tools__flip'
|
||||
const prev = createButton('view-image-btn view-image-tools__flip-prev', '‹', 'Previous image')
|
||||
const next = createButton('view-image-btn view-image-tools__flip-next', '›', 'Next image')
|
||||
flips.appendChild(prev)
|
||||
flips.appendChild(next)
|
||||
|
||||
const close = createButton('view-image-btn view-image-close', '×', 'Close image viewer')
|
||||
|
||||
tools.appendChild(count)
|
||||
tools.appendChild(flips)
|
||||
tools.appendChild(close)
|
||||
|
||||
overlay.appendChild(container)
|
||||
overlay.appendChild(tools)
|
||||
|
||||
function render() {
|
||||
countText.textContent = `${currentIndex + 1}/${sources.length}`
|
||||
lead.className = 'view-image-lead view-image-lead__out'
|
||||
|
||||
window.setTimeout(function () {
|
||||
const image = document.createElement('img')
|
||||
image.alt = 'ViewImage'
|
||||
image.setAttribute('no-view', '')
|
||||
image.addEventListener('load', function () {
|
||||
window.setTimeout(function () {
|
||||
lead.replaceChildren(image)
|
||||
lead.className = 'view-image-lead view-image-lead__in'
|
||||
}, 100)
|
||||
})
|
||||
image.src = sources[currentIndex]
|
||||
}, 300)
|
||||
}
|
||||
|
||||
function closeViewer() {
|
||||
window.removeEventListener('keydown', onKeyDown)
|
||||
overlay.classList.add('view-image__out')
|
||||
window.setTimeout(function () {
|
||||
overlay.remove()
|
||||
}, 290)
|
||||
}
|
||||
|
||||
function onKeyDown(event) {
|
||||
if (event.key === 'Escape') closeViewer()
|
||||
if (event.key === 'ArrowLeft') prev.click()
|
||||
if (event.key === 'ArrowRight') next.click()
|
||||
}
|
||||
|
||||
prev.addEventListener('click', function () {
|
||||
currentIndex = currentIndex === 0 ? sources.length - 1 : currentIndex - 1
|
||||
render()
|
||||
})
|
||||
|
||||
next.addEventListener('click', function () {
|
||||
currentIndex = currentIndex === sources.length - 1 ? 0 : currentIndex + 1
|
||||
render()
|
||||
})
|
||||
|
||||
backdrop.addEventListener('click', closeViewer)
|
||||
close.addEventListener('click', closeViewer)
|
||||
|
||||
document.body.appendChild(overlay)
|
||||
window.addEventListener('keydown', onKeyDown)
|
||||
render()
|
||||
}
|
||||
})()
|
||||
})()
|
||||
|
||||
Reference in New Issue
Block a user