Skip to content

Commit 6a3091c

Browse files
authored
Merge pull request #13 from RaymondWJang/start-extension
Start extension!!!
2 parents 166227c + 9fc4b62 commit 6a3091c

File tree

15 files changed

+7417
-1
lines changed

15 files changed

+7417
-1
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,8 @@ cython_debug/
159159
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
160160
.idea/
161161
.vscode/
162-
/data
162+
/data
163+
164+
# javascript
165+
node_modules
166+
.cache*

docs/plugin/notes.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Notes for the Zotero Plugin
2+
3+
## Plugin format
4+
5+
Bootstrapped Zotero plugins in Zotero 7 require two components:
6+
7+
- A WebExtension-style manifest.json file, as described above
8+
- A bootstrap.js file containing functions to handle various events:
9+
- Plugin lifecycle hooks
10+
- Window hooks
11+
12+
## Hooks
13+
14+
Plugin lifecycle hooks are modeled after the legacy Mozilla bootstrapped-extension framework:
15+
16+
17+
Plugin lifecycle hooks are passed two parameters:
18+
19+
- An object with these properties:
20+
- id, the plugin id
21+
- version, the plugin version
22+
- rootURI, a string URL pointing to the plugin's files. For XPIs, this will be a jar:file:/// URL. This value will always end in a slash, so you can append a relative path to get a URL for a file bundled with your plugin (e.g., rootURI + 'style.css').
23+
- A number representing the reason for the event, which can be checked against the following constants: APP_STARTUP, APP_SHUTDOWN, ADDON_ENABLE, ADDON_DISABLE, ADDON_INSTALL, ADDON_UNINSTALL, ADDON_UPGRADE, ADDON_DOWNGRADE
24+
25+
Window hooks are passed one parameter:
26+
27+
- An object with a window property containing the target window
28+
29+
30+
### `startup()`
31+
32+
Any initialization unrelated to specific windows should be triggered by startup
33+
34+
### `onMainWindowLoad()`
35+
36+
(Zotero 7 only)
37+
38+
On some platforms, the main window can be opened and closed multiple times during a Zotero session, so any window-related activities, such as modifying the main UI, adding menus, or binding shortcuts must be performed by onMainWindowLoad so that new main windows contain your changes.
39+
40+
### `onMainWindowUnload()`
41+
42+
(Zotero 7 only)
43+
44+
You must then remove all references to a window or objects within it, cancel any timers, etc., when onMainWindowUnload is called, or else you'll risk creating a memory leak every time the window is closed.
45+
46+
### `shutdown()`
47+
48+
removal should be triggered by shutdown.
49+
50+
DOM elements added to a window will be automatically destroyed when the window is closed, so you only need to remove those in shutdown(), which you can do by cycling through all windows:
51+
52+
```js
53+
function shutdown() {
54+
var windows = Zotero.getMainWindows();
55+
for (let win of windows) {
56+
win.document.getElementById('make-it-red-stylesheet')?.remove();
57+
}
58+
}
59+
```
60+
61+
### `install()`
62+
63+
### `uninstall()`
64+
65+
## Features
66+
67+
### Panes
68+
69+
Zotero now includes a built-in function to register a preference pane. In your plugin's startup function:
70+
71+
```js
72+
Zotero.PreferencePanes.register({
73+
pluginID: '[email protected]',
74+
src: 'prefs.xhtml',
75+
scripts: ['prefs.js'],
76+
stylesheets: ['prefs.css'],
77+
});
78+
```
79+
80+
See also: https://github.com/zotero/zotero/blob/main/chrome/content/zotero/xpcom/preferencePanes.js
81+
82+
## References
83+
- https://www.zotero.org/support/dev/zotero_7_for_developers - the elusive description of what in the heck zotero plugins actually are
84+
- [preferencesPanes.js](https://github.com/zotero/zotero/blob/main/chrome/content/zotero/xpcom/preferencePanes.js) - settings for preferences panes

zotero/.eslintrc.json

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
{
2+
"root": true,
3+
"env": {
4+
"browser": true,
5+
"es6": true,
6+
"node": true
7+
},
8+
"extends": [
9+
"eslint:recommended",
10+
"plugin:@typescript-eslint/recommended",
11+
"plugin:@typescript-eslint/eslint-recommended",
12+
"plugin:@typescript-eslint/recommended-requiring-type-checking"
13+
],
14+
"parser": "@typescript-eslint/parser",
15+
"parserOptions": {
16+
"project": "tsconfig.json",
17+
"sourceType": "module"
18+
},
19+
"plugins": [
20+
"eslint-plugin-import",
21+
"eslint-plugin-prefer-arrow",
22+
"@typescript-eslint",
23+
"@typescript-eslint/eslint-plugin"
24+
],
25+
"rules": {
26+
"@typescript-eslint/adjacent-overload-signatures": "error",
27+
"@typescript-eslint/array-type": [
28+
"error",
29+
{
30+
"default": "array"
31+
}
32+
],
33+
"@typescript-eslint/await-thenable": "error",
34+
"@typescript-eslint/ban-ts-comment": "warn",
35+
"@typescript-eslint/ban-types": [
36+
"warn",
37+
{
38+
"types": {
39+
"Object": {
40+
"message": "Avoid using the `Object` type. Did you mean `object`?"
41+
},
42+
"Function": {
43+
"message": "Avoid using the `Function` type. Prefer a specific function type, like `() => void`."
44+
},
45+
"Boolean": {
46+
"message": "Avoid using the `Boolean` type. Did you mean `boolean`?"
47+
},
48+
"Number": {
49+
"message": "Avoid using the `Number` type. Did you mean `number`?"
50+
},
51+
"String": {
52+
"message": "Avoid using the `String` type. Did you mean `string`?"
53+
},
54+
"Symbol": {
55+
"message": "Avoid using the `Symbol` type. Did you mean `symbol`?"
56+
}
57+
}
58+
}
59+
],
60+
"@typescript-eslint/consistent-type-assertions": "error",
61+
"@typescript-eslint/dot-notation": "error",
62+
"@typescript-eslint/explicit-module-boundary-types": "warn",
63+
"@typescript-eslint/indent": [
64+
"error",
65+
2
66+
],
67+
"@typescript-eslint/member-delimiter-style": [
68+
"error",
69+
{
70+
"multiline": {
71+
"delimiter": "none",
72+
"requireLast": false
73+
},
74+
"singleline": {
75+
"delimiter": "comma",
76+
"requireLast": false
77+
}
78+
}
79+
],
80+
"@typescript-eslint/member-ordering": "off",
81+
"@typescript-eslint/naming-convention": "off",
82+
"@typescript-eslint/no-array-constructor": "error",
83+
"@typescript-eslint/no-empty-function": "error",
84+
"@typescript-eslint/no-empty-interface": "error",
85+
"@typescript-eslint/no-explicit-any": "off",
86+
"@typescript-eslint/no-extra-non-null-assertion": "error",
87+
"@typescript-eslint/no-extra-semi": "error",
88+
"@typescript-eslint/no-floating-promises": "error",
89+
"@typescript-eslint/no-for-in-array": "error",
90+
"@typescript-eslint/no-implied-eval": "off",
91+
"@typescript-eslint/no-inferrable-types": "error",
92+
"@typescript-eslint/no-misused-new": "error",
93+
"@typescript-eslint/no-misused-promises": "error",
94+
"@typescript-eslint/no-namespace": "error",
95+
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
96+
"@typescript-eslint/no-non-null-assertion": "warn",
97+
"@typescript-eslint/no-parameter-properties": "off",
98+
"@typescript-eslint/no-shadow": [
99+
"error",
100+
{
101+
"hoist": "all"
102+
}
103+
],
104+
"@typescript-eslint/no-this-alias": "error",
105+
"@typescript-eslint/no-unnecessary-type-assertion": "error",
106+
"@typescript-eslint/no-unsafe-assignment": "off",
107+
"@typescript-eslint/no-unsafe-call": "off",
108+
"@typescript-eslint/no-unsafe-member-access": "off",
109+
"@typescript-eslint/no-unsafe-return": "error",
110+
"@typescript-eslint/no-unused-expressions": "error",
111+
"@typescript-eslint/no-unused-vars": [
112+
"error",
113+
{
114+
"argsIgnorePattern": "^_"
115+
}
116+
],
117+
"@typescript-eslint/no-use-before-define": "off",
118+
"@typescript-eslint/no-var-requires": "off",
119+
"@typescript-eslint/prefer-as-const": "error",
120+
"@typescript-eslint/prefer-for-of": "error",
121+
"@typescript-eslint/prefer-function-type": "error",
122+
"@typescript-eslint/prefer-namespace-keyword": "error",
123+
"@typescript-eslint/prefer-regexp-exec": "off",
124+
"@typescript-eslint/quotes": [
125+
"error",
126+
"single",
127+
{
128+
"avoidEscape": true
129+
}
130+
],
131+
"@typescript-eslint/require-await": "error",
132+
"@typescript-eslint/restrict-plus-operands": "error",
133+
"@typescript-eslint/restrict-template-expressions": "off",
134+
"@typescript-eslint/semi": [
135+
"error",
136+
"never"
137+
],
138+
"@typescript-eslint/triple-slash-reference": [
139+
"error",
140+
{
141+
"path": "always",
142+
"types": "prefer-import",
143+
"lib": "always"
144+
}
145+
],
146+
"@typescript-eslint/unbound-method": "error",
147+
"@typescript-eslint/unified-signatures": "error",
148+
"arrow-body-style": "error",
149+
"arrow-parens": [
150+
"error",
151+
"as-needed"
152+
],
153+
"brace-style": [
154+
"error",
155+
"stroustrup",
156+
{
157+
"allowSingleLine": true
158+
}
159+
],
160+
"comma-dangle": [
161+
"error",
162+
{
163+
"objects": "always-multiline",
164+
"arrays": "always-multiline",
165+
"functions": "never"
166+
}
167+
],
168+
"complexity": "off",
169+
"constructor-super": "error",
170+
"curly": [
171+
"error",
172+
"multi-line"
173+
],
174+
"eol-last": "error",
175+
"eqeqeq": [
176+
"error",
177+
"smart"
178+
],
179+
"guard-for-in": "error",
180+
"id-blacklist": [
181+
"error",
182+
"any",
183+
"Number",
184+
"number",
185+
"String",
186+
"string",
187+
"Boolean",
188+
"boolean",
189+
"Undefined",
190+
"undefined"
191+
],
192+
"id-match": "error",
193+
"import/order": "off",
194+
"linebreak-style": [
195+
"error",
196+
"unix"
197+
],
198+
"max-classes-per-file": "off",
199+
"max-len": [
200+
"warn",
201+
{
202+
"code": 240
203+
}
204+
],
205+
"new-parens": "off",
206+
"no-array-constructor": "off",
207+
"no-bitwise": "error",
208+
"no-caller": "error",
209+
"no-cond-assign": "off",
210+
"no-console": "error",
211+
"no-debugger": "error",
212+
"no-empty": [
213+
"error",
214+
{
215+
"allowEmptyCatch": true
216+
}
217+
],
218+
"no-empty-function": "off",
219+
"no-eval": "error",
220+
"no-extra-semi": "off",
221+
"no-fallthrough": "off",
222+
"no-implied-eval": "off",
223+
"no-invalid-this": "off",
224+
"no-irregular-whitespace": "error",
225+
"no-magic-numbers": "off",
226+
"@typescript-eslint/no-magic-numbers": "off",
227+
"no-new-wrappers": "error",
228+
"no-redeclare": "error",
229+
"no-throw-literal": "error",
230+
"no-trailing-spaces": "error",
231+
"no-undef-init": "error",
232+
"no-underscore-dangle": [
233+
"error",
234+
{
235+
"allowAfterThis": true
236+
}
237+
],
238+
"no-unsafe-finally": "error",
239+
"no-unused-labels": "error",
240+
"no-unused-vars": "off",
241+
"no-var": "error",
242+
"object-shorthand": "error",
243+
"one-var": [
244+
"off",
245+
"never"
246+
],
247+
"prefer-arrow/prefer-arrow-functions": [
248+
"error",
249+
{
250+
"allowStandaloneDeclarations": true
251+
}
252+
],
253+
"prefer-const": [
254+
"error",
255+
{
256+
"destructuring": "all"
257+
}
258+
],
259+
"prefer-object-spread": "error",
260+
"prefer-template": "error",
261+
"quote-props": [
262+
"error",
263+
"as-needed"
264+
],
265+
"radix": "off",
266+
"require-await": "off",
267+
"space-before-function-paren": [
268+
"error",
269+
{
270+
"anonymous": "never",
271+
"named": "never",
272+
"asyncArrow": "always"
273+
}
274+
],
275+
"spaced-comment": [
276+
"error",
277+
"always",
278+
{
279+
"markers": [
280+
"/"
281+
]
282+
}
283+
],
284+
"use-isnan": "error",
285+
"valid-typeof": "off",
286+
"yoda": "error",
287+
"@typescript-eslint/consistent-type-definitions": "off",
288+
"no-new-func": "off"
289+
},
290+
"ignorePatterns": [
291+
"webpack.config.ts",
292+
"util/*.ts",
293+
"minitests/*.ts",
294+
"content/minitests/*.ts"
295+
]
296+
}

0 commit comments

Comments
 (0)