Skip to content

Commit

Permalink
Fixed #2842 - Editor Quill: SSR error document is not defined
Browse files Browse the repository at this point in the history
  • Loading branch information
mertsincan committed Aug 29, 2022
1 parent af8efc4 commit 7bdbeec
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 41 deletions.
17 changes: 17 additions & 0 deletions api-generator/components/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ const EditorProps = [
type: "any",
default: "null",
description: "Inline style of the container."
},
{
name: 'modules',
type: 'object',
default: 'null',
description: 'Modules configuration, see <a href="http://quilljs.com/docs/modules/">here</a> for available options.'
}
];

Expand Down Expand Up @@ -98,6 +104,17 @@ const EditorEvents = [
description: "Text editor instance."
}
]
},
{
name: 'load',
description: 'Callback to invoke when the quill modules are loaded.',
arguments: [
{
name: 'event.instance',
type: 'any',
description: 'Quill instance'
}
]
}
];

Expand Down
16 changes: 16 additions & 0 deletions src/components/editor/Editor.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ export interface EditorSelectionChangeEvent {
instance: any;
}

export interface EditorLoadEvent {
/**
* Text editor instance.
*/
instance: any;
}

export interface EditorProps {
/**
* Value of the content.
Expand All @@ -72,6 +79,10 @@ export interface EditorProps {
* Inline style of the container.
*/
editorStyle?: any;
/**
* Modules configuration, see [here](https://quilljs.com/docs/modules/) for available options.
*/
modules?: any;
}

export interface EditorSlots {
Expand All @@ -97,6 +108,11 @@ export declare type EditorEmits = {
* @param {EditorSelectionChangeEvent} event - Custom selection change event.
*/
'selection-change': (event: EditorSelectionChangeEvent) => void;
/**
* Callback to invoke when the quill modules are loaded.
* @param {EditorLoadEvent} event - Custom load event.
*/
'load': (event: EditorLoadEvent) => void;
}

declare class Editor extends ClassComponent<EditorProps, EditorSlots, EditorEmits> { }
Expand Down
119 changes: 80 additions & 39 deletions src/components/editor/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,26 @@
</template>

<script>
import Quill from "quill";
import { DomHandler } from 'primevue/utils';
const QuillJS = (function () {
try {
return window.Quill;
} catch {
return null;
}
})();
export default {
name: 'Editor',
emits: ['update:modelValue', 'text-change', 'selection-change'],
emits: ['update:modelValue', 'text-change', 'selection-change', 'load'],
props: {
modelValue: String,
placeholder: String,
readonly: Boolean,
formats: Array,
editorStyle: null
editorStyle: null,
modules: null
},
quill: null,
watch: {
Expand All @@ -69,59 +78,91 @@ export default {
}
},
mounted() {
this.quill = new Quill(this.$refs.editorElement, {
const configuration = {
modules: {
toolbar: this.$refs.toolbarElement
toolbar: this.$refs.toolbarElement,
...this.modules
},
readOnly: this.readonly,
theme: 'snow',
formats: this.formats,
placeholder: this.placeholder
});
};
this.renderValue(this.modelValue);
if (QuillJS) {
// Loaded by script only
this.quill = new QuillJS(this.$refs.editorElement, configuration);
this.initQuill();
this.handleLoad();
} else {
import('quill')
.then((module) => {
if (module && DomHandler.isExist(this.$refs.editorElement)) {
if (module.default) {
// webpack
this.quill = new module.default(this.$refs.editorElement, configuration);
} else {
// parceljs
this.quill = new module(this.$refs.editorElement, configuration);
}
this.quill.on('text-change', (delta, oldContents, source) => {
if (source === 'user') {
let html = this.$refs.editorElement.children[0].innerHTML;
let text = this.quill.getText().trim();
if (html === '<p><br></p>') {
html = '';
}
this.$emit('update:modelValue', html);
this.$emit('text-change', {
htmlValue: html,
textValue: text,
delta: delta,
source: source,
instance: this.quill
this.initQuill();
}
})
.then(() => {
this.handleLoad();
});
}
});
this.quill.on('selection-change', (range, oldRange, source) => {
let html = this.$refs.editorElement.children[0].innerHTML;
let text = this.quill.getText().trim();
this.$emit('selection-change', {
htmlValue: html,
textValue: text,
range: range,
oldRange: oldRange,
source: source,
instance: this.quill
})
});
}
},
methods: {
renderValue(value) {
if (this.quill) {
if (value)
this.quill.pasteHTML(value);
this.quill.setContents(this.quill.clipboard.convert(value));
else
this.quill.setText('');
}
},
initQuill() {
this.renderValue(this.modelValue);
this.quill.on('text-change', (delta, oldContents, source) => {
if (source === 'user') {
let html = this.$refs.editorElement.children[0].innerHTML;
let text = this.quill.getText().trim();
if (html === '<p><br></p>') {
html = '';
}
this.$emit('update:modelValue', html);
this.$emit('text-change', {
htmlValue: html,
textValue: text,
delta: delta,
source: source,
instance: this.quill
});
}
});
this.quill.on('selection-change', (range, oldRange, source) => {
let html = this.$refs.editorElement.children[0].innerHTML;
let text = this.quill.getText().trim();
this.$emit('selection-change', {
htmlValue: html,
textValue: text,
range: range,
oldRange: oldRange,
source: source,
instance: this.quill
})
});
},
handleLoad() {
if (this.quill && this.quill.getModule('toolbar')) {
this.$emit('load', { instance: this.quill });
}
}
},
beforeUnmount() {
Expand Down
4 changes: 4 additions & 0 deletions src/components/utils/DomHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,10 @@ export default {
(element)[methodName].apply(element, args);
},

isExist(element) {
return element !== null && typeof element !== 'undefined' && element.nodeName && element.parentNode;
},

isClient() {
return !!(typeof window !== 'undefined' && window.document && window.document.createElement);
},
Expand Down
1 change: 1 addition & 0 deletions src/components/utils/Utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export declare class DomHandler {
static resolveUserAgent(): { browser: string; version: string; };
static isVisible(el: HTMLElement): boolean;
static invokeElementMethod(el: HTMLElement, methodName: string, args: any): void;
static isExist(el: HTMLElement): boolean;
static isClient(): boolean;
static getFocusableElements(el: HTMLElement, selector?: string): any[];
static getFirstFocusableElement(el: HTMLElement, selector?: string): any;
Expand Down
17 changes: 15 additions & 2 deletions src/views/editor/EditorDoc.vue
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ import Editor from 'primevue/editor';
<td>any</td>
<td>null</td>
<td>Inline style of the container.</td>
</tr>
<tr>
<td>modules</td>
<td>object</td>
<td>null</td>
<td>
Modules configuration, see <a href="http://quilljs.com/docs/modules/">here</a> for available options.
</td>
</tr>
</tbody>
</table>
Expand Down Expand Up @@ -111,6 +119,11 @@ import Editor from 'primevue/editor';
event.textValue: Current value as text.<br/>
event.instance: Text editor instance.</td>
<td>Callback to invoke when selection of the text changes.</td>
</tr>
<tr>
<td>load</td>
<td>event.instance: Quill instance</td>
<td>Callback to invoke when the quill modules are loaded.</td>
</tr>
</tbody>
</table>
Expand Down Expand Up @@ -253,7 +266,7 @@ export default {
'browser-source': {
tabName: 'Browser Source',
imports: `<script src="https://unpkg.com/quill/dist/quill.min.js"><\\/script>
<script src="https://unpkg.com/primevue@^3/editor/editor.min.js"><\\/script>`,
content: `<div id="app">
<h5>Default</h5>
Expand Down Expand Up @@ -298,4 +311,4 @@ export default {
}
}
}
</script>
</script>

0 comments on commit 7bdbeec

Please sign in to comment.