@punica/editor 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/impl/activityBar/index.js +75 -0
- package/dist/impl/commands/index.js +52 -0
- package/dist/impl/extensions/active/decorators/base.js +19 -0
- package/dist/impl/extensions/active/decorators/configuration/index.js +20 -0
- package/dist/impl/extensions/active/decorators/index.js +3 -0
- package/dist/impl/extensions/active/decorators/moduleLoader/index.js +29 -0
- package/dist/impl/extensions/active/decorators/views/index.js +34 -0
- package/dist/impl/extensions/active/getter/index.js +28 -0
- package/dist/impl/extensions/active/index.js +14 -0
- package/dist/impl/extensions/analysis/decorators/activationEvents/commands/base.js +2 -0
- package/dist/impl/extensions/analysis/decorators/activationEvents/commands/index.js +2 -0
- package/dist/impl/extensions/analysis/decorators/activationEvents/commands/onCommand.js +16 -0
- package/dist/impl/extensions/analysis/decorators/activationEvents/commands/onExtension.js +16 -0
- package/dist/impl/extensions/analysis/decorators/activationEvents/handler/index.js +32 -0
- package/dist/impl/extensions/analysis/decorators/activationEvents/index.js +29 -0
- package/dist/impl/extensions/analysis/decorators/base.js +19 -0
- package/dist/impl/extensions/analysis/decorators/commands/index.js +37 -0
- package/dist/impl/extensions/analysis/decorators/index.js +4 -0
- package/dist/impl/extensions/analysis/decorators/keybindings/index.js +65 -0
- package/dist/impl/extensions/analysis/decorators/menus/index.js +20 -0
- package/dist/impl/extensions/analysis/index.js +15 -0
- package/dist/impl/extensions/analysis/reader/index.js +31 -0
- package/dist/impl/extensions/index.js +76 -0
- package/dist/impl/history/index.js +57 -0
- package/dist/impl/index.js +6 -4
- package/dist/impl/keyboardShortcuts/index.js +67 -0
- package/dist/impl/layout/index.js +50 -0
- package/dist/impl/statusbar/index.js +81 -0
- package/dist/impl/timeServer/index.js +49 -0
- package/dist/index.js +8 -6
- package/package.json +8 -24
- package/types/index.d.ts +4 -13
- package/types/punica.module.activityBar.d.ts +21 -0
- package/types/punica.module.commands.d.ts +10 -7
- package/types/punica.module.extensions.d.ts +122 -4
- package/types/punica.module.history.d.ts +18 -0
- package/types/punica.module.keyboardShortcuts.d.ts +6 -1
- package/types/punica.module.statusbar.d.ts +6 -5
- package/types/punica.module.view.d.ts +1 -1
- package/types/punica.types.d.ts +11 -0
- package/dist/impl/commands.js +0 -72
- package/dist/impl/dragDrop.js +0 -119
- package/dist/impl/extensions.js +0 -45
- package/dist/impl/keyboardShortcuts.js +0 -67
- package/dist/impl/layout.js +0 -59
- package/dist/impl/statusbar.js +0 -75
- package/dist/impl/timeServer.js +0 -57
- /package/dist/impl/{view.js → view/index.js} +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
class ActivityBarManager {
|
|
2
|
+
#primaryItems = new Map();
|
|
3
|
+
#secondaryItems = new Map();
|
|
4
|
+
#content;
|
|
5
|
+
#primaryContent;
|
|
6
|
+
#secondaryContent;
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
#initiliazeContent() {
|
|
11
|
+
const layoutManager = window.punica.Layout.manager;
|
|
12
|
+
const activityBarContent = layoutManager.getItem('activityBar').content;
|
|
13
|
+
this.#content = document.createElement('punica-row');
|
|
14
|
+
this.#primaryContent = document.createElement('punica-col');
|
|
15
|
+
this.#secondaryContent = document.createElement('punica-col');
|
|
16
|
+
this.#content.setAttribute('direction', 'column');
|
|
17
|
+
this.#content.setAttribute('alignitems', 'stretch');
|
|
18
|
+
this.#content.appendChild(this.#primaryContent);
|
|
19
|
+
this.#content.appendChild(this.#secondaryContent);
|
|
20
|
+
activityBarContent?.appendChild(this.#content);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
*/
|
|
25
|
+
constructor() { }
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
* @param alignment
|
|
29
|
+
* @param item
|
|
30
|
+
*/
|
|
31
|
+
addItem(item) {
|
|
32
|
+
if (!this.#content) {
|
|
33
|
+
this.#initiliazeContent();
|
|
34
|
+
}
|
|
35
|
+
const button = document.createElement('punica-button');
|
|
36
|
+
button.setAttribute('id', item.id);
|
|
37
|
+
button.setAttribute('disabled', 'false');
|
|
38
|
+
button.setAttribute('title', item.title);
|
|
39
|
+
button.onclick = () => { };
|
|
40
|
+
button.innerHTML = `<punica-icon size="xlarge">${item.icon}</punica-icon>`;
|
|
41
|
+
button.className = 'extension';
|
|
42
|
+
if (item.alignment === 'primary') {
|
|
43
|
+
this.#primaryItems.set(item.id, item);
|
|
44
|
+
this.#primaryContent.appendChild(button);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
this.#secondaryItems.set(item.id, item);
|
|
48
|
+
this.#secondaryContent.appendChild(button);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
* @param itemId
|
|
54
|
+
*/
|
|
55
|
+
removeItem(itemId) {
|
|
56
|
+
if (this.#primaryItems.has(itemId)) {
|
|
57
|
+
const itemElement = this.#primaryContent.querySelector('#' + itemId);
|
|
58
|
+
if (itemElement) {
|
|
59
|
+
this.#primaryContent.removeChild(itemElement);
|
|
60
|
+
this.#primaryItems.delete(itemId);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if (this.#secondaryItems.has(itemId)) {
|
|
64
|
+
const itemElement = this.#secondaryContent.querySelector('#' + itemId);
|
|
65
|
+
if (itemElement) {
|
|
66
|
+
this.#secondaryContent.removeChild(itemElement);
|
|
67
|
+
this.#secondaryItems.delete(itemId);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const activityBar = {
|
|
73
|
+
manager: new ActivityBarManager()
|
|
74
|
+
};
|
|
75
|
+
export default activityBar;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
class CommandManager {
|
|
2
|
+
#commands = new Map();
|
|
3
|
+
#disposables = new Map();
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param commandName
|
|
7
|
+
* @param command
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
registerCommand(commandName, command) {
|
|
11
|
+
const disposable = {
|
|
12
|
+
dispose: () => {
|
|
13
|
+
this.#commands.delete(commandName);
|
|
14
|
+
this.#disposables.delete(commandName);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
command.disposable = disposable;
|
|
18
|
+
this.#disposables.set(commandName, disposable);
|
|
19
|
+
this.#commands.set(commandName, command);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @param commandName
|
|
24
|
+
* @param args
|
|
25
|
+
*/
|
|
26
|
+
executeCommand(commandName, ...args) {
|
|
27
|
+
const command = this.#commands.get(commandName);
|
|
28
|
+
if (command) {
|
|
29
|
+
command.execute(...args);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
console.error(`Command ${commandName} not found`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @param commandName
|
|
38
|
+
*/
|
|
39
|
+
disposeCommand(commandName) {
|
|
40
|
+
const disposable = this.#disposables.get(commandName);
|
|
41
|
+
if (disposable) {
|
|
42
|
+
disposable.dispose();
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.error(`Command ${commandName} not found or already disposed`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const commands = {
|
|
50
|
+
manager: new CommandManager()
|
|
51
|
+
};
|
|
52
|
+
export default commands;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class BaseDecorator {
|
|
2
|
+
#decorator;
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param decorator
|
|
6
|
+
*/
|
|
7
|
+
constructor(decorator) {
|
|
8
|
+
this.#decorator = decorator;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param extension
|
|
13
|
+
*/
|
|
14
|
+
async execute() {
|
|
15
|
+
const extension = await this.#decorator.execute();
|
|
16
|
+
return extension;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export default BaseDecorator;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import BaseReader from '../base';
|
|
2
|
+
class Decorator extends BaseReader {
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param decorator
|
|
6
|
+
*/
|
|
7
|
+
constructor(decorator) {
|
|
8
|
+
super(decorator);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param extension
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
async execute() {
|
|
16
|
+
const extension = await super.execute();
|
|
17
|
+
return extension;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export default Decorator;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import BaseReader from '../base';
|
|
2
|
+
class Decorator extends BaseReader {
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param decorator
|
|
6
|
+
*/
|
|
7
|
+
constructor(decorator) {
|
|
8
|
+
super(decorator);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param extension
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
async execute() {
|
|
16
|
+
try {
|
|
17
|
+
const extension = await super.execute();
|
|
18
|
+
const extensionMain = `${extension.moduleURL}${extension.main}`;
|
|
19
|
+
const module = await import(/* webpackIgnore: true */ `${extensionMain}`);
|
|
20
|
+
const extensionModule = module.default;
|
|
21
|
+
extension.module = extensionModule;
|
|
22
|
+
return extension;
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
throw new Error();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export default Decorator;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import BaseReader from '../base';
|
|
2
|
+
class Decorator extends BaseReader {
|
|
3
|
+
/**
|
|
4
|
+
* Creates an instance of Decorator.
|
|
5
|
+
* @param decorator An ExtensionDecorator instance to decorate.
|
|
6
|
+
*/
|
|
7
|
+
constructor(decorator) {
|
|
8
|
+
super(decorator);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Reads the extension and adds it to the relevant views.
|
|
12
|
+
* @returns A promise resolving to the read extension.
|
|
13
|
+
*/
|
|
14
|
+
async execute() {
|
|
15
|
+
const extension = await super.execute();
|
|
16
|
+
const { integrations } = extension;
|
|
17
|
+
if (!integrations) {
|
|
18
|
+
return extension;
|
|
19
|
+
}
|
|
20
|
+
const { views } = integrations;
|
|
21
|
+
if (!views) {
|
|
22
|
+
return extension;
|
|
23
|
+
}
|
|
24
|
+
const { activityBar, statusBar } = views;
|
|
25
|
+
if (activityBar) {
|
|
26
|
+
window.punica.ActivityBar.manager.addItem(activityBar);
|
|
27
|
+
}
|
|
28
|
+
if (statusBar) {
|
|
29
|
+
window.punica.Statusbar.manager.addItem(statusBar);
|
|
30
|
+
}
|
|
31
|
+
return extension;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export default Decorator;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class Getter {
|
|
2
|
+
#name;
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param name
|
|
6
|
+
*/
|
|
7
|
+
constructor(name) {
|
|
8
|
+
this.#name = name;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param extension
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
execute() {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const extensionManager = window.punica.Extensions.manager;
|
|
18
|
+
const extension = extensionManager.getExtension(this.#name);
|
|
19
|
+
if (extension) {
|
|
20
|
+
resolve(extension);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
reject(new Error('Extension not found'));
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export default Getter;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Getter from './getter';
|
|
2
|
+
import { Views, Configuration, ModuleLoader } from './decorators';
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param extensionName
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
export const activeExtension = (extensionName) => {
|
|
9
|
+
const getter = new Getter(extensionName);
|
|
10
|
+
const moduleLoader = new ModuleLoader(getter);
|
|
11
|
+
const views = new Views(moduleLoader);
|
|
12
|
+
const configuration = new Configuration(views);
|
|
13
|
+
return configuration;
|
|
14
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export class EventHandler {
|
|
2
|
+
#commandMap;
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
constructor() {
|
|
7
|
+
this.#commandMap = new Map();
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param eventType
|
|
12
|
+
* @param commandClass
|
|
13
|
+
*/
|
|
14
|
+
register(eventType, commandClass) {
|
|
15
|
+
this.#commandMap.set(eventType, commandClass);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
* @param event
|
|
20
|
+
*/
|
|
21
|
+
handleEvent(event) {
|
|
22
|
+
const [eventType, eventDetail] = event.split(':');
|
|
23
|
+
const CommandClass = this.#commandMap.get(eventType);
|
|
24
|
+
if (CommandClass) {
|
|
25
|
+
const command = new CommandClass(eventDetail);
|
|
26
|
+
command.execute();
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
console.warn(`Unknown event type: ${eventType}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import BaseReader from '../base';
|
|
2
|
+
import { EventHandler } from './handler';
|
|
3
|
+
import { OnCommand, OnExtensionCommand } from './commands';
|
|
4
|
+
class Decorator extends BaseReader {
|
|
5
|
+
#eventHandler;
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param decorator
|
|
9
|
+
*/
|
|
10
|
+
constructor(decorator) {
|
|
11
|
+
super(decorator);
|
|
12
|
+
this.#eventHandler = new EventHandler();
|
|
13
|
+
this.#eventHandler.register('onExtension', OnExtensionCommand);
|
|
14
|
+
this.#eventHandler.register('onCommand', OnCommand);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
async execute() {
|
|
21
|
+
const extension = await super.execute();
|
|
22
|
+
const { activationEvents } = extension;
|
|
23
|
+
if (activationEvents) {
|
|
24
|
+
activationEvents.forEach((event) => this.#eventHandler.handleEvent(event));
|
|
25
|
+
}
|
|
26
|
+
return extension;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export default Decorator;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class BaseDecorator {
|
|
2
|
+
#decorator;
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param decorator
|
|
6
|
+
*/
|
|
7
|
+
constructor(decorator) {
|
|
8
|
+
this.#decorator = decorator;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param extension
|
|
13
|
+
*/
|
|
14
|
+
async execute() {
|
|
15
|
+
const extension = await this.#decorator.execute();
|
|
16
|
+
return extension;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export default BaseDecorator;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import BaseReader from '../base';
|
|
2
|
+
class Decorator extends BaseReader {
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param decorator
|
|
6
|
+
*/
|
|
7
|
+
constructor(decorator) {
|
|
8
|
+
super(decorator);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param extension
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
async execute() {
|
|
16
|
+
const extension = await super.execute();
|
|
17
|
+
const { integrations } = extension;
|
|
18
|
+
if (integrations) {
|
|
19
|
+
const { commands } = integrations;
|
|
20
|
+
if (commands) {
|
|
21
|
+
commands.forEach((item) => {
|
|
22
|
+
const { command, title } = item;
|
|
23
|
+
const commandsManager = window.punica.Commands.manager;
|
|
24
|
+
const extensionsManager = window.punica.Extensions.manager;
|
|
25
|
+
commandsManager.registerCommand(command, {
|
|
26
|
+
title,
|
|
27
|
+
execute: () => {
|
|
28
|
+
extensionsManager.activate(extension.name);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return extension;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export default Decorator;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import BaseReader from '../base';
|
|
2
|
+
class Decorator extends BaseReader {
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param shortcut
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
#parseShortcut(shortcut) {
|
|
9
|
+
const parts = shortcut.split('+').map((part) => part.trim().toLowerCase());
|
|
10
|
+
const shortcutObj = {
|
|
11
|
+
key: ''
|
|
12
|
+
};
|
|
13
|
+
parts.forEach((part) => {
|
|
14
|
+
switch (part) {
|
|
15
|
+
case 'ctrl':
|
|
16
|
+
shortcutObj.ctrlKey = true;
|
|
17
|
+
break;
|
|
18
|
+
case 'shift':
|
|
19
|
+
shortcutObj.shiftKey = true;
|
|
20
|
+
break;
|
|
21
|
+
case 'alt':
|
|
22
|
+
shortcutObj.altKey = true;
|
|
23
|
+
break;
|
|
24
|
+
case 'meta':
|
|
25
|
+
case 'cmd':
|
|
26
|
+
case 'command':
|
|
27
|
+
shortcutObj.metaKey = true;
|
|
28
|
+
break;
|
|
29
|
+
default:
|
|
30
|
+
shortcutObj.key = part;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
return shortcutObj;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @param decorator
|
|
38
|
+
*/
|
|
39
|
+
constructor(decorator) {
|
|
40
|
+
super(decorator);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @returns
|
|
45
|
+
*/
|
|
46
|
+
async execute() {
|
|
47
|
+
const extension = await super.execute();
|
|
48
|
+
const { integrations } = extension;
|
|
49
|
+
if (integrations) {
|
|
50
|
+
const { keybindings } = integrations;
|
|
51
|
+
if (keybindings) {
|
|
52
|
+
keybindings.forEach((item) => {
|
|
53
|
+
const { command, key } = item;
|
|
54
|
+
const keyboardShortcutsManager = window.punica.KeyboardShortcuts.manager;
|
|
55
|
+
keyboardShortcutsManager.registerShortcut({
|
|
56
|
+
command,
|
|
57
|
+
keys: [this.#parseShortcut(key)]
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return extension;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export default Decorator;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import BaseReader from '../base';
|
|
2
|
+
class Decorator extends BaseReader {
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param decorator
|
|
6
|
+
*/
|
|
7
|
+
constructor(decorator) {
|
|
8
|
+
super(decorator);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param extension
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
async execute() {
|
|
16
|
+
const extension = await super.execute();
|
|
17
|
+
return extension;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export default Decorator;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import Reader from './reader';
|
|
2
|
+
import { ActivationEvents, Commands, Keybindings, Menus } from './decorators';
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param extensionURL
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
export const analysisExtension = (extensionURL) => {
|
|
9
|
+
const reader = new Reader(extensionURL);
|
|
10
|
+
const commands = new Commands(reader);
|
|
11
|
+
const keybindings = new Keybindings(commands);
|
|
12
|
+
const menus = new Menus(keybindings);
|
|
13
|
+
const activationEvents = new ActivationEvents(menus);
|
|
14
|
+
return activationEvents;
|
|
15
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import yaml from 'yaml';
|
|
2
|
+
class Reader {
|
|
3
|
+
#extensionURL;
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param extensionURL
|
|
7
|
+
*/
|
|
8
|
+
constructor(extensionURL) {
|
|
9
|
+
this.#extensionURL = extensionURL;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param extension
|
|
14
|
+
* @returns
|
|
15
|
+
*/
|
|
16
|
+
execute() {
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
const extensionConfig = `${this.#extensionURL}.punica/config.yaml`;
|
|
19
|
+
fetch(extensionConfig, { method: 'GET' })
|
|
20
|
+
.then((res) => {
|
|
21
|
+
return res.text();
|
|
22
|
+
})
|
|
23
|
+
.then((config) => {
|
|
24
|
+
const extension = yaml.parse(config);
|
|
25
|
+
extension.moduleURL = this.#extensionURL;
|
|
26
|
+
resolve(extension);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export default Reader;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { analysisExtension } from './analysis';
|
|
2
|
+
import { activeExtension } from './active';
|
|
3
|
+
class ExtensionManager {
|
|
4
|
+
#extensions;
|
|
5
|
+
#activeExtension;
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
constructor() {
|
|
10
|
+
this.#extensions = new Map();
|
|
11
|
+
this.#activeExtension = new Map();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param extensionURL
|
|
16
|
+
* @param args
|
|
17
|
+
*/
|
|
18
|
+
async load(extensionURL, ...args) {
|
|
19
|
+
try {
|
|
20
|
+
const extensionURLs = [extensionURL, ...args];
|
|
21
|
+
for (const url of extensionURLs) {
|
|
22
|
+
const analysis = analysisExtension(url);
|
|
23
|
+
const extension = await analysis.execute();
|
|
24
|
+
this.#extensions.set(extension.name, extension);
|
|
25
|
+
this.#activeExtension.set(extension.name, false);
|
|
26
|
+
console.log(extension.name, extension);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error(error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
*
|
|
35
|
+
* @param extensionName
|
|
36
|
+
*/
|
|
37
|
+
async activate(extensionName) {
|
|
38
|
+
if (this.#activeExtension.get(extensionName)) {
|
|
39
|
+
console.log(`Extension "${extensionName}" is already active.`);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const extension = this.#extensions.get(extensionName);
|
|
43
|
+
if (!extension) {
|
|
44
|
+
console.error(`Extension "${extensionName}" not found.`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const active = activeExtension(extensionName);
|
|
49
|
+
const activatedExtension = await active.execute();
|
|
50
|
+
if (activatedExtension &&
|
|
51
|
+
activatedExtension.module &&
|
|
52
|
+
typeof activatedExtension.module.activate === 'function') {
|
|
53
|
+
await activatedExtension.module.activate({});
|
|
54
|
+
this.#activeExtension.set(extensionName, true);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
throw new Error(`Failed to activate extension "${extensionName}". The "activate" method is missing or invalid.`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.error(`Error activating extension "${extensionName}":`, error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
* @param extensionName
|
|
67
|
+
* @returns
|
|
68
|
+
*/
|
|
69
|
+
getExtension(extensionName) {
|
|
70
|
+
return this.#extensions.get(extensionName);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const extension = {
|
|
74
|
+
manager: new ExtensionManager()
|
|
75
|
+
};
|
|
76
|
+
export default extension;
|