mirror of
https://github.com/Jonnyan404/memos-bber.git
synced 2026-06-24 22:36:20 +09:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ed5fc86e39 | |||
| 0f468d49aa | |||
| f3e55ec53e | |||
| f05581f88a | |||
| d237a7f1c6 | |||
| 13cc7659ea | |||
| e9730b5839 |
@@ -5,9 +5,12 @@ Chrome 应用商店:<https://chrome.google.com/webstore/detail/memos-bber/cbhj
|
||||
一个通过浏览器插件发布 [Memos](https://usememos.com/) 的插件。基于 iSpeak-bber 修改,原作者为 [DreamyTZK](https://www.antmoe.com/)。
|
||||
|
||||
## 更新日志
|
||||
- 20260325 优化语言按钮样式
|
||||
- 20260323 优化中文显示效果
|
||||
- 20260322 适配移动端竖屏窗口
|
||||
- 20260310 记忆拖拽窗口大小,移除拖拽窗口动画
|
||||
- 20260309 右键发送选中文本保持原格式,增加全屏和窗口放大功能
|
||||
### 20260308 向前兼容到0.18.0,可能再往前也行,只测试到0.18.0
|
||||
### 20260308 向前兼容到0.15.0,可能再往前也行,只测试到0.15.0
|
||||
- 20260307 增加语言切换按钮以及韩语和日语支持,
|
||||
- 2026年03月06日 右键菜单发送选中文本附带原文链接
|
||||
- 2026年03月05日 向前兼容到0.24.0,可能再往前也行,因为只测试了0.24.0和0.25.0以及当前最新版本,如有更早版本需求,可issue反馈
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"message": "Save"
|
||||
},
|
||||
"supportedMemosVersion": {
|
||||
"message": "Compatible with Memos v0.18.0 - 0.26.x"
|
||||
"message": "Compatible with Memos v0.15.0 - 0.26.x"
|
||||
},
|
||||
"placeApiUrl":{
|
||||
"message": "Memos site URL"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"message": "保存"
|
||||
},
|
||||
"supportedMemosVersion": {
|
||||
"message": "Memos v0.18.0 - 0.26.x に対応"
|
||||
"message": "Memos v0.15.0 - 0.26.x に対応"
|
||||
},
|
||||
"placeApiUrl": {
|
||||
"message": "Memos サイトURL"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"message": "저장"
|
||||
},
|
||||
"supportedMemosVersion": {
|
||||
"message": "Memos v0.18.0 - 0.26.x 호환"
|
||||
"message": "Memos v0.15.0 - 0.26.x 호환"
|
||||
},
|
||||
"placeApiUrl": {
|
||||
"message": "Memos 사이트 URL"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"message": "保存"
|
||||
},
|
||||
"supportedMemosVersion": {
|
||||
"message": "兼容 Memos v0.18.0 - 0.26.x"
|
||||
"message": "兼容 Memos v0.15.0 - 0.26.x"
|
||||
},
|
||||
"placeApiUrl":{
|
||||
"message": "请填入 Memos 主页网址"
|
||||
@@ -33,22 +33,22 @@
|
||||
"message": "现在的想法是..."
|
||||
},
|
||||
"lockPrivate":{
|
||||
"message": "仅自己可见"
|
||||
"message": "私有"
|
||||
},
|
||||
"lockProtected":{
|
||||
"message": "登录用户可见"
|
||||
"message": "登录可见"
|
||||
},
|
||||
"lockPublic":{
|
||||
"message": "所有人可见"
|
||||
"message": "公开"
|
||||
},
|
||||
"submitBtn":{
|
||||
"message": "记下"
|
||||
},
|
||||
"placeHideInput":{
|
||||
"message": "默认“仅自己可见”标签名"
|
||||
"message": "默认“私有”标签名"
|
||||
},
|
||||
"placeShowInput":{
|
||||
"message": "默认“所有人可见”标签名"
|
||||
"message": "默认“公开”标签名"
|
||||
},
|
||||
"picDrag":{
|
||||
"message": "拖拽到窗口上传该图片"
|
||||
|
||||
+70
-7
@@ -20,7 +20,7 @@ input:focus::placeholder ,.common-editor-inputer:focus::placeholder {
|
||||
}
|
||||
|
||||
.body{
|
||||
min-width:460px;
|
||||
min-width:360px;
|
||||
background-color: #f6f5f4;
|
||||
padding:0 1rem 1rem;
|
||||
font-family: eafont,PingFang SC,Hiragino Sans GB,Microsoft YaHei,STHeiti,WenQuanYi Micro Hei,Helvetica,Arial,sans-serif;
|
||||
@@ -29,6 +29,7 @@ input:focus::placeholder ,.common-editor-inputer:focus::placeholder {
|
||||
line-height: 1.5;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
a{color: #555;}
|
||||
.title{
|
||||
width: 100px;
|
||||
@@ -321,17 +322,79 @@ input.inputer{border-bottom: 1px solid #ccc;width:75%;}
|
||||
top: .55rem;
|
||||
}
|
||||
|
||||
.lang-select{
|
||||
border: 1px solid rgb(229,231,235);
|
||||
border-radius: .25rem;
|
||||
background-color: rgb(255,255,255);
|
||||
.lang-toggle{
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background-color: transparent;
|
||||
color: #666;
|
||||
min-width: 24px;
|
||||
height: 24px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.lang-toggle:hover,
|
||||
.lang-toggle[aria-expanded="true"]{
|
||||
background-color: transparent;
|
||||
color: #666;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lang-toggle-text{
|
||||
display: inline-block;
|
||||
min-width: 24px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
font-weight: 700;
|
||||
letter-spacing: .02em;
|
||||
}
|
||||
|
||||
.lang-menu{
|
||||
position: absolute;
|
||||
top: calc(100% + .35rem);
|
||||
right: 0;
|
||||
min-width: 8rem;
|
||||
padding: .25rem;
|
||||
border: 1px solid rgb(229,231,235);
|
||||
border-radius: .5rem;
|
||||
background-color: rgb(255,255,255);
|
||||
box-shadow: 0 8px 24px rgba(15,23,42,.12);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.lang-menu.hidden{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lang-menu-item{
|
||||
width: 100%;
|
||||
display: block;
|
||||
text-align: left;
|
||||
padding: .4rem .5rem;
|
||||
border-radius: .35rem;
|
||||
background: transparent;
|
||||
color: #555;
|
||||
font-size: .75rem;
|
||||
line-height: 1.25rem;
|
||||
padding: .15rem .35rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.lang-menu-item:hover{
|
||||
background-color: rgb(243,244,246);
|
||||
}
|
||||
|
||||
.lang-menu-item.active{
|
||||
background-color: rgb(220,252,231);
|
||||
color: rgb(22,101,52);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
|
||||
.tip{
|
||||
margin-left: 36%;
|
||||
@@ -535,4 +598,4 @@ input.inputer{border-bottom: 1px solid #ccc;width:75%;}
|
||||
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(156 163 175 / var(--tw-text-opacity))
|
||||
}
|
||||
}
|
||||
|
||||
+64
-11
@@ -47,6 +47,36 @@ function formatSubstitutions(message, substitutions) {
|
||||
let currentUiLanguage = 'auto'
|
||||
let overrideMessages = null
|
||||
|
||||
function getLanguageToggleLabel(lang) {
|
||||
if (lang === 'en') return 'EN'
|
||||
if (lang === 'zh_CN') return '中'
|
||||
if (lang === 'ja') return '日'
|
||||
if (lang === 'ko') return '한'
|
||||
return 'A'
|
||||
}
|
||||
|
||||
function syncLanguageToggleText(lang) {
|
||||
const text = document.getElementById('langToggleText')
|
||||
if (text) text.textContent = getLanguageToggleLabel(lang)
|
||||
}
|
||||
|
||||
function syncLanguageMenuState(lang) {
|
||||
const items = document.querySelectorAll('.lang-menu-item')
|
||||
items.forEach((item) => {
|
||||
const isActive = item.getAttribute('data-lang') === lang
|
||||
item.classList.toggle('active', isActive)
|
||||
item.setAttribute('aria-checked', isActive ? 'true' : 'false')
|
||||
})
|
||||
}
|
||||
|
||||
function setLanguageMenuOpen(isOpen) {
|
||||
const toggle = document.getElementById('langToggle')
|
||||
const menu = document.getElementById('langMenu')
|
||||
if (!toggle || !menu) return
|
||||
toggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false')
|
||||
menu.classList.toggle('hidden', !isOpen)
|
||||
}
|
||||
|
||||
function t(key, substitutions) {
|
||||
const msg = overrideMessages && overrideMessages[key] && overrideMessages[key].message
|
||||
if (typeof msg === 'string' && msg.length > 0) {
|
||||
@@ -100,7 +130,9 @@ function applyStaticI18n() {
|
||||
setText('langOptionZhCN', 'langChineseSimplified')
|
||||
setText('langOptionJa', 'langJapanese')
|
||||
setText('langOptionKo', 'langKorean')
|
||||
setTitle('langSelect', 'tipLanguage')
|
||||
setTitle('langToggle', 'tipLanguage')
|
||||
const langToggle = document.getElementById('langToggle')
|
||||
if (langToggle) langToggle.setAttribute('aria-label', t('tipLanguage'))
|
||||
|
||||
// Native hover tooltips (title)
|
||||
setTitle('opensite', 'tipOpenSite')
|
||||
@@ -122,26 +154,47 @@ async function setUiLanguage(nextLang, { persist = true } = {}) {
|
||||
currentUiLanguage = lang
|
||||
overrideMessages = await loadLocaleMessages(lang)
|
||||
applyStaticI18n()
|
||||
|
||||
const select = document.getElementById('langSelect')
|
||||
if (select && select.value !== lang) select.value = lang
|
||||
syncLanguageToggleText(lang)
|
||||
syncLanguageMenuState(lang)
|
||||
|
||||
if (persist) await storageSyncSet({ [UI_LANGUAGE_STORAGE_KEY]: lang })
|
||||
window.dispatchEvent(new CustomEvent('i18n:changed', { detail: { lang } }))
|
||||
}
|
||||
|
||||
async function initLanguageSwitcher() {
|
||||
const select = document.getElementById('langSelect')
|
||||
if (select) {
|
||||
select.addEventListener('change', async () => {
|
||||
await setUiLanguage(select.value)
|
||||
const switcher = document.getElementById('lang_switcher')
|
||||
const toggle = document.getElementById('langToggle')
|
||||
const langItems = document.querySelectorAll('.lang-menu-item')
|
||||
|
||||
if (toggle) {
|
||||
toggle.addEventListener('click', (event) => {
|
||||
event.stopPropagation()
|
||||
const isOpen = toggle.getAttribute('aria-expanded') === 'true'
|
||||
setLanguageMenuOpen(!isOpen)
|
||||
})
|
||||
}
|
||||
|
||||
const items = await storageSyncGet({ [UI_LANGUAGE_STORAGE_KEY]: 'auto' })
|
||||
const stored = normalizeUiLanguage(items[UI_LANGUAGE_STORAGE_KEY])
|
||||
if (select) select.value = stored
|
||||
langItems.forEach((item) => {
|
||||
item.addEventListener('click', async (event) => {
|
||||
event.stopPropagation()
|
||||
setLanguageMenuOpen(false)
|
||||
await setUiLanguage(item.getAttribute('data-lang'))
|
||||
})
|
||||
})
|
||||
|
||||
document.addEventListener('click', (event) => {
|
||||
if (!switcher || switcher.contains(event.target)) return
|
||||
setLanguageMenuOpen(false)
|
||||
})
|
||||
|
||||
document.addEventListener('keydown', (event) => {
|
||||
if (event.key === 'Escape') setLanguageMenuOpen(false)
|
||||
})
|
||||
|
||||
const storedItems = await storageSyncGet({ [UI_LANGUAGE_STORAGE_KEY]: 'auto' })
|
||||
const stored = normalizeUiLanguage(storedItems[UI_LANGUAGE_STORAGE_KEY])
|
||||
await setUiLanguage(stored, { persist: false })
|
||||
setLanguageMenuOpen(false)
|
||||
}
|
||||
|
||||
window.t = t
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
"manifest_version": 3,
|
||||
"name": "__MSG_extName__",
|
||||
"default_locale": "en",
|
||||
"version": "2026.03.11",
|
||||
"version_name": "Supports 0.18.0 - 0.26.x",
|
||||
"version": "2026.03.25",
|
||||
"version_name": "Supports 0.15.0 - 0.26.x",
|
||||
"action": {
|
||||
"default_popup": "popup.html",
|
||||
"default_icon": "assets/logo_24x24.png",
|
||||
|
||||
+16
-7
@@ -13,13 +13,22 @@
|
||||
<body class="body">
|
||||
<div class="title" id="opensite">MEMOS</div>
|
||||
<div id="lang_switcher" class="lang-switcher">
|
||||
<select id="langSelect" class="lang-select" aria-label="Language" title="">
|
||||
<option id="langOptionAuto" value="auto"></option>
|
||||
<option id="langOptionEn" value="en"></option>
|
||||
<option id="langOptionZhCN" value="zh_CN"></option>
|
||||
<option id="langOptionJa" value="ja"></option>
|
||||
<option id="langOptionKo" value="ko"></option>
|
||||
</select>
|
||||
<button
|
||||
id="langToggle"
|
||||
class="lang-toggle"
|
||||
type="button"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<span id="langToggleText" class="lang-toggle-text" aria-hidden="true">A</span>
|
||||
</button>
|
||||
<div id="langMenu" class="lang-menu hidden" role="menu" aria-labelledby="langToggle">
|
||||
<button id="langOptionAuto" class="lang-menu-item" type="button" data-lang="auto" role="menuitemradio" aria-checked="false"></button>
|
||||
<button id="langOptionEn" class="lang-menu-item" type="button" data-lang="en" role="menuitemradio" aria-checked="false"></button>
|
||||
<button id="langOptionZhCN" class="lang-menu-item" type="button" data-lang="zh_CN" role="menuitemradio" aria-checked="false"></button>
|
||||
<button id="langOptionJa" class="lang-menu-item" type="button" data-lang="ja" role="menuitemradio" aria-checked="false"></button>
|
||||
<button id="langOptionKo" class="lang-menu-item" type="button" data-lang="ko" role="menuitemradio" aria-checked="false"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="blog_info_edit"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" class="icon" viewBox="0 0 1024 1024">
|
||||
<path d="M914 432c-5-26-21-43-41-43h-4c-54 0-99-44-99-99 0-17 9-37 9-38 10-22 2-50-18-65l-103-57h-1c-21-9-49-4-64 12-12 12-50 44-79 44s-68-33-79-45a60 60 0 0 0-64-13l-106 58-2 1a54 54 0 0 0-18 65c0 1 9 21 9 38 0 55-45 99-99 99h-5c-19 0-35 17-40 43 0 2-9 45-9 80s9 79 9 81c5 25 21 42 41 42h4c54 0 99 45 99 99 0 18-9 37-9 38-10 23-2 51 18 65l101 56 1 1c21 9 49 3 65-13 14-15 52-47 80-47 30 0 69 35 81 48a58 58 0 0 0 64 14l104-58 2-1c20-14 28-42 18-65 0-1-9-20-9-38 0-54 45-99 99-99h5c19 0 35-17 40-42 0-2 9-46 9-81s-9-78-9-80m-51 80c0 23-5 52-7 64a158 158 0 0 0-134 215l-89 49c-4-5-17-18-35-31-31-23-61-35-88-35s-57 12-88 34c-17 13-30 26-34 31l-86-48a159 159 0 0 0-134-215c-2-12-7-41-7-64 0-22 5-51 7-64a157 157 0 0 0 134-214l91-50c4 4 17 17 35 29 30 22 59 33 86 33s55-11 85-32c18-13 31-25 35-29l88 49a159 159 0 0 0 134 214c2 13 7 42 7 64"/>
|
||||
|
||||
Reference in New Issue
Block a user