UNPKG

novo-elements

Version:

283 lines (278 loc) 13.9 kB
import * as i0 from '@angular/core'; import { forwardRef, EventEmitter, Input, ViewChild, Output, Component, NgModule } from '@angular/core'; import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import { fixCkEditorInputEvent } from 'novo-elements/utils'; import { CommonModule } from '@angular/common'; // NG2 // Value accessor for the component (supports ngModel) const CKEDITOR_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NovoCKEditorElement), multi: true, }; // Prevents CKEDITOR from querying the page for all [contenteditable] elements (fixes a conflict against Codemirror Editor) try { CKEDITOR.disableAutoInline = true; } catch (err) { // may be running in a context without CKEDITOR - ignore } /** * CKEditor component * Usage : * <novo-editor [(ngModel)]="data" [config]="{...}" debounce="500"></novo-editor> */ class NovoCKEditorElement { constructor(zone) { this.zone = zone; this.startupFocus = false; this.fileBrowserImageUploadUrl = ''; this.disabled = false; this.change = new EventEmitter(); this.ready = new EventEmitter(); this.blur = new EventEmitter(); this.focus = new EventEmitter(); this.paste = new EventEmitter(); this.loaded = new EventEmitter(); this._value = ''; } get value() { return this._value; } set value(v) { if (v !== this._value) { this._value = v; this.onChange(v); } } ngOnDestroy() { if (this.instance) { this.instance.focusManager.blur(true); // Remove focus from editor this._ckEditorFixRemoveListener?.(); setTimeout(() => { this.instance.removeAllListeners(); const aInstance = CKEDITOR.instances[this.instance.name]; if (aInstance) { aInstance.destroy(); } this.instance.destroy(); this.instance = null; }); } } ngAfterViewInit() { const config = Object.assign(this.getBaseConfig(), this.config); if (this.startupFocus) { config.startupFocus = true; } if (this.disabled) { config.readOnly = true; } this.ckeditorInit(config); } updateValue(value) { this.zone.run(() => { this.value = value; this.onChange(value); this.onTouched(); this.change.emit(value); }); } ckeditorInit(config) { if (!CKEDITOR) { console.error('Make sure to include CKEditor sources in your dependencies!'); return; } // CKEditor replace textarea this.instance = CKEDITOR.replace(this.host.nativeElement, config); this._ckEditorFixRemoveListener = fixCkEditorInputEvent(this.instance); // Set initial value this.instance.setData(this.value); // listen for instanceReady event this.instance.on('instanceReady', (evt) => { // send the evt to the EventEmitter this.ready.emit(evt); }); // CKEditor change event this.instance.on('change', () => { this.onTouched(); const value = this.instance.getData(); // Debounce update if (this.debounce) { if (this.debounceTimeout) { clearTimeout(this.debounceTimeout); } this.debounceTimeout = setTimeout(() => { this.updateValue(value); this.debounceTimeout = null; }, parseInt(this.debounce, 10)); } else { this.updateValue(value); } }); this.instance.on('blur', (event) => { this.blur.emit(event); }); this.instance.on('focus', (event) => { this.focus.emit(event); }); this.instance.on('paste', (event) => { this.paste.emit(event); }); this.instance.on('loaded', (event) => { this.loaded.emit(event); }); } getBaseConfig() { const baseConfig = { enterMode: CKEDITOR.ENTER_BR, entities: false, shiftEnterMode: CKEDITOR.ENTER_P, disableNativeSpellChecker: false, removePlugins: 'liststyle,tabletools,contextmenu,tableselection', // allows browser based spell checking extraAllowedContent: '*(*){*};table tbody tr td th[*];', // allows class names (*) and inline styles {*} for all and attributes [*] on tables font_names: 'Arial/Arial, Helvetica, sans-serif;' + 'Calibri/Calibri, Verdana, Geneva, sans-serif;' + 'Comic Sans MS/Comic Sans MS, cursive;' + 'Courier New/Courier New, Courier, monospace;' + 'Georgia/Georgia, serif;' + 'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' + 'Tahoma/Tahoma, Geneva, sans-serif;' + 'Times New Roman/Times New Roman, Times, serif;' + 'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' + 'Verdana/Verdana, Geneva, sans-serif', }; const minimalConfig = { toolbar: [ { name: 'basicstyles', items: [ 'Styles', 'FontSize', 'Bold', 'Italic', 'Underline', 'TextColor', '-', 'NumberedList', 'BulletedList', 'Outdent', 'Indent', 'Link', ], }, ], }; const extendedConfig = { toolbar: [ { name: 'clipboard', items: ['Paste', 'PasteText', 'PasteFromWord', 'Undo', 'Redo'] }, { name: 'paragraph', items: [ 'NumberedList', 'BulletedList', 'Outdent', 'Indent', 'Blockquote', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', 'BidiLtr', 'BidiRtl', ], }, { name: 'links', items: ['Link'] }, { name: 'insert', items: ['Image', 'Table', 'HorizontalRule'] }, { name: 'tools', items: ['Maximize', 'Source'] }, '/', // line break { name: 'basicstyles', items: ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript'] }, { name: 'styles', items: ['Styles', 'Format', 'Font', 'FontSize'] }, { name: 'colors', items: ['TextColor', 'BGColor'] }, ], filebrowserImageUploadUrl: this.fileBrowserImageUploadUrl, }; return Object.assign(baseConfig, this.minimal ? minimalConfig : extendedConfig); } writeValue(value) { this._value = value; if (this.instance) { this.instance.setData(value); } } onChange(value) { } onTouched(event) { } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } setDisabledState(disabled) { this.disabled = disabled; if (this.instance) { CKEDITOR.instances[this.instance.name].setReadOnly(disabled); } } insertText(text) { const trimmedText = text.trim(); this.instance.insertText(trimmedText); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoCKEditorElement, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: NovoCKEditorElement, isStandalone: false, selector: "novo-editor", inputs: { config: "config", debounce: "debounce", name: "name", minimal: "minimal", startupFocus: "startupFocus", fileBrowserImageUploadUrl: "fileBrowserImageUploadUrl", disabled: "disabled", value: "value" }, outputs: { change: "change", ready: "ready", blur: "blur", focus: "focus", paste: "paste", loaded: "loaded" }, providers: [CKEDITOR_CONTROL_VALUE_ACCESSOR], viewQueries: [{ propertyName: "host", first: true, predicate: ["host"], descendants: true }], ngImport: i0, template: '<textarea [name]="name" [id]="name" #host></textarea>', isInline: true, styles: [":host ::ng-deep .cke{font:inherit!important;box-shadow:none;border-color:var(--background-muted)}:host ::ng-deep .cke .cke_top,:host ::ng-deep .cke .cke_bottom{background:var(--background-muted) none;box-shadow:none}:host ::ng-deep .cke .cke_bottom{border-top:none}.cke_dialog_background_cover{background-color:#000!important}.cke_dialog .cke_dialog_title{text-shadow:none;background:var(--background-muted) none;box-shadow:none;border-bottom:none}.cke_dialog .cke_dialog_footer{text-shadow:none;background:var(--background-muted) none;box-shadow:none;border-top:none}:host-context(.theme-dark) ::ng-deep .cke_button{filter:invert(1)}:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button:hover,:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button:active,:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button:focus,:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button.cke_combo_on{background:var(--background-main);border:1px solid var(--border)}:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button .cke_combo_text{color:#fff}:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button .cke_combo_arrow{border-top-color:#fff}\n"] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoCKEditorElement, decorators: [{ type: Component, args: [{ selector: 'novo-editor', providers: [CKEDITOR_CONTROL_VALUE_ACCESSOR], template: '<textarea [name]="name" [id]="name" #host></textarea>', standalone: false, styles: [":host ::ng-deep .cke{font:inherit!important;box-shadow:none;border-color:var(--background-muted)}:host ::ng-deep .cke .cke_top,:host ::ng-deep .cke .cke_bottom{background:var(--background-muted) none;box-shadow:none}:host ::ng-deep .cke .cke_bottom{border-top:none}.cke_dialog_background_cover{background-color:#000!important}.cke_dialog .cke_dialog_title{text-shadow:none;background:var(--background-muted) none;box-shadow:none;border-bottom:none}.cke_dialog .cke_dialog_footer{text-shadow:none;background:var(--background-muted) none;box-shadow:none;border-top:none}:host-context(.theme-dark) ::ng-deep .cke_button{filter:invert(1)}:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button:hover,:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button:active,:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button:focus,:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button.cke_combo_on{background:var(--background-main);border:1px solid var(--border)}:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button .cke_combo_text{color:#fff}:host-context(.theme-dark) ::ng-deep .cke_combo a.cke_combo_button .cke_combo_arrow{border-top-color:#fff}\n"] }] }], ctorParameters: () => [{ type: i0.NgZone }], propDecorators: { config: [{ type: Input }], debounce: [{ type: Input }], name: [{ type: Input }], minimal: [{ type: Input }], startupFocus: [{ type: Input }], fileBrowserImageUploadUrl: [{ type: Input }], disabled: [{ type: Input }], change: [{ type: Output }], ready: [{ type: Output }], blur: [{ type: Output }], focus: [{ type: Output }], paste: [{ type: Output }], loaded: [{ type: Output }], host: [{ type: ViewChild, args: ['host'] }], value: [{ type: Input }] } }); // NG2 class NovoNovoCKEditorModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoNovoCKEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: NovoNovoCKEditorModule, declarations: [NovoCKEditorElement], imports: [CommonModule, FormsModule], exports: [NovoCKEditorElement] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoNovoCKEditorModule, imports: [CommonModule, FormsModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NovoNovoCKEditorModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule, FormsModule], declarations: [NovoCKEditorElement], exports: [NovoCKEditorElement], }] }] }); /** * Generated bundle index. Do not edit. */ export { NovoCKEditorElement, NovoNovoCKEditorModule }; //# sourceMappingURL=novo-elements-addons-ckeditor.mjs.map