Skip to content

Commit

Permalink
feat(uip-editor): uip-editor reworked to use latest version of Code…
Browse files Browse the repository at this point in the history
…Jar and Prism without producing side-effects
  • Loading branch information
ala-n committed Sep 19, 2023
1 parent dea5a42 commit 8216d2a
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 130 deletions.
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@
},
"homepage": "https://github.com/exadel-inc/ui-playground#readme",
"engines": {
"node": ">=14.17.0"
"node": ">=18.17.0"
},
"dependencies": {
"@exadel/esl": "^4.11.0",
"codejar": "^3.7.0",
"codejar": "^4.2.0",
"jsx-dom": "6.4.23",
"prismjs": "^1.29.0"
},
Expand Down
90 changes: 65 additions & 25 deletions src/plugins/editor/editor.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,101 @@
// Prevent Prism from auto-highlighting
window.Prism = window.Prism || {};
if (typeof Prism.manual === 'undefined') Prism.manual = true;

import React from 'jsx-dom';
import Prism from 'prismjs';
import 'prismjs/plugins/normalize-whitespace/prism-normalize-whitespace';

import {CodeJar} from 'codejar';

import {debounce} from '@exadel/esl/modules/esl-utils/async/debounce';
import {bind, decorate, jsonAttr} from '@exadel/esl/modules/esl-utils/decorators';
import {bind, decorate, memoize, jsonAttr} from '@exadel/esl/modules/esl-utils/decorators';

import {UIPPlugin} from '../../core/base/plugin';

import {UIPPlugin} from '../../core/registration';
import {JarEditor} from './jar/jar-editor';
import {EditorConfig} from './jar/jar-utils';
export interface UIPEditorConfig {
wrap?: number;
}

/**
* Editor {@link UIPPlugin} custom element definition
* Uses Codejar code editor to provide an ability to modify UIP state markup
* @extends UIPPlugin
*/
export class UIPEditor extends UIPPlugin {
public static is = 'uip-editor';
/** Wrapped {@link https://medv.io/codejar/ Codejar} editor instance */
protected editor: JarEditor;
/** Editor's {@link EditorConfig} passed through attribute */
public static override is = 'uip-editor';

/** Highlight method declaration */
public static highlight: (editor: HTMLElement) => void = Prism.highlightElement;

/** Editor's {@link UIPEditorConfig} passed through attribute */
@jsonAttr({defaultValue: {wrap: 60}})
private editorConfig: Partial<EditorConfig>;
private editorConfig: Partial<UIPEditorConfig>;

/** Wrapped {@link https://medv.io/codejar/ Codejar} editor instance */
@memoize()
protected get editor(): CodeJar {
return CodeJar(this.$code, UIPEditor.highlight, { tab: '\t' });
}

@memoize()
protected get $code(): HTMLElement {
return (<pre class='language-html editor-content'><code/></pre>) as HTMLElement;
}

protected connectedCallback() {
/** @returns editor's content */
public get value(): string {
return this.editor.toString();
}

/** Preformat and set editor's content */
public set value(value: string) {
this.editor.updateCode(this.normalizeValue(value));
}

protected override connectedCallback() {
super.connectedCallback();
this.innerHTML = '';

// Prefill content
this.appendChild(this.$inner);
this.initEditor();
this.$inner.classList.add('esl-scrollable-content');
this.$inner.append(<esl-scrollbar target="::parent"/>);
this.$inner.append(this.$code);

// Initial update
this._onChange();
this.editor.onUpdate(this._onChange);
this._onRootStateChange();
}

protected disconnectedCallback(): void {
this.editor.removeEventListener(this._onChange);
protected override disconnectedCallback(): void {
this.editor?.destroy();
memoize.clear(this, 'editor');
super.disconnectedCallback();
}

/** Initialize inner {@link https://medv.io/codejar/ Codejar} editor */
protected initEditor(): void {
const codeBlock = (<pre class='language-html editor-content'><code/></pre>) as HTMLPreElement;
this.$inner.classList.add('esl-scrollable-content');
this.$inner.append(<esl-scrollbar target="::parent"></esl-scrollbar> as HTMLElement);
this.$inner.append(codeBlock);

this.editor = new JarEditor(codeBlock, this.editorConfig);
this.editor.addEventListener('uip:editor-change', this._onChange);
this._onRootStateChange();
/** Preformat value, calls before setting to editor */
protected normalizeValue(value: string): string {
const {wrap} = this.editorConfig;
const settings: Record<string, any> = {};
if (wrap) settings['break-lines'] = wrap;
return Prism.plugins.NormalizeWhitespace.normalize(value, settings);
}

/** Callback to call on editor's content changes */
@decorate(debounce, 1000)
protected _onChange() {
this.model!.setHtml(this.editor.getValue(), this);
this.model!.setHtml(this.value, this);
}

/** Change editor's markup from markup state changes */
@bind
protected _onRootStateChange(): void {
if (this.model!.lastModifier === this) return;
const markup = this.model!.html;
setTimeout(() => this.editor?.setValue(markup));
setTimeout(() => {
this.value = markup;
});
}
}
58 changes: 0 additions & 58 deletions src/plugins/editor/jar/jar-editor.ts

This file was deleted.

37 changes: 0 additions & 37 deletions src/plugins/editor/jar/jar-utils.ts

This file was deleted.

0 comments on commit 8216d2a

Please # to comment.