diff --git a/README.md b/README.md index 9373f9b..1211b8e 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,6 @@ 一个通过浏览器插件发布 [Memos](https://usememos.com/) 的插件。基于 iSpeak-bber 修改,原作者为 [DreamyTZK](https://www.antmoe.com/)。 -## 打包 - -仓库内置了 GitHub Actions 工作流 [package-extensions.yml](.github/workflows/package-extensions.yml),支持手动触发或在推送 `v*` 标签时自动打包并发布到 GitHub Releases。 - -- 推送 `v*` 标签时:自动把 Chrome 的 zip 包和 Firefox 的 xpi 包上传为对应 Release 的 assets。 -- 手动触发时:需要填写 `release_tag`,工作流会把产物直接上传到这个 tag 对应的 Release。 -- 下载时拿到的是文件本体,不再通过 Actions artifact 额外包一层 zip。 -- 打包源码固定来自 `main` 分支;`tag` 只用于决定上传到哪个 Release。 - -说明:Chrome 的 zip 包可用于商店上传,Firefox 的 xpi 包可用于 AMO 上传或离线分发。工作流已显式启用 Node 24 运行 JavaScript actions,并使用新的 `actions/checkout@v5`。 ## 更新日志 - 20260422 调整发送设置,支持仅发送附件 diff --git a/firefox/assets/logo-128.png b/firefox/assets/logo-128.png new file mode 100644 index 0000000..338cfee Binary files /dev/null and b/firefox/assets/logo-128.png differ diff --git a/firefox/assets/logo-16.png b/firefox/assets/logo-16.png new file mode 100644 index 0000000..1976d45 Binary files /dev/null and b/firefox/assets/logo-16.png differ diff --git a/firefox/assets/logo-48.png b/firefox/assets/logo-48.png new file mode 100644 index 0000000..90075ee Binary files /dev/null and b/firefox/assets/logo-48.png differ diff --git a/firefox/js/background.js b/firefox/js/background.js index 5889229..b13d901 100644 --- a/firefox/js/background.js +++ b/firefox/js/background.js @@ -99,24 +99,17 @@ function getSelectionTextFromTab(tabId, fallbackText) { }) } -function getActionApi() { - if (chrome.action && typeof chrome.action.openPopup === 'function') return chrome.action - if (chrome.browserAction && typeof chrome.browserAction.openPopup === 'function') return chrome.browserAction - return null -} - function tryOpenActionPopup(tab) { try { - const actionApi = getActionApi() - if (!actionApi) return + if (!chrome.browserAction || typeof chrome.browserAction.openPopup !== 'function') return const windowId = tab && typeof tab.windowId === 'number' ? tab.windowId : undefined const open = () => { try { if (typeof windowId === 'number') { - actionApi.openPopup({ windowId }, () => void chrome.runtime.lastError) + chrome.browserAction.openPopup({ windowId }, () => void chrome.runtime.lastError) } else { - actionApi.openPopup({}, () => void chrome.runtime.lastError) + chrome.browserAction.openPopup({}, () => void chrome.runtime.lastError) } } catch (_) { // best-effort only diff --git a/firefox/js/view-image.js b/firefox/js/view-image.js index 9d5a8cf..dd65b6c 100644 --- a/firefox/js/view-image.js +++ b/firefox/js/view-image.js @@ -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\n \n
\n
\n
\n
\n
\n
\n
\n '+ -(c+1)+"/"+a.length+'\n
\n
\n
\n \n
\n
\n \n
\n
\n
\n \n
\n
\n \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='ViewImage';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() + } + })() +})() diff --git a/firefox/manifest.json b/firefox/manifest.json index 307b636..b7606e6 100644 --- a/firefox/manifest.json +++ b/firefox/manifest.json @@ -12,13 +12,16 @@ "homepage_url": "https://github.com/Jonnyan404/memos-bber", "browser_specific_settings": { "gecko": { - "id": "memos-bber@jonnyan404.github.io" + "id": "memos-bber@jonnyan404.github.io", + "data_collection_permissions": { + "required": false + } } }, "icons": { - "128": "assets/logo.png", - "16": "assets/logo.png", - "48": "assets/logo.png" + "128": "assets/logo-128.png", + "16": "assets/logo-16.png", + "48": "assets/logo-48.png" }, "background": { "scripts": ["js/background.js"]