Compressed URL
This commit is contained in:
@@ -2,11 +2,10 @@
|
||||
import { browser } from '$app/env';
|
||||
|
||||
import Card from '$lib/components/card/card.svelte';
|
||||
import { rendererUrl, krokiRendererUrl } from '$lib/util/env';
|
||||
import { base64State, codeStore } from '$lib/util/state';
|
||||
import { toBase64, btoa as jsbtoa } from 'js-base64';
|
||||
import { krokiRendererUrl, rendererUrl } from '$lib/util/env';
|
||||
import { compressedState, codeStore, compressString } from '$lib/util/state';
|
||||
import { toBase64 } from 'js-base64';
|
||||
import moment from 'moment';
|
||||
import pako from 'pako';
|
||||
|
||||
type Exporter = (context: CanvasRenderingContext2D, image: HTMLImageElement) => () => void;
|
||||
|
||||
@@ -109,7 +108,7 @@
|
||||
};
|
||||
|
||||
const onCopyMarkdown = () => {
|
||||
document.getElementById('markdown').select();
|
||||
(document.getElementById('markdown') as HTMLInputElement).select();
|
||||
document.execCommand('Copy');
|
||||
};
|
||||
|
||||
@@ -128,33 +127,9 @@
|
||||
window.location.href = `${window.location.pathname}?gist=${gistURL}`;
|
||||
};
|
||||
|
||||
const textEncode = (str) => {
|
||||
if (window.TextEncoder) {
|
||||
return new TextEncoder('utf-8').encode(str);
|
||||
}
|
||||
let utf8 = unescape(encodeURIComponent(str));
|
||||
let result = new Uint8Array(utf8.length);
|
||||
for (let i = 0; i < utf8.length; i++) {
|
||||
result[i] = utf8.charCodeAt(i);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
const onKrokiClick = () => {
|
||||
const krokiCode = getKrokiCode($codeStore.code);
|
||||
const krokiUrl = `${krokiRendererUrl}/mermaid/svg/${krokiCode}`;
|
||||
return window.open(krokiUrl, '_blank');
|
||||
};
|
||||
|
||||
const getKrokiCode = (source) => {
|
||||
const data = textEncode(source);
|
||||
const compressed = pako.deflate(data, { level: 9, to: 'string' });
|
||||
let result = jsbtoa(compressed).replace(/\+/g, '-').replace(/\//g, '_');
|
||||
return result;
|
||||
};
|
||||
|
||||
let iUrl: string;
|
||||
let svgUrl: string;
|
||||
let krokiUrl: string;
|
||||
let mdCode: string;
|
||||
let imagemodeselected = 'auto';
|
||||
let userimagesize = 1080;
|
||||
@@ -163,14 +138,10 @@
|
||||
if (browser && ['mermaid.live', 'netlify'].some((path) => window.location.host.includes(path))) {
|
||||
isNetlify = true;
|
||||
}
|
||||
base64State.subscribe((encodedState: string) => {
|
||||
const stateCopy = JSON.parse(JSON.stringify($codeStore));
|
||||
if (typeof stateCopy.mermaid === 'string') {
|
||||
stateCopy.mermaid = JSON.parse(stateCopy.mermaid);
|
||||
}
|
||||
const b64Code = toBase64(JSON.stringify(stateCopy), true);
|
||||
iUrl = `${rendererUrl}/img/${b64Code}`;
|
||||
svgUrl = `${rendererUrl}/svg/${b64Code}`;
|
||||
compressedState.subscribe((encodedState: string) => {
|
||||
iUrl = `${rendererUrl}/img/${encodedState}`;
|
||||
svgUrl = `${rendererUrl}/svg/${encodedState}`;
|
||||
krokiUrl = `${krokiRendererUrl}/mermaid/svg/${compressString($codeStore.code)}`;
|
||||
mdCode = `[](${window.location.protocol}//${window.location.host}${window.location.pathname}#${encodedState})`;
|
||||
});
|
||||
</script>
|
||||
@@ -194,8 +165,8 @@
|
||||
<button class="action-btn flex-auto">
|
||||
<a target="_blank" href={svgUrl}><i class="fas fa-external-link-alt mr-2" /> SVG</a>
|
||||
</button>
|
||||
<button class="action-btn flex-auto" on:click={onKrokiClick}>
|
||||
<i class="fas fa-external-link-alt mr-2" /> Kroki
|
||||
<button class="action-btn flex-auto">
|
||||
<a target="_blank" href={krokiUrl}><i class="fas fa-external-link-alt mr-2" /> Kroki</a>
|
||||
</button>
|
||||
|
||||
<div class="flex gap-2 items-center">
|
||||
|
||||
+29
-5
@@ -1,9 +1,10 @@
|
||||
import { writable, get, derived } from 'svelte/store';
|
||||
import type { Readable } from 'svelte/store';
|
||||
import { toBase64, fromBase64 } from 'js-base64';
|
||||
import { fromBase64, toUint8Array, fromUint8Array } from 'js-base64';
|
||||
import { persist, localStorage } from '@macfja/svelte-persistent-store';
|
||||
import type { State } from '$lib/types';
|
||||
import { saveStatistics } from './stats';
|
||||
import pako from 'pako';
|
||||
|
||||
export const defaultState: State = {
|
||||
code: `graph TD
|
||||
@@ -36,15 +37,38 @@ const urlParseFailedState = `graph TD
|
||||
G --> |"No :("| H(Try using the Timeline tab in History <br/>from same browser you used to create the diagram.)
|
||||
click D href "https://github.com/mermaid-js/mermaid-live-editor/issues/new?assignees=&labels=bug&template=bug_report.md&title=Broken%20link" "Raise issue"`;
|
||||
|
||||
const textEncode = (str: string) => {
|
||||
return new TextEncoder().encode(str);
|
||||
};
|
||||
|
||||
export const compressString = (source: string): string => {
|
||||
const data = textEncode(source);
|
||||
const compressed = pako.deflate(data, { level: 9 });
|
||||
const result = fromUint8Array(compressed, true);
|
||||
return result;
|
||||
};
|
||||
|
||||
const decompressString = (source: string): string => {
|
||||
const data = toUint8Array(source);
|
||||
const decompressed = pako.inflate(data, { to: 'string' });
|
||||
return decompressed;
|
||||
};
|
||||
|
||||
export const codeStore = persist(writable(defaultState), localStorage(), 'codeStore');
|
||||
export const base64State: Readable<string> = derived([codeStore], ([code], set) => {
|
||||
set(toBase64(JSON.stringify(code), true));
|
||||
export const compressedState: Readable<string> = derived([codeStore], ([code], set) => {
|
||||
set(compressString(JSON.stringify(code)));
|
||||
});
|
||||
|
||||
export const loadState = (data: string): void => {
|
||||
let state: State;
|
||||
console.log('Loading', data);
|
||||
try {
|
||||
const stateStr = fromBase64(data);
|
||||
let stateStr: string;
|
||||
if (data.startsWith('eyJ')) {
|
||||
stateStr = fromBase64(data);
|
||||
} else {
|
||||
stateStr = decompressString(data);
|
||||
}
|
||||
console.log(`Trying to load state: ${stateStr}`);
|
||||
state = JSON.parse(stateStr);
|
||||
const mermaidConfig =
|
||||
@@ -116,7 +140,7 @@ export const toggleDarkTheme = (dark: boolean): void => {
|
||||
};
|
||||
|
||||
export const initURLSubscription = (): void => {
|
||||
base64State.subscribe((state: string) => {
|
||||
compressedState.subscribe((state: string) => {
|
||||
history.replaceState(undefined, undefined, `#${state}`);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import View from '$lib/components/view.svelte';
|
||||
import Card from '$lib/components/card/card.svelte';
|
||||
import History from '$lib/components/history/history.svelte';
|
||||
import { updateCode, updateConfig, codeStore, base64State } from '$lib/util/state';
|
||||
import { updateCode, updateConfig, codeStore, compressedState } from '$lib/util/state';
|
||||
import { initHandler, syncDiagram } from '$lib/util/util';
|
||||
import { errorStore } from '$lib/util/error';
|
||||
import { onMount } from 'svelte';
|
||||
@@ -15,7 +15,7 @@
|
||||
import type { EditorUpdateEvent, State, Tab } from '$lib/types';
|
||||
import { base } from '$app/paths';
|
||||
|
||||
base64State; // Weird fix for error > base64State is not defined. Treeshaking?
|
||||
compressedState; // Weird fix for error > compressedState is not defined. Treeshaking?
|
||||
let selectedMode = 'code';
|
||||
const languageMap = {
|
||||
code: 'mermaid',
|
||||
@@ -96,7 +96,7 @@
|
||||
};
|
||||
|
||||
const viewDiagram = () => {
|
||||
window.open(`${base}/view#${$base64State}`, '_blank').focus();
|
||||
window.open(`${base}/view#${$compressedState}`, '_blank').focus();
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
|
||||
Reference in New Issue
Block a user