Compressed URL

This commit is contained in:
Sidharth Vinod
2022-01-20 14:19:36 +05:30
parent a8b27fc815
commit 4628a670c8
8 changed files with 81 additions and 56 deletions
+11 -40
View File
@@ -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 = `[![](${iUrl})](${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
View File
@@ -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}`);
});
};
+3 -3
View File
@@ -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 () => {