plugins: api.events.stop
Massimo Melina committed
Jun 5, 2024 at 10:38 UTC
69bbf3df20ed9e095c7db84e294c04ea0a56fb37
6 files changed
+22
-23
dev-plugins.md
+1
-1
@@ -383,7 +383,7 @@ api.events.on('deleting', async () => your-code-here)
383
384
### Stop, the way you prevent default behavior
385
386
-Some events allow you to stop their default behavior, by returning `false`.
386
+Some events allow you to stop their default behavior, by returning `api.events.stop`.
387
This is reported in the list below with the word "stoppable".
388
389
```js
frontend/src/fileMenu.ts
+13
-13
@@ -99,25 +99,25 @@ export function openFileMenu(entry: DirEntry, ev: MouseEvent, addToMenu: (FileMe
99
),
100
entry.cantOpen && h(Fragment, {}, hIcon('password', { style: { marginRight: '.5em' } }), t(MISSING_PERM)),
101
h('div', { className: 'file-menu' },
102
- dontBotherWithKeys(menu.map((e: FileMenuEntry, i) => // render menu entries
103
- isValidElement(e) ? e
104
- : e?.label && h('a', {
102
+ dontBotherWithKeys(menu.map((entry: FileMenuEntry, i) => // render menu entries
103
+ isValidElement(entry) ? entry
104
+ : entry?.label && h('a', {
105
key: i,
106
href: '#',
107
- ..._.omit(e, ['label', 'icon', 'toggled']),
108
- id: e.id && `menu-entry-${e.id}`,
109
- className: e.toggled ? 'toggled' : undefined,
110
- async onClick(event: MouseEvent) {
111
- if (!e.href)
112
- event.preventDefault()
113
- if (false !== await e.onClick?.(event))
107
+ ..._.omit(entry, ['label', 'icon', 'toggled']),
108
+ id: entry.id && `menu-entry-${entry.id}`,
109
+ className: entry.toggled ? 'toggled' : undefined,
110
+ async onClick(ev: MouseEvent) {
111
+ if (!entry.href)
112
+ ev.preventDefault()
113
+ if (false !== await entry.onClick?.(ev))
114
close()
115
}
116
},
117
- hIcon(e.icon || 'file'),
117
+ hIcon(entry.icon || 'file'),
118
h('label', { style: { display: 'flex', flexDirection: 'column' } },
119
- h('div', {}, e.label),
120
- h('small', {}, e.subLabel) )
119
+ h('div', {}, entry.label),
120
+ h('small', {}, entry.subLabel) )
121
)
122
))
123
)
frontend/src/upload.ts
+3
-3
@@ -64,10 +64,10 @@ setInterval(() => {
64
uploadState.eta = uploadState.speed && Math.round(left / uploadState.speed)
65
}, 5_000)
66
67
-window.onbeforeunload = e => {
67
+window.onbeforeunload = ev => {
68
if (!uploadState.qs.length) return
69
- e.preventDefault()
70
- return e.returnValue = t("Uploading") // modern browsers ignore this message
69
+ ev.preventDefault()
70
+ return ev.returnValue = t("Uploading") // modern browsers ignore this message
71
}
72
73
let reloadOnClose = false
src/events.ts
+3
-4
@@ -6,6 +6,7 @@ const LISTENERS_SUFFIX = '\0listeners'
6
7
export class BetterEventEmitter {
8
protected listeners = new Map<string, Listeners>()
9
+ stop = Symbol()
10
on(event: string | string[], listener: Listener, { warnAfter=10 }={}) {
11
if (typeof event === 'string')
12
event = [event]
@@ -56,15 +57,13 @@ export class BetterEventEmitter {
57
ret.push(res)
58
}
59
return Object.assign(ret, {
59
- preventDefault: () => ret.some(r => r === false)
60
+ isDefaultPrevented: () => ret.some(r => r === this.stop),
61
})
62
}
63
emitAsync(event: string, ...args: any[]) {
64
const ret = Promise.all(this.emit(event, ...args) || [])
65
return Object.assign(ret, {
65
- async preventDefault() {
66
- return (await ret).some((x: any) => x === false)
67
- }
66
+ isDefaultPrevented: async () => (await ret).some((r: any) => r === this.stop)
67
})
68
}
69
}
src/misc.ts
+1
-1
@@ -132,7 +132,7 @@ export async function deleteNode(ctx: Koa.Context, node: VfsNode, uri: string) {
132
if (statusCodeForMissingPerm(node, 'can_delete', ctx))
133
return ctx.status
134
try {
135
- if (await events.emitAsync('deleting', { node, ctx }).preventDefault())
135
+ if (await events.emitAsync('deleting', { node, ctx }).isDefaultPrevented())
136
return null // stop
137
ctx.logExtra(null, { target: decodeURI(uri) })
138
await rm(source, { recursive: true })
src/upload.ts
+1
-1
@@ -116,7 +116,7 @@ export function uploadWriter(base: VfsNode, path: string, ctx: Koa.Context) {
116
// allow plugins to mess with the write-stream, because the read-stream can be complicated in case of multipart
117
const obj = { ctx, writeStream }
118
const resEvent = events.emit('uploadStart', obj)
119
- if (resEvent?.preventDefault()) return
119
+ if (resEvent?.isDefaultPrevented()) return
120
121
const fileStream = resuming ? fs.createWriteStream(resumable, { flags: 'r+', start: resume })
122
: fs.createWriteStream(tempName)