From a0ba8d36ee78d468415bd173d0a692c84d23367a Mon Sep 17 00:00:00 2001 From: Nejat Mhango Date: Mon, 11 Dec 2023 16:45:53 +0200 Subject: [PATCH 1/2] fixed document is not defined error during ssr build --- src/app/components/editor/editor.ts | 480 ++++++++++++++-------------- 1 file changed, 240 insertions(+), 240 deletions(-) diff --git a/src/app/components/editor/editor.ts b/src/app/components/editor/editor.ts index aee722c9434..1d6537d2ba1 100755 --- a/src/app/components/editor/editor.ts +++ b/src/app/components/editor/editor.ts @@ -1,37 +1,34 @@ +import { CommonModule, isPlatformServer } from '@angular/common' import { - NgModule, + AfterContentInit, + ChangeDetectionStrategy, Component, + ContentChild, + ContentChildren, ElementRef, - AfterViewInit, + EventEmitter, + Inject, Input, + NgModule, Output, - EventEmitter, - ContentChild, - forwardRef, - ChangeDetectionStrategy, - ViewEncapsulation, - ContentChildren, + PLATFORM_ID, QueryList, - AfterContentInit, TemplateRef, - AfterViewChecked, - Inject, - PLATFORM_ID -} from '@angular/core'; -import { isPlatformBrowser, CommonModule } from '@angular/common'; -import { SharedModule, Header, PrimeTemplate } from 'primeng/api'; -import { DomHandler } from 'primeng/dom'; -import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; -import { EditorInitEvent, EditorTextChangeEvent, EditorSelectionChangeEvent } from './editor.interface'; -import { Nullable } from 'primeng/ts-helpers'; -//@ts-ignore -import Quill from 'quill'; + ViewEncapsulation, + afterNextRender, + forwardRef +} from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' +import { Header, PrimeTemplate, SharedModule } from 'primeng/api' +import { DomHandler } from 'primeng/dom' +import { Nullable } from 'primeng/ts-helpers' +import { EditorInitEvent, EditorSelectionChangeEvent, EditorTextChangeEvent } from './editor.interface' export const EDITOR_VALUE_ACCESSOR: any = { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => Editor), - multi: true -}; + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => Editor), + multi: true, +} /** * Editor groups a collection of contents in tabs. * @group Components @@ -96,253 +93,256 @@ export const EDITOR_VALUE_ACCESSOR: any = { class: 'p-element' } }) -export class Editor implements AfterViewInit, AfterViewChecked, AfterContentInit, ControlValueAccessor { - /** - * Inline style of the container. - * @group Props - */ - @Input() style: { [klass: string]: any } | null | undefined; - /** - * Style class of the container. - * @group Props - */ - @Input() styleClass: string | undefined; - /** - * Placeholder text to show when editor is empty. - * @group Props - */ - @Input() placeholder: string | undefined; - /** - * Whitelist of formats to display, see here for available options. - * @group Props - */ - @Input() formats: string[] | undefined; - /** - * Modules configuration of Editor, see here for available options. - * @group Props - */ - @Input() modules: object | undefined; - /** - * DOM Element or a CSS selector for a DOM Element, within which the editor’s p elements (i.e. tooltips, etc.) should be confined. Currently, it only considers left and right boundaries. - * @group Props - */ - @Input() bounds: HTMLElement | string | undefined; - /** - * DOM Element or a CSS selector for a DOM Element, specifying which container has the scrollbars (i.e. overflow-y: auto), if is has been changed from the default ql-editor with custom CSS. Necessary to fix scroll jumping bugs when Quill is set to auto grow its height, and another ancestor container is responsible from the scrolling.. - * @group Props - */ - @Input() scrollingContainer: HTMLElement | string | undefined; - /** - * Shortcut for debug. Note debug is a static method and will affect other instances of Quill editors on the page. Only warning and error messages are enabled by default. - * @group Props - */ - @Input() debug: string | undefined; - /** - * Whether to instantiate the editor to read-only mode. - * @group Props - */ - @Input() get readonly(): boolean { - return this._readonly; +export class Editor implements AfterContentInit, ControlValueAccessor { + /** + * Inline style of the container. + * @group Props + */ + @Input() style: { [klass: string]: any } | null | undefined + /** + * Style class of the container. + * @group Props + */ + @Input() styleClass: string | undefined + /** + * Placeholder text to show when editor is empty. + * @group Props + */ + @Input() placeholder: string | undefined + /** + * Whitelist of formats to display, see here for available options. + * @group Props + */ + @Input() formats: string[] | undefined + /** + * Modules configuration of Editor, see here for available options. + * @group Props + */ + @Input() modules: object | undefined + /** + * DOM Element or a CSS selector for a DOM Element, within which the editor’s p elements (i.e. tooltips, etc.) should be confined. Currently, it only considers left and right boundaries. + * @group Props + */ + @Input() bounds: HTMLElement | string | undefined + /** + * DOM Element or a CSS selector for a DOM Element, specifying which container has the scrollbars (i.e. overflow-y: auto), if is has been changed from the default ql-editor with custom CSS. Necessary to fix scroll jumping bugs when Quill is set to auto grow its height, and another ancestor container is responsible from the scrolling.. + * @group Props + */ + @Input() scrollingContainer: HTMLElement | string | undefined + /** + * Shortcut for debug. Note debug is a static method and will affect other instances of Quill editors on the page. Only warning and error messages are enabled by default. + * @group Props + */ + @Input() debug: string | undefined + /** + * Whether to instantiate the editor to read-only mode. + * @group Props + */ + @Input() get readonly(): boolean { + return this._readonly + } + set readonly(val: boolean) { + this._readonly = val + + if (this.quill) { + if (this._readonly) this.quill.disable() + else this.quill.enable() } - set readonly(val: boolean) { - this._readonly = val; + } + /** + * Callback to invoke when the quill modules are loaded. + * @param {EditorInitEvent} event - custom event. + * @group Emits + */ + @Output() onInit: EventEmitter = new EventEmitter() + /** + * Callback to invoke when text of editor changes. + * @param {EditorTextChangeEvent} event - custom event. + * @group Emits + */ + @Output() onTextChange: EventEmitter = new EventEmitter() + /** + * Callback to invoke when selection of the text changes. + * @param {EditorSelectionChangeEvent} event - custom event. + * @group Emits + */ + @Output() onSelectionChange: EventEmitter = new EventEmitter() - // if (this.quill) { - // if (this._readonly) this.quill.disable(); - // else this.quill.enable(); - // } - } - /** - * Callback to invoke when the quill modules are loaded. - * @param {EditorInitEvent} event - custom event. - * @group Emits - */ - @Output() onInit: EventEmitter = new EventEmitter(); - /** - * Callback to invoke when text of editor changes. - * @param {EditorTextChangeEvent} event - custom event. - * @group Emits - */ - @Output() onTextChange: EventEmitter = new EventEmitter(); - /** - * Callback to invoke when selection of the text changes. - * @param {EditorSelectionChangeEvent} event - custom event. - * @group Emits - */ - @Output() onSelectionChange: EventEmitter = new EventEmitter(); + @ContentChildren(PrimeTemplate) templates!: QueryList - @ContentChildren(PrimeTemplate) templates!: QueryList; + @ContentChild(Header) toolbar: any - @ContentChild(Header) toolbar: any; + value: Nullable - value: Nullable; + delayedCommand: Function | null = null - delayedCommand: Function | null = null; + _readonly: boolean = false - _readonly: boolean = false; + onModelChange: Function = () => {} - onModelChange: Function = () => {}; + onModelTouched: Function = () => {} - onModelTouched: Function = () => {}; + quill: any - quill: any; + dynamicQuill: any - headerTemplate: Nullable>; + headerTemplate: Nullable> - private get isAttachedQuillEditorToDOM(): boolean | undefined { - return this.quillElements?.editorElement?.isConnected; - } + private get isAttachedQuillEditorToDOM(): boolean | undefined { + return this.quillElements?.editorElement?.isConnected + } - private quillElements!: { editorElement: HTMLElement; toolbarElement: HTMLElement }; + private quillElements!: { editorElement: HTMLElement; toolbarElement: HTMLElement } - constructor(@Inject(PLATFORM_ID) public platformId: any, public el: ElementRef) {} + constructor(public el: ElementRef, @Inject(PLATFORM_ID) private platformId: object) { + /** + * Read or write the DOM once, when initializing non-Angular (Quill) library. + */ + afterNextRender(() => { + this.initQuillElements() + + if (this.isAttachedQuillEditorToDOM) { + this.initQuillEditor() + } + }) + } + + ngAfterContentInit() { + this.templates.forEach((item) => { + switch (item.getType()) { + case 'header': + this.headerTemplate = item.template + break + } + }) + } + + writeValue(value: any): void { + this.value = value + + if (this.quill) { + if (value) { + const command = (): void => { + this.quill.setContents(this.quill.clipboard.convert(this.value)) + } - ngAfterViewInit(): void { - if (isPlatformBrowser(this.platformId)) { - this.initQuillElements(); - if (this.isAttachedQuillEditorToDOM) { - this.initQuillEditor(); - } + if (this.isAttachedQuillEditorToDOM) { + command() + } else { + this.delayedCommand = command + } + } else { + const command = (): void => { + this.quill.setText('') } - } - ngAfterViewChecked(): void { - if (isPlatformBrowser(this.platformId)) { - // The problem is inside the `quill` library, we need to wait for a new release. - // Function `isLine` - used `getComputedStyle`, it was rewritten in the next release. - // (We need to wait for a release higher than 1.3.7). - // These checks and code can be removed. - if (!this.quill && this.isAttachedQuillEditorToDOM) { - this.initQuillEditor(); - } - - // Can also be deleted after updating `quill`. - if (this.delayedCommand && this.isAttachedQuillEditorToDOM) { - this.delayedCommand(); - this.delayedCommand = null; - } + if (this.isAttachedQuillEditorToDOM) { + command() + } else { + this.delayedCommand = command } + } } + } - ngAfterContentInit() { - this.templates.forEach((item) => { - switch (item.getType()) { - case 'header': - this.headerTemplate = item.template; - break; - } - }); - } + registerOnChange(fn: Function): void { + this.onModelChange = fn + } - writeValue(value: any): void { - this.value = value; - - if (this.quill) { - if (value) { - const command = (): void => { - this.quill.setContents(this.quill.clipboard.convert(this.value)); - }; - - if (this.isAttachedQuillEditorToDOM) { - command(); - } else { - this.delayedCommand = command; - } - } else { - const command = (): void => { - this.quill.setText(''); - }; - - if (this.isAttachedQuillEditorToDOM) { - command(); - } else { - this.delayedCommand = command; - } - } - } - } + registerOnTouched(fn: Function): void { + this.onModelTouched = fn + } - registerOnChange(fn: Function): void { - this.onModelChange = fn; - } + getQuill() { + return this.quill + } - registerOnTouched(fn: Function): void { - this.onModelTouched = fn; + private initQuillEditor(): void { + if (isPlatformServer(this.platformId)) { + return } - getQuill() { - return this.quill; + /** + * Importing Quill at top level, throws `document is undefined` error during when + * building for SSR, so this dynamically loads quill when it's in browser module. + */ + if (!this.dynamicQuill) { + import('quill').then((quillModule: any) => { + this.dynamicQuill = quillModule.default; + this.createQuillEditor() + }).catch(e => console.error(e.message)) + } else { + this.createQuillEditor() } - - private initQuillEditor(): void { - this.initQuillElements(); - - const { toolbarElement, editorElement } = this.quillElements; - let defaultModule = { toolbar: toolbarElement }; - let modules = this.modules ? { ...defaultModule, ...this.modules } : defaultModule; - this.quill = new Quill(editorElement, { - modules: modules, - placeholder: this.placeholder, - readOnly: this.readonly, - theme: 'snow', - formats: this.formats, - bounds: this.bounds, - debug: this.debug, - scrollingContainer: this.scrollingContainer - }); - - if (this.value) { - this.quill.setContents(this.quill.clipboard.convert(this.value)); - } - - this.quill.on('text-change', (delta: any, oldContents: any, source: any) => { - if (source === 'user') { - let html = DomHandler.findSingle(editorElement, '.ql-editor').innerHTML; - let text = this.quill.getText().trim(); - if (html === '


') { - html = null; - } - - this.onTextChange.emit({ - htmlValue: html, - textValue: text, - delta: delta, - source: source - }); - - this.onModelChange(html); - this.onModelTouched(); - } - }); - - this.quill.on('selection-change', (range: string, oldRange: string, source: string) => { - this.onSelectionChange.emit({ - range: range, - oldRange: oldRange, - source: source - }); - }); - - this.onInit.emit({ - editor: this.quill - }); + } + + private createQuillEditor(): void { + this.initQuillElements() + + const { toolbarElement, editorElement } = this.quillElements + let defaultModule = { toolbar: toolbarElement } + let modules = this.modules ? { ...defaultModule, ...this.modules } : defaultModule + this.quill = new this.dynamicQuill(editorElement, { + modules: modules, + placeholder: this.placeholder, + readOnly: this.readonly, + theme: 'snow', + formats: this.formats, + bounds: this.bounds, + debug: this.debug, + scrollingContainer: this.scrollingContainer, + }) + + if (this.value) { + this.quill.setContents(this.quill.clipboard.convert(this.value)) } - private initQuillElements(): void { - if (isPlatformBrowser(this.platformId)) { - if (!this.quillElements) { - this.quillElements = { - editorElement: DomHandler.findSingle(this.el.nativeElement, 'div.p-editor-content'), - toolbarElement: DomHandler.findSingle(this.el.nativeElement, 'div.p-editor-toolbar') - }; - } + this.quill.on('text-change', (delta: any, oldContents: any, source: any) => { + if (source === 'user') { + let html = DomHandler.findSingle(editorElement, '.ql-editor').innerHTML + let text = this.quill.getText().trim() + if (html === '


') { + html = null } + + this.onTextChange.emit({ + htmlValue: html, + textValue: text, + delta: delta, + source: source, + }) + + this.onModelChange(html) + this.onModelTouched() + } + }) + + this.quill.on('selection-change', (range: string, oldRange: string, source: string) => { + this.onSelectionChange.emit({ + range: range, + oldRange: oldRange, + source: source, + }) + }) + + this.onInit.emit({ + editor: this.quill, + }) + } + + private initQuillElements(): void { + if (!this.quillElements) { + this.quillElements = { + editorElement: DomHandler.findSingle(this.el.nativeElement, 'div.p-editor-content'), + toolbarElement: DomHandler.findSingle(this.el.nativeElement, 'div.p-editor-toolbar'), + } } + } } @NgModule({ - imports: [CommonModule], - exports: [Editor, SharedModule], - declarations: [Editor] + imports: [CommonModule], + exports: [Editor, SharedModule], + declarations: [Editor], }) export class EditorModule {} From d22dee0414aa1ba41f9d38bfca9af55b437cb3c4 Mon Sep 17 00:00:00 2001 From: Nejat Mhango Date: Mon, 11 Dec 2023 18:51:32 +0200 Subject: [PATCH 2/2] refactor indentation --- src/app/components/editor/editor.ts | 460 ++++++++++++++-------------- 1 file changed, 231 insertions(+), 229 deletions(-) diff --git a/src/app/components/editor/editor.ts b/src/app/components/editor/editor.ts index 1d6537d2ba1..9e578437fe7 100755 --- a/src/app/components/editor/editor.ts +++ b/src/app/components/editor/editor.ts @@ -1,4 +1,4 @@ -import { CommonModule, isPlatformServer } from '@angular/common' +import { CommonModule, isPlatformServer } from '@angular/common'; import { AfterContentInit, ChangeDetectionStrategy, @@ -17,18 +17,18 @@ import { ViewEncapsulation, afterNextRender, forwardRef -} from '@angular/core' -import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' -import { Header, PrimeTemplate, SharedModule } from 'primeng/api' -import { DomHandler } from 'primeng/dom' -import { Nullable } from 'primeng/ts-helpers' -import { EditorInitEvent, EditorSelectionChangeEvent, EditorTextChangeEvent } from './editor.interface' +} from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { Header, PrimeTemplate, SharedModule } from 'primeng/api'; +import { DomHandler } from 'primeng/dom'; +import { Nullable } from 'primeng/ts-helpers'; +import { EditorInitEvent, EditorSelectionChangeEvent, EditorTextChangeEvent } from './editor.interface'; export const EDITOR_VALUE_ACCESSOR: any = { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => Editor), - multi: true, -} + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => Editor), + multi: true +}; /** * Editor groups a collection of contents in tabs. * @group Components @@ -94,255 +94,257 @@ export const EDITOR_VALUE_ACCESSOR: any = { } }) export class Editor implements AfterContentInit, ControlValueAccessor { - /** - * Inline style of the container. - * @group Props - */ - @Input() style: { [klass: string]: any } | null | undefined - /** - * Style class of the container. - * @group Props - */ - @Input() styleClass: string | undefined - /** - * Placeholder text to show when editor is empty. - * @group Props - */ - @Input() placeholder: string | undefined - /** - * Whitelist of formats to display, see here for available options. - * @group Props - */ - @Input() formats: string[] | undefined - /** - * Modules configuration of Editor, see here for available options. - * @group Props - */ - @Input() modules: object | undefined - /** - * DOM Element or a CSS selector for a DOM Element, within which the editor’s p elements (i.e. tooltips, etc.) should be confined. Currently, it only considers left and right boundaries. - * @group Props - */ - @Input() bounds: HTMLElement | string | undefined - /** - * DOM Element or a CSS selector for a DOM Element, specifying which container has the scrollbars (i.e. overflow-y: auto), if is has been changed from the default ql-editor with custom CSS. Necessary to fix scroll jumping bugs when Quill is set to auto grow its height, and another ancestor container is responsible from the scrolling.. - * @group Props - */ - @Input() scrollingContainer: HTMLElement | string | undefined - /** - * Shortcut for debug. Note debug is a static method and will affect other instances of Quill editors on the page. Only warning and error messages are enabled by default. - * @group Props - */ - @Input() debug: string | undefined - /** - * Whether to instantiate the editor to read-only mode. - * @group Props - */ - @Input() get readonly(): boolean { - return this._readonly - } - set readonly(val: boolean) { - this._readonly = val - - if (this.quill) { - if (this._readonly) this.quill.disable() - else this.quill.enable() + /** + * Inline style of the container. + * @group Props + */ + @Input() style: { [klass: string]: any } | null | undefined; + /** + * Style class of the container. + * @group Props + */ + @Input() styleClass: string | undefined; + /** + * Placeholder text to show when editor is empty. + * @group Props + */ + @Input() placeholder: string | undefined; + /** + * Whitelist of formats to display, see here for available options. + * @group Props + */ + @Input() formats: string[] | undefined; + /** + * Modules configuration of Editor, see here for available options. + * @group Props + */ + @Input() modules: object | undefined; + /** + * DOM Element or a CSS selector for a DOM Element, within which the editor’s p elements (i.e. tooltips, etc.) should be confined. Currently, it only considers left and right boundaries. + * @group Props + */ + @Input() bounds: HTMLElement | string | undefined; + /** + * DOM Element or a CSS selector for a DOM Element, specifying which container has the scrollbars (i.e. overflow-y: auto), if is has been changed from the default ql-editor with custom CSS. Necessary to fix scroll jumping bugs when Quill is set to auto grow its height, and another ancestor container is responsible from the scrolling.. + * @group Props + */ + @Input() scrollingContainer: HTMLElement | string | undefined; + /** + * Shortcut for debug. Note debug is a static method and will affect other instances of Quill editors on the page. Only warning and error messages are enabled by default. + * @group Props + */ + @Input() debug: string | undefined; + /** + * Whether to instantiate the editor to read-only mode. + * @group Props + */ + @Input() get readonly(): boolean { + return this._readonly; } - } - /** - * Callback to invoke when the quill modules are loaded. - * @param {EditorInitEvent} event - custom event. - * @group Emits - */ - @Output() onInit: EventEmitter = new EventEmitter() - /** - * Callback to invoke when text of editor changes. - * @param {EditorTextChangeEvent} event - custom event. - * @group Emits - */ - @Output() onTextChange: EventEmitter = new EventEmitter() - /** - * Callback to invoke when selection of the text changes. - * @param {EditorSelectionChangeEvent} event - custom event. - * @group Emits - */ - @Output() onSelectionChange: EventEmitter = new EventEmitter() + set readonly(val: boolean) { + this._readonly = val; - @ContentChildren(PrimeTemplate) templates!: QueryList + if (this.quill) { + if (this._readonly) this.quill.disable(); + else this.quill.enable(); + } + } + /** + * Callback to invoke when the quill modules are loaded. + * @param {EditorInitEvent} event - custom event. + * @group Emits + */ + @Output() onInit: EventEmitter = new EventEmitter(); + /** + * Callback to invoke when text of editor changes. + * @param {EditorTextChangeEvent} event - custom event. + * @group Emits + */ + @Output() onTextChange: EventEmitter = new EventEmitter(); + /** + * Callback to invoke when selection of the text changes. + * @param {EditorSelectionChangeEvent} event - custom event. + * @group Emits + */ + @Output() onSelectionChange: EventEmitter = new EventEmitter(); - @ContentChild(Header) toolbar: any + @ContentChildren(PrimeTemplate) templates!: QueryList; - value: Nullable + @ContentChild(Header) toolbar: any; - delayedCommand: Function | null = null + value: Nullable; - _readonly: boolean = false + delayedCommand: Function | null = null; - onModelChange: Function = () => {} + _readonly: boolean = false; - onModelTouched: Function = () => {} + onModelChange: Function = () => {}; - quill: any + onModelTouched: Function = () => {}; - dynamicQuill: any + quill: any; - headerTemplate: Nullable> + dynamicQuill: any; - private get isAttachedQuillEditorToDOM(): boolean | undefined { - return this.quillElements?.editorElement?.isConnected - } + headerTemplate: Nullable>; - private quillElements!: { editorElement: HTMLElement; toolbarElement: HTMLElement } + private get isAttachedQuillEditorToDOM(): boolean | undefined { + return this.quillElements?.editorElement?.isConnected; + } - constructor(public el: ElementRef, @Inject(PLATFORM_ID) private platformId: object) { - /** - * Read or write the DOM once, when initializing non-Angular (Quill) library. - */ - afterNextRender(() => { - this.initQuillElements() - - if (this.isAttachedQuillEditorToDOM) { - this.initQuillEditor() - } - }) - } - - ngAfterContentInit() { - this.templates.forEach((item) => { - switch (item.getType()) { - case 'header': - this.headerTemplate = item.template - break - } - }) - } - - writeValue(value: any): void { - this.value = value - - if (this.quill) { - if (value) { - const command = (): void => { - this.quill.setContents(this.quill.clipboard.convert(this.value)) - } + private quillElements!: { editorElement: HTMLElement; toolbarElement: HTMLElement }; - if (this.isAttachedQuillEditorToDOM) { - command() - } else { - this.delayedCommand = command - } - } else { - const command = (): void => { - this.quill.setText('') - } + constructor(public el: ElementRef, @Inject(PLATFORM_ID) private platformId: object) { + /** + * Read or write the DOM once, when initializing non-Angular (Quill) library. + */ + afterNextRender(() => { + this.initQuillElements(); - if (this.isAttachedQuillEditorToDOM) { - command() - } else { - this.delayedCommand = command - } - } + if (this.isAttachedQuillEditorToDOM) { + this.initQuillEditor(); + } + }); } - } - registerOnChange(fn: Function): void { - this.onModelChange = fn - } + ngAfterContentInit() { + this.templates.forEach((item) => { + switch (item.getType()) { + case 'header': + this.headerTemplate = item.template; + break; + } + }); + } - registerOnTouched(fn: Function): void { - this.onModelTouched = fn - } + writeValue(value: any): void { + this.value = value; + + if (this.quill) { + if (value) { + const command = (): void => { + this.quill.setContents(this.quill.clipboard.convert(this.value)); + }; + + if (this.isAttachedQuillEditorToDOM) { + command(); + } else { + this.delayedCommand = command; + } + } else { + const command = (): void => { + this.quill.setText(''); + }; + + if (this.isAttachedQuillEditorToDOM) { + command(); + } else { + this.delayedCommand = command; + } + } + } + } - getQuill() { - return this.quill - } + registerOnChange(fn: Function): void { + this.onModelChange = fn; + } - private initQuillEditor(): void { - if (isPlatformServer(this.platformId)) { - return + registerOnTouched(fn: Function): void { + this.onModelTouched = fn; } - /** - * Importing Quill at top level, throws `document is undefined` error during when - * building for SSR, so this dynamically loads quill when it's in browser module. - */ - if (!this.dynamicQuill) { - import('quill').then((quillModule: any) => { - this.dynamicQuill = quillModule.default; - this.createQuillEditor() - }).catch(e => console.error(e.message)) - } else { - this.createQuillEditor() + getQuill() { + return this.quill; } - } - - private createQuillEditor(): void { - this.initQuillElements() - - const { toolbarElement, editorElement } = this.quillElements - let defaultModule = { toolbar: toolbarElement } - let modules = this.modules ? { ...defaultModule, ...this.modules } : defaultModule - this.quill = new this.dynamicQuill(editorElement, { - modules: modules, - placeholder: this.placeholder, - readOnly: this.readonly, - theme: 'snow', - formats: this.formats, - bounds: this.bounds, - debug: this.debug, - scrollingContainer: this.scrollingContainer, - }) - - if (this.value) { - this.quill.setContents(this.quill.clipboard.convert(this.value)) + + private initQuillEditor(): void { + if (isPlatformServer(this.platformId)) { + return; + } + + /** + * Importing Quill at top level, throws `document is undefined` error during when + * building for SSR, so this dynamically loads quill when it's in browser module. + */ + if (!this.dynamicQuill) { + import('quill') + .then((quillModule: any) => { + this.dynamicQuill = quillModule.default; + this.createQuillEditor(); + }) + .catch((e) => console.error(e.message)); + } else { + this.createQuillEditor(); + } } - this.quill.on('text-change', (delta: any, oldContents: any, source: any) => { - if (source === 'user') { - let html = DomHandler.findSingle(editorElement, '.ql-editor').innerHTML - let text = this.quill.getText().trim() - if (html === '


') { - html = null + private createQuillEditor(): void { + this.initQuillElements(); + + const { toolbarElement, editorElement } = this.quillElements; + let defaultModule = { toolbar: toolbarElement }; + let modules = this.modules ? { ...defaultModule, ...this.modules } : defaultModule; + this.quill = new this.dynamicQuill(editorElement, { + modules: modules, + placeholder: this.placeholder, + readOnly: this.readonly, + theme: 'snow', + formats: this.formats, + bounds: this.bounds, + debug: this.debug, + scrollingContainer: this.scrollingContainer + }); + + if (this.value) { + this.quill.setContents(this.quill.clipboard.convert(this.value)); } - this.onTextChange.emit({ - htmlValue: html, - textValue: text, - delta: delta, - source: source, - }) - - this.onModelChange(html) - this.onModelTouched() - } - }) - - this.quill.on('selection-change', (range: string, oldRange: string, source: string) => { - this.onSelectionChange.emit({ - range: range, - oldRange: oldRange, - source: source, - }) - }) - - this.onInit.emit({ - editor: this.quill, - }) - } - - private initQuillElements(): void { - if (!this.quillElements) { - this.quillElements = { - editorElement: DomHandler.findSingle(this.el.nativeElement, 'div.p-editor-content'), - toolbarElement: DomHandler.findSingle(this.el.nativeElement, 'div.p-editor-toolbar'), - } + this.quill.on('text-change', (delta: any, oldContents: any, source: any) => { + if (source === 'user') { + let html = DomHandler.findSingle(editorElement, '.ql-editor').innerHTML; + let text = this.quill.getText().trim(); + if (html === '


') { + html = null; + } + + this.onTextChange.emit({ + htmlValue: html, + textValue: text, + delta: delta, + source: source + }); + + this.onModelChange(html); + this.onModelTouched(); + } + }); + + this.quill.on('selection-change', (range: string, oldRange: string, source: string) => { + this.onSelectionChange.emit({ + range: range, + oldRange: oldRange, + source: source + }); + }); + + this.onInit.emit({ + editor: this.quill + }); + } + + private initQuillElements(): void { + if (!this.quillElements) { + this.quillElements = { + editorElement: DomHandler.findSingle(this.el.nativeElement, 'div.p-editor-content'), + toolbarElement: DomHandler.findSingle(this.el.nativeElement, 'div.p-editor-toolbar') + }; + } } - } } @NgModule({ - imports: [CommonModule], - exports: [Editor, SharedModule], - declarations: [Editor], + imports: [CommonModule], + exports: [Editor, SharedModule], + declarations: [Editor] }) export class EditorModule {}