Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions plugins/traditional-simplified-cn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 繁简转换(ZTools 插件)

基于 [OpenCC](https://github.com/BYVoid/OpenCC)(`opencc-js`)的繁体字与简体字互转,支持台湾地区 / 香港地区与大陆简体之间的用词差异。

## 功能

- 界面**左侧为原文**,**右侧为转换结果**,可对照查看。
- 在 ZTools 中复制文本后呼出启动器:剪贴板有内容时会出现 **「繁简转换(剪贴板)」**,进入插件后自动填入**原文**侧;在右侧点击 **繁 → 简** 或 **简 → 繁** 生成结果。
- 剪贴板为空时,可搜索 **「繁简转换」** 或 **「繁简」** 手动打开。
- **繁体标准**可在界面选择 **台湾(tw)** 或 **香港(hk)**,会影响词语级转换。

## 安装依赖

在插件根目录执行:

```bash
npm install
```

需存在 `node_modules/opencc-js`(ZTools 通过 `preload.js` 以 CommonJS 加载)。

## 在 ZTools 中加载

1. 将本目录准备完整(含 `logo.png`、`plugin.json`、`preload.js`、`index.html` 等)。
2. ZTools → **设置** → **开发者** → **加载本地插件**,选择本插件目录。
3. 修改 `preload.js` 后若未生效,请对该插件 **卸载再重新加载**(preload 通常不热重载)。

## 文件说明

| 文件 | 说明 |
|------|------|
| `plugin.json` | 插件元数据、主搜索框推送(剪贴板入口)与手动打开关键字 |
| `preload.js` | 读取剪贴板、`opencc-js` 转换逻辑、`onMainPush` / `onPluginEnter` |
| `index.html` / `index.js` | 双栏界面与交互 |
| `package.json` | 声明 `opencc-js` 依赖 |
143 changes: 143 additions & 0 deletions plugins/traditional-simplified-cn/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>繁简转换</title>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
padding: 16px 18px 24px;
font-family: -apple-system, "Segoe UI", "Microsoft YaHei", "PingFang SC", sans-serif;
font-size: 14px;
line-height: 1.45;
background: #f5f5f7;
color: #1d1d1f;
}
body.dark {
background: #1c1c1e;
color: #f5f5f7;
}
h1 {
margin: 0 0 12px;
font-size: 18px;
font-weight: 600;
}
.toolbar {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
margin-bottom: 12px;
}
.toolbar label { font-size: 13px; opacity: 0.85; }
select {
padding: 6px 10px;
border-radius: 6px;
border: 1px solid #c7c7cc;
background: #fff;
color: inherit;
font-size: 13px;
}
body.dark select {
background: #2c2c2e;
border-color: #48484a;
}
.panels {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
align-items: stretch;
}
@media (max-width: 520px) {
.panels { grid-template-columns: 1fr; }
}
.panel {
display: flex;
flex-direction: column;
gap: 6px;
min-width: 0;
}
.panel label {
font-size: 13px;
font-weight: 500;
opacity: 0.88;
}
textarea {
width: 100%;
min-height: 160px;
flex: 1;
padding: 10px 12px;
border-radius: 8px;
border: 1px solid #c7c7cc;
background: #fff;
color: inherit;
font-size: 14px;
resize: vertical;
font-family: inherit;
}
body.dark textarea {
background: #2c2c2e;
border-color: #48484a;
}
textarea.result {
background: #fafafa;
}
body.dark textarea.result {
background: #252528;
}
.actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 12px;
}
button {
padding: 8px 14px;
border: none;
border-radius: 6px;
background: #007aff;
color: #fff;
cursor: pointer;
font-size: 13px;
}
button:hover { background: #0066d6; }
button.secondary {
background: #e5e5ea;
color: #1d1d1f;
}
body.dark button.secondary {
background: #3a3a3c;
color: #f5f5f7;
}
button.secondary:hover { opacity: 0.92; }
</style>
</head>
<body>
<h1>繁简转换</h1>
<div class="toolbar">
<label for="variant">繁体标准</label>
<select id="variant" aria-label="繁体标准">
<option value="tw" selected>台湾(OpenCC tw)</option>
<option value="hk">香港(OpenCC hk)</option>
</select>
</div>
<div class="panels">
<div class="panel">
<label for="inputOriginal">原文</label>
<textarea id="inputOriginal" placeholder="在此粘贴或输入中文…" spellcheck="false"></textarea>
</div>
<div class="panel">
<label for="inputResult">转换结果</label>
<textarea id="inputResult" class="result" placeholder="点击上方按钮,从原文生成…" spellcheck="false"></textarea>
</div>
</div>
<div class="actions">
<button type="button" id="btnToSimp">繁 → 简</button>
<button type="button" id="btnToTrad">简 → 繁</button>
<button type="button" class="secondary" id="btnCopy">复制转换结果</button>
</div>
<script src="index.js"></script>
</body>
</html>
77 changes: 77 additions & 0 deletions plugins/traditional-simplified-cn/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
;(function () {
var originalEl = document.getElementById('inputOriginal')
var resultEl = document.getElementById('inputResult')
var variantEl = document.getElementById('variant')
Comment on lines +2 to +4
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

建议使用 const 代替 var 来声明这些 DOM 元素的引用。在现代 JavaScript 开发中,const 是声明不打算重新赋值的变量的首选方式,有助于提高代码的可读性和可维护性。

Suggested change
var originalEl = document.getElementById('inputOriginal')
var resultEl = document.getElementById('inputResult')
var variantEl = document.getElementById('variant')
const originalEl = document.getElementById('inputOriginal')
const resultEl = document.getElementById('inputResult')
const variantEl = document.getElementById('variant')


if (window.ztools && window.ztools.isDarkColors && window.ztools.isDarkColors()) {
document.body.classList.add('dark')
}

function resizeHeight() {
setTimeout(function () {
var h = document.body.scrollHeight
if (window.ztools && window.ztools.setExpendHeight) {
window.ztools.setExpendHeight(h + 48)
}
}, 80)
Comment on lines +11 to +16
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

使用 setTimeout 配合硬编码的延迟(80ms)来处理高度调整是一种比较脆弱的做法。这可能导致 UI 响应迟钝或在性能较差的设备上出现布局计算不准确的问题。此外,48 是一个魔术数字,建议将其定义为常量或通过计算得出。可以考虑使用 requestAnimationFrame 来确保在下一次重绘前执行高度调整,并将内部的 var h 改为 const h

}

function applyVariant() {
if (window.nodeAPI && window.nodeAPI.setVariant) {
window.nodeAPI.setVariant(variantEl.value)
}
}

variantEl.addEventListener('change', function () {
applyVariant()
resizeHeight()
})
applyVariant()

function onTextChange() {
resizeHeight()
}
originalEl.addEventListener('input', onTextChange)
resultEl.addEventListener('input', onTextChange)

document.getElementById('btnToSimp').addEventListener('click', function () {
if (!window.nodeAPI) return
applyVariant()
resultEl.value = window.nodeAPI.toSimplified(originalEl.value)
Comment on lines +39 to +40
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

此处调用 applyVariant() 是多余的。applyVariant() 已经在初始化(第 29 行)以及 variantElchange 事件监听器(第 26 行)中被调用,确保了转换器状态始终与 UI 同步。移除此处的重复调用可以避免每次点击转换按钮时都重新初始化 OpenCC 转换器,从而提升性能。

Suggested change
applyVariant()
resultEl.value = window.nodeAPI.toSimplified(originalEl.value)
resultEl.value = window.nodeAPI.toSimplified(originalEl.value)

resizeHeight()
})

document.getElementById('btnToTrad').addEventListener('click', function () {
if (!window.nodeAPI) return
applyVariant()
resultEl.value = window.nodeAPI.toTraditional(originalEl.value)
Comment on lines +46 to +47
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

同上,此处无需重复调用 applyVariant()。转换器状态已通过事件监听器保持同步。

Suggested change
applyVariant()
resultEl.value = window.nodeAPI.toTraditional(originalEl.value)
resultEl.value = window.nodeAPI.toTraditional(originalEl.value)

resizeHeight()
})

document.getElementById('btnCopy').addEventListener('click', function () {
var t = resultEl.value
if (!t) {
if (window.ztools && window.ztools.showNotification) {
window.ztools.showNotification('没有可复制的内容')
}
return
}
if (window.ztools && window.ztools.copyText) {
window.ztools.copyText(t)
window.ztools.showNotification('已复制转换结果')
}
})

window.addEventListener('plugin-enter', function (e) {
var action = e.detail || {}
var payload = action.payload
if (action.code === 'convert-clipboard' && typeof payload === 'string') {
applyVariant()
originalEl.value = payload
resultEl.value = ''
}
resizeHeight()
})

resizeHeight()
})()
Binary file added plugins/traditional-simplified-cn/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions plugins/traditional-simplified-cn/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions plugins/traditional-simplified-cn/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "ztools-traditional-simplified",
"version": "1.0.0",
"private": true,
"type": "commonjs",
"description": "ZTools 插件:繁体字与简体字互转(基于 opencc-js)",
"dependencies": {
"opencc-js": "^1.0.5"
}
}
29 changes: 29 additions & 0 deletions plugins/traditional-simplified-cn/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "traditional-simplified-cn",
"title": "繁简转换",
"description": "剪贴板有文本时在启动器中推送入口;亦可手动打开(OpenCC)",
"version": "1.0.0",
"author": "lecoix",
"preload": "preload.js",
"main": "index.html",
"logo": "logo.png",
"features": [
{
"code": "convert-clipboard",
"explain": "剪贴板有文本时推送",
"cmds": [
{
"type": "over",
"label": "繁简转换(剪贴板)",
"minLength": 0,
"maxLength": 50000
}
]
},
{
"code": "convert-ui",
"explain": "手动打开(剪贴板为空时)",
"cmds": ["繁简转换", "繁简"]
}
]
}
Loading