Trying to get more of the Tiptap buttons to work. Why does only bold, italics, strike work???

This commit is contained in:
Scott Idem
2024-11-22 17:19:00 -05:00
parent dd8181ba0e
commit 4c09edaceb
4 changed files with 305 additions and 111 deletions

View File

@@ -1,18 +1,31 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { fade } from 'svelte/transition'
import { Color } from '@tiptap/extension-color'
import ListItem from '@tiptap/extension-list-item'
import TextStyle from '@tiptap/extension-text-style'
import StarterKit from "@tiptap/starter-kit";
import { Editor } from "@tiptap/core";
// import Highlight from '@tiptap/extension-highlight';
import { cubicOut } from 'svelte/easing';
// import Highlight from '@tiptap/extension-highlight' ????
// import Typography from '@tiptap/extension-typography' ????
// Import Tiptap related modules
import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";
import Bold from '@tiptap/extension-bold';
import BulletList from '@tiptap/extension-bullet-list';
import CodeBlock from '@tiptap/extension-code-block';
import Code from '@tiptap/extension-code';
import Color from '@tiptap/extension-color';
import Document from '@tiptap/extension-document';
import Heading from '@tiptap/extension-heading';
import Highlight from '@tiptap/extension-highlight';
import History from '@tiptap/extension-history';
import Italic from '@tiptap/extension-italic';
import Link from '@tiptap/extension-link';
import ListItem from '@tiptap/extension-list-item';
import OrderedList from '@tiptap/extension-ordered-list';
import Paragraph from '@tiptap/extension-paragraph';
import Strike from '@tiptap/extension-strike';
import Text from '@tiptap/extension-text';
import TextStyle from '@tiptap/extension-text-style';
import Typography from '@tiptap/extension-typography';
import "./element_tiptap_editor.scss";
import { cubicOut } from 'svelte/easing';
// https://tiptap.dev/docs/examples/basics/default-text-editor
// https://tiptap.dev/docs/examples/basics/formatting
@@ -67,14 +80,27 @@ let show_button_kv_defaults: any = {
italic: true,
strike: true,
code: true,
paragraph: true,
heading__h1: true,
heading__h2: true,
heading__h3: true,
unsetAllMarks: true,
heading__h4: false,
heading__h5: false,
heading__h6: false,
bulletList: true,
orderedList: true,
codeBlock: false,
blockquote: false,
horizontalRule: false,
hardBreak: true,
link: true,
unsetLink: true,
unsetAllMarks: true,
undo: true,
redo: true,
};
@@ -93,9 +119,86 @@ onMount(() => {
editor = new Editor({
element: element,
extensions: [
// StarterKit,
Bold, // part of StarterKit
Code, // part of StarterKit
CodeBlock, // part of StarterKit
Italic, // part of StarterKit
Strike, // part of StarterKit
BulletList, // part of StarterKit
Color.configure({ types: [TextStyle.name, ListItem.name] }),
TextStyle.configure({ types: [ListItem.name] }),
StarterKit,
Heading.configure({ levels: [1, 2, 3, 4, 5, 6] }),
Highlight,
History.configure({
depth: 100,
newGroupDelay: 500
}),
Link.configure({
openOnClick: false,
autolink: true,
defaultProtocol: 'https',
protocols: ['http', 'https'],
isAllowedUri: (url, ctx) => {
try {
// construct URL
const parsedUrl = url.includes(':') ? new URL(url) : new URL(`${ctx.defaultProtocol}://${url}`)
// use default validation
if (!ctx.defaultValidate(parsedUrl.href)) {
return false
}
// disallowed protocols
const disallowedProtocols = ['ftp', 'file', 'mailto']
const protocol = parsedUrl.protocol.replace(':', '')
if (disallowedProtocols.includes(protocol)) {
return false
}
// only allow protocols specified in ctx.protocols
const allowedProtocols = ctx.protocols.map(p => (typeof p === 'string' ? p : p.scheme))
if (!allowedProtocols.includes(protocol)) {
return false
}
// disallowed domains
const disallowedDomains = ['example-phishing.com', 'malicious-site.net']
const domain = parsedUrl.hostname
if (disallowedDomains.includes(domain)) {
return false
}
// all checks have passed
return true
} catch (error) {
return false
}
},
shouldAutoLink: url => {
try {
// construct URL
const parsedUrl = url.includes(':') ? new URL(url) : new URL(`https://${url}`)
// only auto-link if the domain is not in the disallowed list
const disallowedDomains = ['example-no-autolink.com', 'another-no-autolink.com']
const domain = parsedUrl.hostname
return !disallowedDomains.includes(domain)
} catch (error) {
return false
}
},
}),
ListItem,
Document,
OrderedList, // part of StarterKit
Paragraph,
Text,
Typography,
],
content: html_text,
onTransaction: () => {
@@ -399,6 +502,32 @@ let mouse_leave_wait: number = 2000;
</span>
<span>
<!-- Links: -->
<button
type="button"
on:click={() => editor.chain().focus().toggleLink({ href: 'https://example.com' }).run()}
class="btn btn-sm variant-glass-secondary hover:variant-filled-secondary rounded-md"
class:variant-ghost-success={editor.isActive('link') ? 'is-active' : ''}
class:hidden={!show_button_kv.link}
title="Link"
>
<span class="fas fa-link mx-1"></span>
<!-- Link -->
</button>
<button
type="button"
on:click={() => editor.chain().focus().unsetLink().run()}
class="btn btn-sm variant-glass-secondary hover:variant-filled-warning rounded-md"
class:hidden={!show_button_kv.unsetLink}
title="Unset link"
>
<span class="fas fa-unlink mx-1"></span>
<!-- Unset link -->
</button>
</span>
<span
class="justify-self-end"
>