Skip to content

Commit ba1e2f0

Browse files
authored
同步未过时的插件开发者文档 (#125)
* init * 添加插件清单和引导脚本两部分内容 * 添加prefs部分 * 更新描述避免歧义 * 增加调试、条目、事件、其他接口 * 添加备注说明 * fix typo * Fix typo
1 parent 60682fc commit ba1e2f0

File tree

17 files changed

+1186
-2
lines changed

17 files changed

+1186
-2
lines changed

src/.vuepress/sidebar/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { sidebar } from "vuepress-theme-hope";
55

66
export const zhSidebar = sidebar({
77
"/user-guide/": userGuide,
8-
"/plugin-dev-guide/": "structure",
8+
"/plugin-dev-guide/": pluginDevGuide,
99
"/csl-dev-guide/": cslDevGuide,
1010
"/": [
1111
"about",
Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,35 @@
11
import { arraySidebar } from "vuepress-theme-hope";
22

3-
export const pluginDevGuide = arraySidebar([""]);
3+
export const pluginDevGuide = arraySidebar([
4+
"",
5+
{
6+
text: "从 Make It Red 开始",
7+
collapsible: true,
8+
children: ["quick-start/"],
9+
},
10+
{
11+
text: "使用社区框架",
12+
collapsible: true,
13+
children: ["use-template"],
14+
},
15+
{
16+
text: "调试代码",
17+
collapsible: true,
18+
children: ["development/debug", "development/sideloading"],
19+
},
20+
{
21+
text: "参考",
22+
collapsible: true,
23+
children: [
24+
"reference/manifest",
25+
"reference/bootstrap",
26+
"reference/localization",
27+
"reference/update",
28+
"reference/zotero",
29+
"reference/preference",
30+
"reference/notify",
31+
"reference/item",
32+
"reference/more",
33+
],
34+
},
35+
]);

src/plugin-dev-guide/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
title: 插件开发指南
33
date: 2023-04-20 10:06:59
44
updated: 2023-07-20 16:51:54
5+
author:
6+
- name: windingwind
7+
url: https://github.com/windingwind/
58
---
69

710
# 插件开发指南
@@ -11,3 +14,47 @@ updated: 2023-07-20 16:51:54
1114
待完善,前托管于语雀的开发者文档主要针对 Zotero 6,鉴于插件在 Zotero 7 相对 Zotero 6 变动较大,因此插件开发者文档需要重写。
1215

1316
:::
17+
18+
本文档所述内容仅适用于 Zotero 7 插件开发,Zotero 6 插件开发文档请参阅 [Zotero 6 插件开发文档](https://zotero.yuque.com/staff-gkhviy/developer/)
19+
20+
## 前置基础知识
21+
22+
Zotero 插件遵循 Firefox 插件的要求。此处列举了编写插件的基础知识。并非所有知识都需要掌握,只需要在遇到问题时能通过查阅文档找到解决方法即可。
23+
24+
### Firefox 插件
25+
26+
[Introduction: Welcome to Software Development the Mozilla Way](http://mb.eschew.org/intro)
27+
28+
[Web 浏览器扩展](https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions)
29+
30+
### HTML / XUL
31+
32+
关于 HTML,可参考网上的任意教程,只需理解基本的树结构,大致清楚元素类型与通用属性即可。
33+
参考文档:[HTML 教程 | 菜鸟教程](https://www.runoob.com/html/html-tutorial.html)
34+
关于 XUL,在了解 HTML 的基础上只需大概浏览文档即可。在使用时可随时查阅文档。
35+
参考文档:[Huihoo - XML User Interface Language (XUL)](https://docs.huihoo.com/xul/)[XUL School Tutorial - Archive of obsolete content](https://udn.realityripple.com/docs/Archive/Add-ons/Overlay_Extensions/XUL_School)
36+
37+
### JavaScript / TypeScript
38+
39+
如果对其他编程语言有了解,上手 JavaScript 很快,看一下基本语法即可。
40+
参考文档:[JavaScript 教程](https://www.w3school.com.cn/js/index.asp)
41+
42+
(非必需)也可以直接学习 TypeScript,它是 JS 的超集,提供了更多特性,并对习惯于 C++/JAVA 等强类型语言的开发者而言更加熟悉。第二章将要介绍的的 Zotero 插件框架支持 TS。
43+
参考文档:[TypeScript 中文网 · TypeScript——JavaScript 的超集](https://www.tslang.cn/)
44+
45+
### Git
46+
47+
Git 是版本管理的常用工具。
48+
参考文档:[Git 教程 | 菜鸟教程](https://www.runoob.com/git/git-tutorial.html)
49+
50+
### Zotero 官方资料
51+
52+
Zoero 文档(部分过时或不全):[start [Zotero Documentation]](https://www.zotero.org/support/)
53+
Zotero 社区:[Recent Discussions](https://forums.zotero.org/discussions)
54+
Zotero 贡献文档:[Zotero | Get Involved](https://www.zotero.org/getinvolved/)
55+
Zotero 开发者群组:[https://groups.google.com/g/zotero-dev](https://groups.google.com/g/zotero-dev)
56+
社区维护的 Zotero Types 接口类型定义包:[windingwind / Zotero-types](https://github.com/windingwind/zotero-types) [Zotero-types](https://www.npmjs.com/package/zotero-types)
57+
58+
## 本文档的结构
59+
60+
> todo
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
author:
3+
- name: windingwind
4+
url: https://github.com/windingwind/
5+
- name: ShareStuff
6+
- name: northword
7+
url: https://github.com/northword/
8+
---
9+
10+
# 调试代码
11+
12+
## 通过 Run JavaScript 调试
13+
14+
`菜单栏` -> `工具` -> `开发者` -> `Run JavaScript` 打开界面。
15+
16+
在左侧键入代码,点击运行即可在右侧看到输出。
17+
18+
如果代码中包含异步语法(async),需要将结果 return 才能在右侧看见。
19+
20+
## 通过 Zotero.debug 输出日志
21+
22+
- 使用 `Zotero.debug` 输出到 `菜单栏` -> `帮助` -> `输出日志排错` -> `查看输出文件`
23+
- 使用 `Zotero.log` 输出到 `菜单栏` -> `工具` -> `开发者` -> `Error Console`
24+
25+
## 通过开发者工具
26+
27+
如果你不熟悉开发者工具,可参看[什么是浏览器开发者工具? - 学习 Web 开发 | MDN](https://developer.mozilla.org/zh-CN/docs/Learn/Common_questions/What_are_browser_developer_tools)
28+
29+
远程调试需要 [Zotero beta builds](https://www.zotero.org/support/beta_builds) 。Windows 开发者可下载 zip 版本,解压缩后即可使用,不会将正式版覆盖。
30+
31+
截止至最后编辑日期,Zotero 底层基于 Firefox 102 ESR。
32+
33+
1. 打开 Zotero Beta,打开 `菜单栏` -> `编辑` -> `首选项` -> `高级` -> `设置编辑器`,搜索 `debug` 并开启 `remote debugging`
34+
2. 使用 `--debugger` 参数启动 Zotero。
35+
也可以将启动参数写入快捷方式。
36+
3. 在 FireFox 102 ESR 中,找到`设置` -> `更多工具` -> `远程调试`(或者浏览器中输入:`about:debugging#/setup`),找到网络位置,输入 `localhost:6100`,点击确定添加即可。
37+
4. 选择 `localhost:6100`,然后点击进程中的多线程工具箱进行检查,可进入控制台、无障碍环境等进行调试
38+
39+
::: tip 模板用户无需手动配置
40+
41+
模板的启动脚本中已经进行了相关配置,因此你无需再手动执行以上步骤,直接打开 FireFox 远程调试即可。
42+
43+
:::
44+
45+
::: tip Zotero 正在包含此功能
46+
47+
Zotero 团队正在将开发者工具嵌入 Zotero,见 [PR #3387](https://github.com/zotero/zotero/pull/3387),此 PR 合并后即可直接从菜单呼出开发者工具,而无需安装 FireFox。
48+
49+
:::
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# 侧载插件
2+
3+
::: note Todo
4+
5+
此页说明如何将插件侧载入 Zotero,待完善,请参阅:[Setting Up a Plugin Development Environment](https://www.zotero.org/support/dev/client_coding/plugin_development#setting_up_a_plugin_development_environment)
6+
7+
:::
8+
9+
::: tip
10+
11+
使用社区模板的开发者,无需配置这些环境,只需要按照模板要求配置 Zotero 可执行文件路径和配置文件地址即可。模板中的启动脚本将为你自动完成以上步骤。
12+
13+
:::
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# 快速开始
2+
3+
此节以官方插件示例 [Make It Red](https://github.com/zotero/make-it-red/tree/main/src-2.0) 为例,说明 Zotero 插件的工作过程。
4+
5+
::: note Todo
6+
7+
待完善,请参阅插件仓库:[Make It Red](https://github.com/zotero/make-it-red/tree/main/src-2.0)
8+
9+
:::
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# 参考
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
author:
3+
- name: windingwind
4+
url: https://github.com/windingwind/
5+
- name: northword
6+
url: https://github.com/northword/
7+
---
8+
9+
# 引导脚本
10+
11+
引导脚本即 `bootstrap.js`,这是 Zotero 插件的入口脚本文件,此文件必须存在,否则插件将无法被安装。
12+
13+
## 内容
14+
15+
这个文件里必须包含以下几个钩子,Zotero 将在对应动作发生时调用对应的钩子。
16+
17+
### 生命周期钩子
18+
19+
```js
20+
// 插件被安装时调用
21+
function install(data, reason) {}
22+
23+
// 插件启动时调用
24+
function startup(data, reason) {}
25+
26+
// 插件被禁用时或 Zotero 被关闭时调用
27+
function shutdown(data, reason) {}
28+
29+
// 插件被卸载时调用
30+
function uninstall(data, reason) {}
31+
```
32+
33+
插件生命周期挂钩传递两个参数:
34+
35+
- 具有以下属性的对象:
36+
- `id` ,插件 ID
37+
- `version` ,插件版本
38+
- `rootURI` ,指向插件文件的字符串 URL。对于 XPI,这将是 `jar:file:///` URL。该值始终以斜杠结尾,因此您可以附加相对路径来获取与插件捆绑的文件的 URL(例如 `rootURI + 'style.css'` )。
39+
- 表示事件原因的数字,可以根据以下常量进行检查: `APP_STARTUP``APP_SHUTDOWN``ADDON_ENABLE``ADDON_DISABLE``ADDON_INSTALL``ADDON_UNINSTALL``ADDON_UPGRADE``ADDON_DOWNGRADE`
40+
41+
任何与特定窗口无关的初始化都应由 `startup` 触发,删除应由 `shutdown` 触发。
42+
43+
### 窗口钩子
44+
45+
```js
46+
// Zotero 主窗口加载完毕时调用
47+
function onMainWindowLoad({ window }) {}
48+
49+
// Zotero 主窗口被关闭时调用
50+
function onMainWindowUnload({ window }) {}
51+
```
52+
53+
窗口钩子传递一个参数:
54+
55+
- 具有包含目标窗口的 window 属性的对象
56+
57+
在某些平台上,主窗口可以在 Zotero 会话期间多次打开和关闭,因此任何与窗口相关的活动,例如修改主 UI、添加菜单或绑定快捷方式都必须由 `onMainWindowLoad` 执行以便新的主窗口包含您的更改。
58+
59+
然后,当调用 `onMainWindowUnload` 时,您必须删除对窗口或其中的对象的所有引用,取消任何计时器等,否则每次关闭窗口时都会有造成内存泄漏的风险。添加到窗口的 DOM 元素会在窗口关闭时自动销毁,因此只需删除 `shutdown()` 中的元素即可,可以通过循环遍历所有窗口来完成:
60+
61+
```js
62+
function shutdown() {
63+
var windows = Zotero.getMainWindows();
64+
for (let win of windows) {
65+
win.document.getElementById("make-it-red-stylesheet")?.remove();
66+
}
67+
}
68+
```
69+
70+
(目前仅支持一个主窗口,但有些用户可能会找到打开多个主窗口的方法,这将在未来版本中正式支持。)
71+
72+
::: tip
73+
74+
通常地,在 `startup` 中初始化插件地本地化系统、首选项、兼容性等,在 `onMainWindowLoad` 中初始化与 Zotero UI 有关的组件,如菜单、侧边栏、自定义列等。
75+
76+
:::
77+
78+
## 样例
79+
80+
关于 `bootstrap.js` 的样例,可参考前章提到的插件框架。它将插件的根对象注册到全局变量 `Zotero` 中,在任何引入了 Zotero 的位置均可使用。 或参考 Zutilo 插件。它将插件的根对象注册为一个全局变量。缺陷是在非主窗口内引入插件代码将较为复杂。
81+
82+
- [Zotero-addon-template/bootstrap.js at bootstrap · windingwind/Zotero-addon-template](https://github.com/windingwind/zotero-addon-template/blob/main/addon/bootstrap.js)
83+
- [Zutilo/bootstrap.js at master · wshanks/Zutilo](https://github.com/wshanks/Zutilo/blob/master/addon/bootstrap.js)
84+
85+
下面是以官方示例 `Make It Red``bootstrap.js`,它在 `startup()` 中通过 `Services.scriptloader.loadSubScript(rootURI + "make-it-red.js");` 将插件脚本载入,在 `make-it-red.js` 中,在 `Zotero` 下定义了一个对象 `MakeItRed`。在 `make-it-red.js` 加载完成后,调用 `MakeItRed` 对象下的方法完成插件初始化。
86+
87+
```js
88+
var MakeItRed;
89+
90+
function log(msg) {
91+
Zotero.debug("Make It Red: " + msg);
92+
}
93+
94+
function install() {
95+
log("Installed 2.0");
96+
}
97+
98+
async function startup({ id, version, rootURI }) {
99+
log("Starting 2.0");
100+
101+
Services.scriptloader.loadSubScript(rootURI + "make-it-red.js");
102+
MakeItRed.init({ id, version, rootURI });
103+
MakeItRed.addToAllWindows();
104+
await MakeItRed.main();
105+
}
106+
107+
function onMainWindowLoad({ window }) {
108+
MakeItRed.addToWindow(window);
109+
}
110+
111+
function onMainWindowUnload({ window }) {
112+
MakeItRed.removeFromWindow(window);
113+
}
114+
115+
function shutdown() {
116+
log("Shutting down 2.0");
117+
MakeItRed.removeFromAllWindows();
118+
MakeItRed = undefined;
119+
}
120+
121+
function uninstall() {
122+
log("Uninstalled 2.0");
123+
}
124+
```
125+
126+
## 参考资料
127+
128+
- [Zotero 7 for developers](https://www.zotero.org/support/dev/zotero_7_for_developers)
129+
- [bootstrapped-extension framework](https://www.devdoc.net/web/developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Bootstrapped_Extensions.html#Bootstrap_entry_points)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Zotero 条目
2+
3+
Item(条目)是 Zotero 中的基础数据元素。条目根据类型又可分为普通条目 (regular item),附件 (attachment item),笔记 (note item) 和注释 (annotation item)。Zotero 中,小到一个 PDF 附件中的一条高亮,大到一个集合(collection),都可以抽象为一个条目(Item)。
4+
5+
大多数插件的最终目的就是修改这些条目,例如,添加标签,修改信息,等等。
6+
7+
## 创建条目
8+
9+
```javascript
10+
new Zotero.Item(itemType);
11+
```
12+
13+
## 获取条目
14+
15+
```typescript
16+
declare Zotero.Items.get: (ids: Number | Number[]) => ZoteroItem | ZoteroItem[];
17+
declare Zotero.Items.getByLibraryAndKeyAsync: (
18+
libraryID: Number,
19+
itemKey: String
20+
) => Promise<ZoteroItem>;
21+
declare ZoteroPane.getSelectedItems: () => ZoteroItem[];
22+
```
23+
24+
通过 `Zotero.Items.get` / `getByLibraryAndKeyAsync` 来从 ID 获取条目;
25+
通过 `ZoteroPane.getSelectedItems` 获取当前选中的条目。
26+
27+
```javascript
28+
ZoteroPane.itemsView.getRow(2).ref;
29+
```
30+
31+
## 修改条目
32+
33+
对条目内容进行修改后,请使用 `item.save` / `item.saveTx()`来保存。
34+
35+
```javascript
36+
var item = new Zotero.Item("computerProgram");
37+
item.setType(Zotero.ItemTypes.getID("note"));
38+
```
39+
40+
## PDF 批注
41+
42+
> Zotero 中的批注也是 Item 类型!
43+
44+
```javascript
45+
Zotero.Items.getAll(1).then((i) => i.filter((t) => t.isAnnotation()));
46+
```
47+
48+
注释的属性:
49+
50+
- annotationText:高亮注释的内容
51+
- parentItem:获得 pdf 条目
52+
53+
```javascript
54+
const annotations = Zotero.Items.get(reader.itemID).getAnnotations();
55+
reader.navigate({ annotationKey: annotations[0].key });
56+
```
57+
58+
## 从对话框选择条目
59+
60+
```javascript
61+
let io = { dataIn: null, dataOut: null, deferred: Zotero.Promise.defer() };
62+
window.openDialog(
63+
"chrome://zotero/content/selectItemsDialog.xhtml",
64+
"",
65+
"chrome,dialog=no,centerscreen,resizable=yes",
66+
io
67+
);
68+
io.deferred.promise.then(() => console.debug(io));
69+
```
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# i18n
2+
3+
`locales/`
4+
5+
::: note Todo
6+
7+
Zotero 7 已全面使用 Fluent 作为本地化系统,请参考以下几个文档:
8+
9+
- [Zotero 7 for developers](https://www.zotero.org/support/dev/zotero_7_for_developers#localization)
10+
- [Fluent for Firefox Developers](https://firefox-source-docs.mozilla.org/l10n/fluent/tutorial.html#markup-localization)
11+
- [Fluent 文档](https://projectfluent.org/)
12+
13+
:::

0 commit comments

Comments
 (0)