Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { EditV2 } from './editv2.js';
import { Transactor } from './Transactor.js';

/**
* OpenSCD core communicates the data necessary for editing SCL documents by setting the
* following [properties](https://developer.mozilla.org/en-US/docs/Glossary/Property/JavaScript) on
* the plugin's [DOM Element](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement)
*
* @property docs - A map of document names to their loaded XMLDocument instances.
* @property doc - The XMLDocument currently being edited, if any.
* @property docName - The name of the currently edited document, if any.
* @property docsState - changes value when the document is modified or documents are added/removed.
* @property locale - The end user's selected locale.
*/
export interface Plugin {
editor: Transactor<EditV2>;
docs: Record<string, XMLDocument>;
doc?: XMLDocument; // the document currently being edited
docName?: string; // the current doc's name
docsState: unknown; // current doc's state indicator
locale: string; // the end user's chosen locale
}
46 changes: 36 additions & 10 deletions docs/plugin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
An **OpenSCD plugin** is a [custom element](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#implementing_a_custom_element) that has been registered in the global [`customElements`](https://developer.mozilla.org/en-US/docs/Web/API/Window/customElements) registry under some tag name. OpenSCD core renders an element with that tag name into the app. The component may optionally provide a `run()` method for OpenSCD core to call in order to trigger an action.

The **OpenSCD core API** describes the ways in which:

- OpenSCD core communicates relevant data to the plugins,
- plugins communicate user intent to OpenSCD core, and
- OpenSCD sets CSS fonts and colors for plugins.
Expand All @@ -17,30 +18,40 @@ The **OpenSCD core API** describes the ways in which:

OpenSCD core communicates the data necessary for editing SCL documents by setting the following [properties](https://developer.mozilla.org/en-US/docs/Glossary/Property/JavaScript) on the plugin's [DOM Element](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement):


```typescript
export default class MyPlugin extends HTMLElement {
editor: Transactor<EditV2>;
docs: Record<string, XMLDocument> = {}; // all loaded documents
doc?: XMLDocument; // the document currently being edited
docName?: string; // the current doc's name
docVersion: unknown; // current doc's state indicator
docsState: unknown; // changes value when the document is modified or documents are added/removed.
locale: string = 'en'; // the end user's chosen locale
}
```

### `editor`

`editor` provides a reference to the central editor class used for modifying SCL documents. For
more details on the Transactor<EditV2> (Defaults to XMLEditor). For more on the XMLEditor checkout the [documentation](https://github.com/OMICRONEnergyOSS/oscd-editor)

### `docs`

`docs` is set to an object mapping `string` keys (document names) to `XMLDocument` values.

### `docName`

The name of the `XMLDocument` currently being edited.

### `doc`

The `XMLDocument` currently being edited.

### `docVersion`
A change in this property's value indicates a change to the `doc`.
### `docsState`

A value which changes with edits to the current document AND when documents are opened or closed.

### `locale`

Selected language (IETF language tag).

## Communicating user intent to OpenSCD core
Expand All @@ -56,20 +67,25 @@ export type EditDetailV2<E extends EditV2 = EditV2> = {
edit: E;
title?: string;
squash?: boolean;
}
};

export type EditEventV2<E extends EditV2 = EditV2> = CustomEvent<EditDetailV2<E>>;
export type EditEventV2<E extends EditV2 = EditV2> = CustomEvent<
EditDetailV2<E>
>;

export type EditEventOptions = {
title?: string;
squash?: boolean;
}
};

export function newEditEventV2<E extends EditV2>(edit: E, options: EditEventOptions): EditEventV2<E> {
export function newEditEventV2<E extends EditV2>(
edit: E,
options: EditEventOptions,
): EditEventV2<E> {
return new CustomEvent<E>('oscd-edit-v2', {
composed: true,
bubbles: true,
detail: {...options, edit},
detail: { ...options, edit },
});
}

Expand All @@ -85,15 +101,22 @@ Its `title` property is a human-readable description of the edit.
The `squash` flag indicates whether the edit should be merged with the previous edit in the history.

#### `EditV2` type

The `EditDetailV2` defined above contains an `edit` of this type:

```typescript
export type EditV2 = Insert | SetAttributes | SetTextContent | Remove | EditV2[];
export type EditV2 =
| Insert
| SetAttributes
| SetTextContent
| Remove
| EditV2[];
```

This means that a single edit can either consist in a sequence of other edits or in one of the following atomic edit types:

> Intent to set or remove (if null) attributes on `element`.

```typescript
export type SetAttributes = {
element: Element;
Expand All @@ -103,6 +126,7 @@ export type SetAttributes = {
```

> Intent to set the `textContent` of `element`.

```typescript
export type SetTextContent = {
element: Element;
Expand All @@ -111,6 +135,7 @@ export type SetTextContent = {
```

> Intent to `parent.insertBefore(node, reference)`

```typescript
export type Insert = {
parent: Node;
Expand All @@ -120,6 +145,7 @@ export type Insert = {
```

> Intent to remove a `node` from its `ownerDocument`.

```typescript
export type Remove = {
node: Node;
Expand Down
2 changes: 2 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import js from '@eslint/js';
import { FlatCompat } from '@eslint/eslintrc';
import eslintPluginTSDoc from 'eslint-plugin-tsdoc';
import openWcConfig from '@open-wc/eslint-config';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Expand Down Expand Up @@ -86,4 +87,5 @@ export default [
],
},
},
eslintPluginPrettierRecommended,
];