diff --git a/README.md b/README.md index 550733d1..d36d17bc 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,11 @@ export class AppModule {} Then in HTML ```html - + ``` ### Working with HTML diff --git a/docs/README.md b/docs/README.md index f1f59916..9608aa77 100644 --- a/docs/README.md +++ b/docs/README.md @@ -56,7 +56,11 @@ export class AppModule {} Then in HTML ```html - + ``` ### Working with HTML diff --git a/src/lib/editor.component.ts b/src/lib/editor.component.ts index 40ffcba3..4dcd84f8 100644 --- a/src/lib/editor.component.ts +++ b/src/lib/editor.component.ts @@ -13,6 +13,7 @@ import { Node as ProsemirrorNode } from 'prosemirror-model'; import { NgxEditorService, NgxEditorServiceConfig } from './editor.service'; import { SharedService } from './services/shared/shared.service'; import { Toolbar } from './types'; +import { editable } from 'ngx-editor/plugins'; @Component({ selector: 'ngx-editor', @@ -37,6 +38,7 @@ export class NgxEditorComponent implements ControlValueAccessor, OnInit, OnDestr @Input() customMenuRef: TemplateRef; @Input() placeholder: string; + @Input() editable = true; @Output() init = new EventEmitter(); @Output() focusOut = new EventEmitter(); @Output() focusIn = new EventEmitter(); @@ -122,6 +124,15 @@ export class NgxEditorComponent implements ControlValueAccessor, OnInit, OnDestr return plugin; } + private filterBuiltIns(plugin: Plugin): boolean { + const pluginKey: string = (plugin as any).key; + if (/^editable\$/.test(pluginKey)) { + return false; + } + + return true; + } + private createEditor(): void { const { schema, plugins, nodeViews } = this.config; @@ -130,8 +141,9 @@ export class NgxEditorComponent implements ControlValueAccessor, OnInit, OnDestr doc: null, schema, plugins: [ - ...plugins, - this.createUpdateWatcherPlugin() + ...plugins.filter((plugin) => this.filterBuiltIns(plugin)), + this.createUpdateWatcherPlugin(), + editable(this.editable) ] }), nodeViews, @@ -164,6 +176,11 @@ export class NgxEditorComponent implements ControlValueAccessor, OnInit, OnDestr dispatch(tr.setMeta('UPDATE_PLACEHOLDER', placeholder)); } + private updateEditable(edit: boolean): void { + const { dispatch, state: { tr } } = this.view; + dispatch(tr.setMeta('UPDATE_EDITABLE', edit)); + } + ngOnInit(): void { this.createEditor(); this.setPlaceholder(); @@ -173,6 +190,10 @@ export class NgxEditorComponent implements ControlValueAccessor, OnInit, OnDestr if (changes?.placeholder && !changes.placeholder.isFirstChange()) { this.setPlaceholder(changes.placeholder.currentValue); } + + if (changes?.editable && !changes.editable.isFirstChange()) { + this.updateEditable(changes.editable.currentValue); + } } ngOnDestroy(): void { diff --git a/src/plugins/editable.ts b/src/plugins/editable.ts new file mode 100644 index 00000000..3b86c21f --- /dev/null +++ b/src/plugins/editable.ts @@ -0,0 +1,22 @@ +import { EditorState, Plugin, PluginKey, Transaction } from 'prosemirror-state'; + +const editablePlugin = (editable = true) => { + return new Plugin({ + key: new PluginKey('editable'), + state: { + init(): boolean { + return editable; + }, + apply(tr: Transaction, previousVal: boolean): string { + return tr.getMeta('UPDATE_EDITABLE') ?? previousVal; + } + }, + props: { + editable(state: EditorState): boolean { + return this.getState(state); + } + } + }); +}; + +export default editablePlugin; diff --git a/src/plugins/public_api.ts b/src/plugins/public_api.ts index ffc8a6f3..93554e2e 100644 --- a/src/plugins/public_api.ts +++ b/src/plugins/public_api.ts @@ -1,2 +1,3 @@ export { default as placeholder } from './placeholder'; +export { default as editable } from './editable'; export { default as image } from './image';