/
action-dispatcher.ts
104 lines (92 loc) · 3.44 KB
/
action-dispatcher.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
import InfoWindow from '@typo3/backend/info-window';
import RegularEvent from '@typo3/core/event/regular-event';
import shortcutMenu from '@typo3/backend/toolbar/shortcut-menu';
import windowManager from '@typo3/backend/window-manager';
import moduleMenuApp from '@typo3/backend/module-menu';
import documentService from '@typo3/core/document-service';
import Utility from '@typo3/backend/utility';
declare type ActionDispatchArgument = string | HTMLElement | Event;
/**
* Module: @typo3/backend/action-dispatcher
*
* @example
* <a class="btn btn-default" href="#"
* data-dispatch-action="TYPO3.InfoWindow.showItem"
* data-dispatch-args-list="tt_content,123"
* ...
* data-dispatch-args="[$quot;tt_content",123]"
* ...
* data-dispatch-disabled>
*/
class ActionDispatcher {
private delegates: {[key: string]: (...args: ActionDispatchArgument[]) => void} = {};
public constructor() {
this.createDelegates();
documentService.ready().then((): void => this.registerEvents());
}
private static resolveArguments(element: HTMLElement): null | string[] {
if (element.dataset.dispatchArgs) {
// `"` is the only literal of a PHP `json_encode` that needs to be substituted
// all other payload values are expected to be serialized to unicode literals
const json = element.dataset.dispatchArgs.replace(/"/g, '"');
const args = JSON.parse(json);
return args instanceof Array ? Utility.trimItems(args) : null;
} else if (element.dataset.dispatchArgsList) {
const args = element.dataset.dispatchArgsList.split(',');
return Utility.trimItems(args);
}
return null;
}
private createDelegates(): void {
this.delegates = {
'TYPO3.InfoWindow.showItem': InfoWindow.showItem.bind(null),
'TYPO3.ShortcutMenu.createShortcut': shortcutMenu.createShortcut.bind(shortcutMenu),
'TYPO3.WindowManager.localOpen': windowManager.localOpen.bind(windowManager),
'TYPO3.ModuleMenu.showModule': moduleMenuApp.App.showModule.bind(moduleMenuApp.App),
};
}
private registerEvents(): void {
new RegularEvent('click', this.handleClickEvent.bind(this))
.delegateTo(document, '[data-dispatch-action]');
}
private handleClickEvent(evt: Event, target: HTMLElement): void {
evt.preventDefault();
this.delegateTo(evt, target);
}
private delegateTo(evt: Event, target: HTMLElement): void {
const disabled = target.hasAttribute('data-dispatch-disabled');
if (disabled) {
return;
}
const action = target.dataset.dispatchAction;
let args: ActionDispatchArgument[] = ActionDispatcher.resolveArguments(target);
if (args instanceof Array) {
args = args.map((arg: string): ActionDispatchArgument => {
switch (arg) {
case '{$target}':
return target;
case '{$event}':
return evt;
default:
return arg;
}
});
}
if (this.delegates[action]) {
this.delegates[action].apply(null, args || []);
}
}
}
export default new ActionDispatcher();