mirror of
https://github.com/garraflavatra/rolens.git
synced 2025-07-14 04:34:04 +00:00
Implement object viewer based on codemirror
This commit is contained in:
@ -1,64 +1,77 @@
|
||||
<script>
|
||||
import Icon from './icon.svelte';
|
||||
import Modal from './modal.svelte';
|
||||
import ObjectTree from './objecttree.svelte';
|
||||
import { onDestroy } from 'svelte';
|
||||
import { deepClone } from '$lib/objects';
|
||||
import { createEventDispatcher, onDestroy } from 'svelte';
|
||||
import ObjectEditor from './objecteditor.svelte';
|
||||
import { jsonLooseParse } from '$lib/strings';
|
||||
|
||||
export let data;
|
||||
export let saveable = false;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
let copySucceeded = false;
|
||||
let timeout;
|
||||
let _data;
|
||||
let text = JSON.stringify(data, undefined, '\t');
|
||||
let newData;
|
||||
let invalid = false;
|
||||
|
||||
$: if (data) {
|
||||
_data = deepClone(data);
|
||||
for (const key of Object.keys(_data)) {
|
||||
if (typeof _data[key] === 'undefined') {
|
||||
delete _data[key];
|
||||
}
|
||||
$: {
|
||||
try {
|
||||
newData = jsonLooseParse(text);
|
||||
}
|
||||
catch {
|
||||
invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
async function copy() {
|
||||
await navigator.clipboard.writeText(JSON.stringify(_data));
|
||||
await navigator.clipboard.writeText(text);
|
||||
copySucceeded = true;
|
||||
timeout = setTimeout(() => copySucceeded = false, 1500);
|
||||
}
|
||||
|
||||
function close() {
|
||||
data = undefined;
|
||||
text = '';
|
||||
}
|
||||
|
||||
function save() {
|
||||
dispatch('save', text);
|
||||
}
|
||||
|
||||
onDestroy(() => clearTimeout(timeout));
|
||||
</script>
|
||||
|
||||
{#if data}
|
||||
<Modal bind:show={data} title="Object viewer">
|
||||
<Modal bind:show={data} contentPadding={false}>
|
||||
<div class="objectviewer">
|
||||
<div class="buttons">
|
||||
<button class="btn" on:click={copy}>
|
||||
<Icon name={copySucceeded ? 'check' : 'clipboard'} />
|
||||
</button>
|
||||
</div>
|
||||
<div class="code">
|
||||
<ObjectTree data={_data} />
|
||||
</div>
|
||||
<ObjectEditor {text} />
|
||||
</div>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
{#if saveable}
|
||||
<button class="btn" on:click={save} disabled={invalid}>
|
||||
<Icon name="save" /> Save
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<button class="btn secondary" on:click={close}>
|
||||
<Icon name="x" /> Close
|
||||
</button>
|
||||
|
||||
<button class="btn secondary" on:click={copy}>
|
||||
<Icon name={copySucceeded ? 'check' : 'clipboard'} /> Copy
|
||||
</button>
|
||||
</svelte:fragment>
|
||||
</Modal>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.objectviewer {
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.objectviewer .code :global(span.root) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
.buttons button {
|
||||
margin-left: 1rem;
|
||||
justify-content: stretch;
|
||||
align-items: stretch;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user