Skip to content

Commit

Permalink
Throw typed event when rich text changes
Browse files Browse the repository at this point in the history
1. Throw event when rich text changes, rather than rely on observable property
2. Removed references to lazy loading of Quill, which is no longer the point of why I'm doing it this way
  • Loading branch information
deanmoses committed Jan 2, 2023
1 parent 16e2a11 commit 9961aa2
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 61 deletions.
10 changes: 10 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@playwright/test": "1.29.1",
"@sveltejs/adapter-static": "^1.0.0",
"@sveltejs/kit": "1.0.1",
"@types/quill": "^1.3.10",
"@typescript-eslint/eslint-plugin": "^5.47.1",
"@typescript-eslint/parser": "^5.47.1",
"eslint": "^8.31.0",
Expand Down
18 changes: 6 additions & 12 deletions src/lib/components/site/edit/EditableHtml.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,14 @@
*/
export let htmlContent = '';
// The edited content
let newHtmlContent: string;
// Update the draft store any time the HTML is edited
// The $: is Svelte syntax. This gets compiled into a
// reactive statement that executes whenever any of the
// variables referenced within it changes.
$: {
if (newHtmlContent == null) {
console.log('<EditableHtml>: newHtmlContent null');
function handleChange(event: CustomEvent<{ html: string }>) {
if (event.detail.html == null) {
console.log('<EditableHtml>: html is null');
} else {
DraftStore.setDesc(newHtmlContent);
// TODO: this class should not know about DraftStore nor the specific field they represent ("desc", "title")
DraftStore.setDesc(event.detail.html);
}
}
</script>

<HtmlEditor {htmlContent} bind:newHtmlContent />
<HtmlEditor {htmlContent} on:change={handleChange} />
81 changes: 32 additions & 49 deletions src/lib/components/site/edit/HtmlEditor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,25 @@
WYSIWYG editor for HTML content
-->
<script lang="ts">
import { onMount } from 'svelte';
import { onMount, createEventDispatcher } from 'svelte';
import Quill from 'quill';
const dispatch = createEventDispatcher<{ change: { html: string } }>();
/**
* The HTML content to be made editable
*/
export let htmlContent = '';
/**
* The edited content.
* Don't pass in anything to this; instead, do a bind:newHtmlContent to get the value
*/
export let newHtmlContent: string = null;
let editor;
let quill;
// Instance of the Quill rich text editor
let quill: Quill;
// The buttons to show in Quill's toolbar
const toolbar = [
['bold', 'italic', 'underline'],
[{ list: 'ordered' }, { list: 'bullet' }],
['link']
];
// What formatting the Quill.js editor allows, whether via the toolbar
// or via keystroke commands (or pasting content in?)
const formats = ['header', 'bold', 'italic', 'underline', 'strike', 'list', 'bullet', 'link'];
// The DOM node on which the Quill editor is mounted
let editorElement: HTMLDivElement;
// Load the Quill.js WYSIWYG editor when the component is mounted,
// so as to be able to pass the DOM node into Quill's constructor
onMount(async () => {
// Load the Quill.js WYSIWYG editor async
// TODO: confirm this is actually prevents the bits from being included in the initial bundle
const { default: Quill } = await import('quill');
// Prevent Quill from adding target="_blank" and rel="noopener noreferrer" to links
const Link = Quill.import('formats/link');
class MyLink extends Link {
Expand All @@ -50,41 +37,37 @@
}
Quill.register(MyLink);
quill = new Quill(editor, {
theme: 'bubble', // The "bubble" theme pops up the toolbar when text is selected, rather than it being there permanently
let editor: HTMLDivElement;
quill = new Quill(editorElement, {
// This theme pops up the toolbar when text is selected, rather than displaying it permanently
theme: 'bubble',
modules: {
toolbar: toolbar
// Toolbar buttons
toolbar: [
['bold', 'italic', 'underline'],
[{ list: 'ordered' }, { list: 'bullet' }],
['link']
]
},
formats: formats
// The formatting to allow in content, including pasted-in content
formats: ['header', 'bold', 'italic', 'underline', 'strike', 'list', 'bullet', 'link']
});
// Every time the text in Quill changes, update my public newHtmlContent property
// so that my parent component can listen to it changing via Svelte's bind: syntax.
quill.on('text-change', (delta, oldDelta, source) => {
newHtmlContent = quill.root.innerHTML;
quill.on('text-change', () => {
dispatch('change', {
html: quill.root.innerHTML
});
});
});
// When navigating from one photo to the next while in edit mode,
// Svelte doesn't create a new rich text editor component, but instead
// re-uses the existing one containing the caption from the previous
// photo. So here, we are using Svelte's $: syntax to detect when
// the htmlContent property changes and set the contents of the editor.
//
// This depends on the onMount() always loading the editor before this
// runs. In my testing that is what happens, but I'm not sure if it's
// guaranteed.
//
// I should remove the onMount(). It exists to lazy load the editor
// so that non-admin viewers of Tacocat don't have to load it, but
// that job is being handled by Svelte's route-level code splitting.
// re-uses the existing one, which contains the caption from the previous
// photo. So here we use Svelte's $: reactive syntax to ensure when
// a new value is passed in to the htmlContent property, it sets the
// contents of the editor.
$: {
if (!quill) {
console.log(
"The Quill rich text editor isn't loaded yet, so I can't set its contents to ",
htmlContent
);
} else {
if (quill) {
quill.setContents(
quill.clipboard.convert(htmlContent ?? ''),
'silent' /* Don't trigger a text-change event */
Expand All @@ -93,7 +76,7 @@
}
</script>

<div bind:this={editor} />
<div bind:this={editorElement} />

<style>
@import 'https://cdn.quilljs.com/1.3.7/quill.bubble.css';
Expand Down

0 comments on commit 9961aa2

Please sign in to comment.