init
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
<script>
|
||||
import { onMount, onDestroy } from "svelte";
|
||||
import { basicSetup, EditorView } from "codemirror";
|
||||
import { EditorState, Compartment } from "@codemirror/state";
|
||||
import { keymap } from "@codemirror/view";
|
||||
import { indentWithTab } from "@codemirror/commands";
|
||||
import { json, jsonParseLinter } from "@codemirror/lang-json";
|
||||
import { linter, lintGutter } from "@codemirror/lint";
|
||||
let parentElement;
|
||||
let codeMirrorView;
|
||||
export let value;
|
||||
export let editable = true;
|
||||
|
||||
onMount(() => {
|
||||
let language = new Compartment();
|
||||
let tabSize = new Compartment();
|
||||
|
||||
let state = EditorState.create({
|
||||
doc: JSON.stringify(value, null, 4),
|
||||
extensions: [
|
||||
basicSetup,
|
||||
keymap.of([indentWithTab]),
|
||||
language.of(json()),
|
||||
json(),
|
||||
tabSize.of(EditorState.tabSize.of(4)),
|
||||
lintGutter(),
|
||||
basicSetup,
|
||||
EditorView.editable.of(editable),
|
||||
EditorView.updateListener.of(function (e) {
|
||||
if (e.docChanged) {
|
||||
value = e.state.doc.toString();
|
||||
}
|
||||
}),
|
||||
linter(jsonParseLinter()),
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
|
||||
codeMirrorView = new EditorView({
|
||||
state,
|
||||
|
||||
parent: parentElement,
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (codeMirrorView) {
|
||||
codeMirrorView.destroy();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="is-editable-{editable}" bind:this={parentElement} />
|
||||
@@ -0,0 +1,58 @@
|
||||
<script>
|
||||
import Sortable from "sortablejs";
|
||||
import { onMount, createEventDispatcher } from "svelte";
|
||||
export let sortableClass;
|
||||
// export let handle;
|
||||
export let isTable = false;
|
||||
export let sortableInstance;
|
||||
const dispatch = createEventDispatcher();
|
||||
let sortableContainer;
|
||||
|
||||
onMount(() => {
|
||||
let options = {
|
||||
// handle: ".sortable-handle",
|
||||
// draggable: ".quote-line-wrapper",
|
||||
// filter: ".not-draggable", // Selectors that do not lead to dragging (String or Function)
|
||||
// preventOnFilter: true,
|
||||
animation: 150, // ms, animation speed moving items when sorting, `0` — without animation
|
||||
easing: "cubic-bezier(1, 0, 0, 1)",
|
||||
onUpdate: function (/**Event*/ evt) {
|
||||
// reorder(evt.oldIndex,evt.newIndex);
|
||||
dispatch("update", {
|
||||
source: evt.oldIndex,
|
||||
target: evt.newIndex,
|
||||
});
|
||||
},
|
||||
onMove(event) {
|
||||
// if (event.related.className.indexOf("not-draggable") > -1) {
|
||||
// return false;
|
||||
// }
|
||||
},
|
||||
};
|
||||
|
||||
// if (handle) {
|
||||
// options.handle = handle;
|
||||
// }
|
||||
sortableInstance = Sortable.create(sortableContainer, options);
|
||||
});
|
||||
|
||||
// function reorder(from, to) {
|
||||
// let newList = JSON.parse(JSON.stringify(value));
|
||||
// let fromElem = newList[from];
|
||||
// newList.splice(from, 1);
|
||||
// newList.splice(to, 0, fromElem);
|
||||
// value = newList;
|
||||
// dispatch("reordered", value);
|
||||
// }
|
||||
</script>
|
||||
|
||||
{#if isTable}
|
||||
<tbody class="sortable-container {sortableClass}" bind:this={sortableContainer}>
|
||||
<slot />
|
||||
</tbody>
|
||||
{:else}
|
||||
<div class="sortable-container {sortableClass}" bind:this={sortableContainer}>
|
||||
<slot />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<script>
|
||||
import {onDestroy, onMount} from "svelte";
|
||||
|
||||
import tinymce from "tinymce/tinymce";
|
||||
import "tinymce/models/dom";
|
||||
import "tinymce/icons/default";
|
||||
import "tinymce/themes/silver";
|
||||
import "tinymce/skins/ui/oxide/skin.css";
|
||||
import contentUiSkinCss from "tinymce/skins/ui/oxide/content.css";
|
||||
|
||||
import "tinymce/plugins/link";
|
||||
import "tinymce/plugins/code";
|
||||
import "tinymce/plugins/image";
|
||||
import "tinymce/plugins/table";
|
||||
import "tinymce/plugins/codesample";
|
||||
import "tinymce/plugins/media";
|
||||
|
||||
import "tinymce/plugins/lists";
|
||||
import "tinymce/plugins/autoresize";
|
||||
import "tinymce/plugins/wordcount";
|
||||
|
||||
export let value = "";
|
||||
export let additionalConfig = {};
|
||||
let lastVal = "";
|
||||
let textareaEl;
|
||||
let activeEditor;
|
||||
let editorWrapper;
|
||||
const plugins = [
|
||||
"autoresize",
|
||||
"code",
|
||||
"image",
|
||||
"table",
|
||||
"codesample",
|
||||
"link",
|
||||
"lists",
|
||||
"media",
|
||||
"wordcount",
|
||||
];
|
||||
const toolbar =
|
||||
"bold italic underline strikethrough removeformat | link | subscript superscript bullist numlist media image codesample table code wordcount blockquote indent outdent blocks";
|
||||
|
||||
onDestroy(() => {
|
||||
if (activeEditor) {
|
||||
activeEditor.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
const config = {
|
||||
target: textareaEl,
|
||||
toolbar_mode: "sliding",
|
||||
toolbar_sticky: true,
|
||||
skin: false,
|
||||
content_css: false,
|
||||
content_style: contentUiSkinCss.toString(),
|
||||
branding: false,
|
||||
inline: false,
|
||||
plugins: plugins,
|
||||
contextmenu: false,
|
||||
menubar: false,
|
||||
statusbar: false,
|
||||
entity_encoding: "raw",
|
||||
convert_urls: false,
|
||||
toolbar: toolbar,
|
||||
image_caption: true,
|
||||
relative_urls: false,
|
||||
browser_spellcheck: true,
|
||||
max_height: 600,
|
||||
// media_poster: false,
|
||||
// content_style:
|
||||
// "body {font-family: 'Averta Std', sans serif; color: #152F77}",
|
||||
setup: function (editor) {
|
||||
activeEditor = editor;
|
||||
|
||||
editor.on("init", function (e) {
|
||||
editor.setContent(value ?? "");
|
||||
});
|
||||
|
||||
// editor.on("blur", function (e) {
|
||||
// let content = setImageDimensions(editor.getContent());
|
||||
// dispatch("editorBlur", content);
|
||||
// editorWrapper.classList.remove("editorFocus");
|
||||
// // return false;
|
||||
// });
|
||||
|
||||
// editor.on("focus", function (e) {
|
||||
// editorWrapper.classList.add("editorFocus");
|
||||
// // return false;
|
||||
// });
|
||||
|
||||
editor.on("change input undo redo", function (e) {
|
||||
lastVal = editor.getContent();
|
||||
if (lastVal !== value) {
|
||||
value = lastVal;
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
tinymce.init({...config, ...additionalConfig});
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<div bind:this={editorWrapper} class="tox-wrapper">
|
||||
<div class="form-control" bind:this={textareaEl}>
|
||||
{@html value}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:global(.tox:not(.tox-tinymce-inline) .tox-editor-header) {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ced4da;
|
||||
box-shadow: none;
|
||||
padding: 4px 0;
|
||||
transition: box-shadow 0.5s;
|
||||
}
|
||||
|
||||
:global(.tox-tinymce) {
|
||||
border: 1px solid #ced4da;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,179 @@
|
||||
<script>
|
||||
import { onMount, onDestroy, tick } from "svelte";
|
||||
|
||||
import tinymce from "tinymce/tinymce";
|
||||
import "tinymce/models/dom";
|
||||
import "tinymce/icons/default";
|
||||
import "tinymce/themes/silver";
|
||||
import "tinymce/skins/ui/oxide/skin.css";
|
||||
import contentUiSkinCss from "tinymce/skins/ui/oxide/content.css";
|
||||
|
||||
import "tinymce/plugins/link";
|
||||
import "tinymce/plugins/code";
|
||||
import "tinymce/plugins/image";
|
||||
import "tinymce/plugins/table";
|
||||
import "tinymce/plugins/codesample";
|
||||
import "tinymce/plugins/media";
|
||||
|
||||
import "tinymce/plugins/lists";
|
||||
import "tinymce/plugins/autoresize";
|
||||
import "tinymce/plugins/wordcount";
|
||||
import BrowseModal from "../records/elements/BrowseModal.svelte";
|
||||
|
||||
export let schemas;
|
||||
export let schema;
|
||||
export let field;
|
||||
export let value = "";
|
||||
export let additionalConfig = {};
|
||||
let browseModal;
|
||||
let lastVal = "";
|
||||
let textareaEl;
|
||||
let activeEditor;
|
||||
let editorWrapper;
|
||||
const plugins = [
|
||||
"autoresize",
|
||||
"code",
|
||||
"image",
|
||||
"table",
|
||||
"codesample",
|
||||
"link",
|
||||
"lists",
|
||||
"media",
|
||||
"wordcount",
|
||||
];
|
||||
const toolbar =
|
||||
"bold italic underline strikethrough removeformat | link image fileManager | subscript superscript bullist numlist media codesample table code wordcount blockquote indent outdent blocks";
|
||||
|
||||
onDestroy(() => {
|
||||
if (activeEditor) {
|
||||
activeEditor.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
const config = {
|
||||
target: textareaEl,
|
||||
toolbar_mode: "sliding",
|
||||
toolbar_sticky: true,
|
||||
skin: false,
|
||||
content_css: false,
|
||||
content_style: contentUiSkinCss.toString(),
|
||||
branding: false,
|
||||
inline: false,
|
||||
plugins: plugins,
|
||||
contextmenu: false,
|
||||
menubar: false,
|
||||
statusbar: false,
|
||||
entity_encoding: "raw",
|
||||
convert_urls: false,
|
||||
toolbar: toolbar,
|
||||
image_caption: true,
|
||||
relative_urls: false,
|
||||
browser_spellcheck: true,
|
||||
max_height: 600,
|
||||
// media_poster: false,
|
||||
// content_style:
|
||||
// "body {font-family: 'Averta Std', sans serif; color: #152F77}",
|
||||
setup: function (editor) {
|
||||
activeEditor = editor;
|
||||
|
||||
editor.on("init", function (e) {
|
||||
editor.setContent(value ?? "");
|
||||
});
|
||||
|
||||
// editor.on("blur", function (e) {
|
||||
// let content = setImageDimensions(editor.getContent());
|
||||
// dispatch("editorBlur", content);
|
||||
// editorWrapper.classList.remove("editorFocus");
|
||||
// // return false;
|
||||
// });
|
||||
|
||||
// editor.on("focus", function (e) {
|
||||
// editorWrapper.classList.add("editorFocus");
|
||||
// // return false;
|
||||
// });
|
||||
|
||||
editor.on("change input undo redo", function (e) {
|
||||
lastVal = editor.getContent();
|
||||
if (lastVal !== value) {
|
||||
value = lastVal;
|
||||
}
|
||||
});
|
||||
|
||||
editor.ui.registry.addMenuButton("fileManager", {
|
||||
icon: "upload",
|
||||
fetch: (callback) => {
|
||||
const items = field.collections.map((c) => {
|
||||
return {
|
||||
type: "menuitem",
|
||||
text:
|
||||
schemas.find((s) => s.name == c).label ??
|
||||
"Schema missing",
|
||||
onAction: () => {
|
||||
openBrowseModal(c);
|
||||
},
|
||||
};
|
||||
});
|
||||
callback(items);
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
tinymce.init({ ...config, ...additionalConfig });
|
||||
});
|
||||
|
||||
function openBrowseModal(aschema) {
|
||||
browseModal.open(aschema);
|
||||
}
|
||||
|
||||
async function insert(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const recordsToInsert = e.detail.records;
|
||||
let fileSchema = schemas.find(
|
||||
(s) => s.name === recordsToInsert[0]._sys.schema
|
||||
);
|
||||
let contentTonInsert = recordsToInsert
|
||||
.map((r) => {
|
||||
if (r._file.mime.startsWith("image")) {
|
||||
let fileUrl =
|
||||
fileSchema.objectStorageProxy + "/" + r._file.path;
|
||||
return `<img src="${fileUrl}" alt="${r._file.path}" width="${r._file.width}" height="${r._file.height}" />`;
|
||||
} else {
|
||||
let fileUrl =
|
||||
fileSchema.objectStorageUrl + "/" + r._file.path;
|
||||
return `<a href="${fileUrl}" title="${r._file.path}">${r._file.path}</a>`;
|
||||
}
|
||||
})
|
||||
.join("<br />");
|
||||
|
||||
activeEditor.insertContent(contentTonInsert);
|
||||
await tick();
|
||||
browseModal.close();
|
||||
}
|
||||
</script>
|
||||
|
||||
<div bind:this={editorWrapper} class="tox-wrapper">
|
||||
<div class="form-control" bind:this={textareaEl}>
|
||||
{@html value}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if field && schema}
|
||||
<BrowseModal bind:this={browseModal} on:insert={insert} />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
:global(.tox:not(.tox-tinymce-inline) .tox-editor-header) {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ced4da;
|
||||
box-shadow: none;
|
||||
padding: 4px 0;
|
||||
transition: box-shadow 0.5s;
|
||||
}
|
||||
|
||||
:global(.tox-tinymce) {
|
||||
border: 1px solid #ced4da;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user