Getting the new new new rich text editor working. I think it is working... Yay Shad Editor that uses TipTap and Shadcn.
This commit is contained in:
@@ -121,112 +121,112 @@ export let new_html: string = '';
|
||||
|
||||
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
|
||||
Underline, // part of StarterKit
|
||||
BulletList, // part of StarterKit
|
||||
// Color.configure({ types: [TextStyle.name, ListItem.name] }),
|
||||
// TextStyle.configure({ types: [ListItem.name] }),
|
||||
// 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}`)
|
||||
// element: element,
|
||||
// extensions: [
|
||||
// // StarterKit,
|
||||
// Bold, // part of StarterKit
|
||||
// Code, // part of StarterKit
|
||||
// CodeBlock, // part of StarterKit
|
||||
// Italic, // part of StarterKit
|
||||
// Strike, // part of StarterKit
|
||||
// Underline, // part of StarterKit
|
||||
// BulletList, // part of StarterKit
|
||||
// // Color.configure({ types: [TextStyle.name, ListItem.name] }),
|
||||
// // TextStyle.configure({ types: [ListItem.name] }),
|
||||
// // 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
|
||||
}
|
||||
// // use default validation
|
||||
// if (!ctx.defaultValidate(parsedUrl.href)) {
|
||||
// return false
|
||||
// }
|
||||
|
||||
// disallowed protocols
|
||||
const disallowedProtocols = ['ftp', 'file', 'mailto']
|
||||
const protocol = parsedUrl.protocol.replace(':', '')
|
||||
// // disallowed protocols
|
||||
// const disallowedProtocols = ['ftp', 'file', 'mailto']
|
||||
// const protocol = parsedUrl.protocol.replace(':', '')
|
||||
|
||||
if (disallowedProtocols.includes(protocol)) {
|
||||
return false
|
||||
}
|
||||
// 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))
|
||||
// // 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
|
||||
}
|
||||
// if (!allowedProtocols.includes(protocol)) {
|
||||
// return false
|
||||
// }
|
||||
|
||||
// disallowed domains
|
||||
const disallowedDomains = ['example-phishing.com', 'malicious-site.net']
|
||||
const domain = parsedUrl.hostname
|
||||
// // disallowed domains
|
||||
// const disallowedDomains = ['example-phishing.com', 'malicious-site.net']
|
||||
// const domain = parsedUrl.hostname
|
||||
|
||||
if (disallowedDomains.includes(domain)) {
|
||||
return false
|
||||
}
|
||||
// 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}`)
|
||||
// // 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
|
||||
// // 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: ({ editor, transaction }) => {
|
||||
// console.log('onTransaction');
|
||||
// force re-render so `editor.isActive` works as expected
|
||||
// editor = editor;
|
||||
// return !disallowedDomains.includes(domain)
|
||||
// } catch (error) {
|
||||
// return false
|
||||
// }
|
||||
// },
|
||||
// }),
|
||||
// ListItem,
|
||||
// Document,
|
||||
// OrderedList, // part of StarterKit
|
||||
// Paragraph,
|
||||
// Text,
|
||||
// Typography,
|
||||
// ],
|
||||
// content: html_text,
|
||||
// onTransaction: ({ editor, transaction }) => {
|
||||
// // console.log('onTransaction');
|
||||
// // force re-render so `editor.isActive` works as expected
|
||||
// // editor = editor;
|
||||
|
||||
// let updated_html = editor.getHTML();
|
||||
// if (updated_html == '<p></p>') {
|
||||
// new_html = '';
|
||||
// } else {
|
||||
// new_html = updated_html;
|
||||
// }
|
||||
},
|
||||
onUpdate: ({ editor }) => {
|
||||
console.log('onUpdate', editor.getHTML());
|
||||
let updated_html = editor.getHTML();
|
||||
if (updated_html == '<p></p>') {
|
||||
new_html = '';
|
||||
} else {
|
||||
new_html = updated_html;
|
||||
}
|
||||
}
|
||||
// // let updated_html = editor.getHTML();
|
||||
// // if (updated_html == '<p></p>') {
|
||||
// // new_html = '';
|
||||
// // } else {
|
||||
// // new_html = updated_html;
|
||||
// // }
|
||||
// },
|
||||
// onUpdate: ({ editor }) => {
|
||||
// // console.log('onUpdate', editor.getHTML());
|
||||
// // let updated_html = editor.getHTML();
|
||||
// // if (updated_html == '<p></p>') {
|
||||
// // new_html = '';
|
||||
// // } else {
|
||||
// // new_html = updated_html;
|
||||
// // }
|
||||
// }
|
||||
});
|
||||
});
|
||||
|
||||
@@ -248,9 +248,11 @@ let mouse_enter_wait: number = 500;
|
||||
let mouse_leave_wait: number = 2000;
|
||||
</script>
|
||||
|
||||
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- class:py-1={show_menu} -->
|
||||
{#if 1==3}
|
||||
<div
|
||||
on:click={() => {
|
||||
if (default_minimal) {
|
||||
@@ -285,6 +287,7 @@ let mouse_leave_wait: number = 2000;
|
||||
// }
|
||||
}}
|
||||
class="editor textarea p-1 transition-all duration-1000"
|
||||
class:hidden={true}
|
||||
>
|
||||
|
||||
<!-- && show_menu -->
|
||||
@@ -619,8 +622,16 @@ let mouse_leave_wait: number = 2000;
|
||||
>{placeholder}</span>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<main class="my-10 flex w-full flex-col items-center justify-center">
|
||||
<ShadEditor
|
||||
class="editor textarea p-1 transition-all duration-1000"
|
||||
bind:content={html_text}
|
||||
bind:new_html={new_html}
|
||||
/>
|
||||
</main>
|
||||
|
||||
<style lang="scss">
|
||||
// :global(.ProseMirror) {
|
||||
|
||||
Reference in New Issue
Block a user