This commit is contained in:
Timothy Jaeryang Baek
2025-05-03 22:53:23 +04:00
parent 1d82a1c8c4
commit 4acd278624
11 changed files with 370 additions and 222 deletions

View File

@@ -29,15 +29,19 @@
export let oncompositionstart = (e) => {};
export let oncompositionend = (e) => {};
export let onChange = (e) => {};
// create a lowlight instance with all languages loaded
const lowlight = createLowlight(all);
export let className = 'input-prose';
export let placeholder = 'Type here...';
export let value = '';
export let id = '';
export let id = '';
export let value = '';
export let html = '';
export let json = false;
export let raw = false;
export let preserveBreaks = false;
@@ -128,41 +132,43 @@
};
onMount(async () => {
console.log(value);
if (preserveBreaks) {
turndownService.addRule('preserveBreaks', {
filter: 'br', // Target <br> elements
replacement: function (content) {
return '<br/>';
}
});
}
let content = value;
if (!raw) {
async function tryParse(value, attempts = 3, interval = 100) {
try {
// Try parsing the value
return marked.parse(value.replaceAll(`\n<br/>`, `<br/>`), {
breaks: false
});
} catch (error) {
// If no attempts remain, fallback to plain text
if (attempts <= 1) {
return value;
if (!json) {
if (preserveBreaks) {
turndownService.addRule('preserveBreaks', {
filter: 'br', // Target <br> elements
replacement: function (content) {
return '<br/>';
}
// Wait for the interval, then retry
await new Promise((resolve) => setTimeout(resolve, interval));
return tryParse(value, attempts - 1, interval); // Recursive call
}
});
}
// Usage example
content = await tryParse(value);
if (!raw) {
async function tryParse(value, attempts = 3, interval = 100) {
try {
// Try parsing the value
return marked.parse(value.replaceAll(`\n<br/>`, `<br/>`), {
breaks: false
});
} catch (error) {
// If no attempts remain, fallback to plain text
if (attempts <= 1) {
return value;
}
// Wait for the interval, then retry
await new Promise((resolve) => setTimeout(resolve, interval));
return tryParse(value, attempts - 1, interval); // Recursive call
}
}
// Usage example
content = await tryParse(value);
}
}
console.log('content', content);
editor = new Editor({
element: element,
extensions: [
@@ -198,32 +204,44 @@
// force re-render so `editor.isActive` works as expected
editor = editor;
if (!raw) {
let newValue = turndownService
.turndown(
editor
.getHTML()
.replace(/<p><\/p>/g, '<br/>')
.replace(/ {2,}/g, (m) => m.replace(/ /g, '\u00a0'))
)
.replace(/\u00a0/g, ' ');
html = editor.getHTML();
if (!preserveBreaks) {
newValue = newValue.replace(/<br\/>/g, '');
}
onChange({
html: editor.getHTML(),
json: editor.getJSON(),
md: turndownService.turndown(editor.getHTML())
});
if (value !== newValue) {
value = newValue;
if (json) {
value = editor.getJSON();
} else {
if (!raw) {
let newValue = turndownService
.turndown(
editor
.getHTML()
.replace(/<p><\/p>/g, '<br/>')
.replace(/ {2,}/g, (m) => m.replace(/ /g, '\u00a0'))
)
.replace(/\u00a0/g, ' ');
// check if the node is paragraph as well
if (editor.isActive('paragraph')) {
if (value === '') {
editor.commands.clearContent();
if (!preserveBreaks) {
newValue = newValue.replace(/<br\/>/g, '');
}
if (value !== newValue) {
value = newValue;
// check if the node is paragraph as well
if (editor.isActive('paragraph')) {
if (value === '') {
editor.commands.clearContent();
}
}
}
} else {
value = editor.getHTML();
}
} else {
value = editor.getHTML();
}
},
editorProps: {
@@ -356,35 +374,25 @@
}
});
// Update the editor content if the external `value` changes
$: if (
editor &&
(raw
? value !== editor.getHTML()
: value !==
turndownService
.turndown(
(preserveBreaks
? editor.getHTML().replace(/<p><\/p>/g, '<br/>')
: editor.getHTML()
).replace(/ {2,}/g, (m) => m.replace(/ /g, '\u00a0'))
)
.replace(/\u00a0/g, ' '))
) {
if (raw) {
editor.commands.setContent(value);
} else {
preserveBreaks
? editor.commands.setContent(value)
: editor.commands.setContent(
marked.parse(value.replaceAll(`\n<br/>`, `<br/>`), {
breaks: false
})
); // Update editor content
}
selectTemplate();
$: if (value && editor) {
onValueChange();
}
const onValueChange = () => {
if (!editor) return;
if (json) {
if (JSON.stringify(value) !== JSON.stringify(editor.getJSON())) {
editor.commands.setContent(value);
selectTemplate();
}
} else {
if (value !== editor.getHTML()) {
editor.commands.setContent(value);
selectTemplate();
}
}
};
</script>
<div bind:this={element} class="relative w-full min-w-full h-full min-h-fit {className}" />