2023-01-19 08:57:25 +01:00
|
|
|
<script>
|
|
|
|
import Icon from './icon.svelte';
|
|
|
|
import Modal from './modal.svelte';
|
|
|
|
import ObjectTree from './objecttree.svelte';
|
|
|
|
import { onDestroy } from 'svelte';
|
2023-02-19 17:26:32 +01:00
|
|
|
import { deepClone } from '$lib/objects';
|
2023-01-19 08:57:25 +01:00
|
|
|
|
|
|
|
export let data;
|
|
|
|
|
|
|
|
let copySucceeded = false;
|
|
|
|
let timeout;
|
2023-01-20 13:54:57 +01:00
|
|
|
let _data;
|
|
|
|
|
|
|
|
$: if (data) {
|
2023-02-19 17:26:32 +01:00
|
|
|
_data = deepClone(data);
|
2023-01-20 13:54:57 +01:00
|
|
|
for (const key of Object.keys(_data)) {
|
|
|
|
if (typeof _data[key] === 'undefined') {
|
|
|
|
delete _data[key];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-01-19 08:57:25 +01:00
|
|
|
|
|
|
|
async function copy() {
|
2023-01-20 13:54:57 +01:00
|
|
|
await navigator.clipboard.writeText(JSON.stringify(_data));
|
2023-01-19 08:57:25 +01:00
|
|
|
copySucceeded = true;
|
|
|
|
timeout = setTimeout(() => copySucceeded = false, 1500);
|
|
|
|
}
|
|
|
|
|
|
|
|
onDestroy(() => clearTimeout(timeout));
|
|
|
|
</script>
|
|
|
|
|
|
|
|
{#if data}
|
2023-01-20 13:54:57 +01:00
|
|
|
<Modal bind:show={data} title="Object viewer">
|
2023-01-19 08:57:25 +01:00
|
|
|
<div class="objectviewer">
|
|
|
|
<div class="buttons">
|
|
|
|
<button class="btn" on:click={copy}>
|
|
|
|
<Icon name={copySucceeded ? 'check' : 'clipboard'} />
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<div class="code">
|
2023-01-20 13:54:57 +01:00
|
|
|
<ObjectTree data={_data} />
|
2023-01-19 08:57:25 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</Modal>
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
<style>
|
|
|
|
.objectviewer {
|
|
|
|
position: relative;
|
|
|
|
}
|
2023-01-31 16:58:23 +01:00
|
|
|
|
|
|
|
.objectviewer .code :global(span.root) {
|
|
|
|
display: block;
|
|
|
|
}
|
|
|
|
|
2023-01-19 08:57:25 +01:00
|
|
|
.buttons {
|
|
|
|
position: absolute;
|
|
|
|
top: 0;
|
|
|
|
right: 0;
|
|
|
|
}
|
|
|
|
.buttons button {
|
|
|
|
margin-left: 1rem;
|
|
|
|
}
|
|
|
|
</style>
|