Compare commits
3 Commits
a55a5f6b06
...
b700ef73ad
Author | SHA1 | Date | |
---|---|---|---|
b700ef73ad | |||
0598e0c6bd | |||
30e4d5c87e |
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"useTabs": false,
|
"useTabs": false,
|
||||||
|
"bracketSameLine": true,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "es5",
|
"trailingComma": "es5",
|
||||||
"printWidth": 100,
|
"printWidth": 100,
|
||||||
|
|
2
src/app.d.ts
vendored
2
src/app.d.ts
vendored
|
@ -9,4 +9,4 @@ declare global {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
export {}
|
||||||
|
|
|
@ -23,7 +23,7 @@ npm/codemirror@5.65.16/theme/nord.min.css"
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta property="og:title" content="Paste - No-database paste service" />
|
<meta property="og:title" content="Paste - No-database paste service" />
|
||||||
<meta property="og:url" content="https://paste.scambier.xyz" />
|
<meta property="og:url" content="https://paste.scambier.xyz" />
|
||||||
<meta property="og:type" content="article" />
|
<meta property="og:type" content="website" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
property="og:description"
|
property="og:description"
|
||||||
|
|
22
src/components/CodeView.svelte
Normal file
22
src/components/CodeView.svelte
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<script lang="ts">
|
||||||
|
export let isMarkdown: boolean
|
||||||
|
export let isPlainText: boolean
|
||||||
|
export let decompressed: string
|
||||||
|
export let htmlContent: string
|
||||||
|
let cssClass = ''
|
||||||
|
export { cssClass as class }
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class={cssClass}>
|
||||||
|
{#if isMarkdown}
|
||||||
|
<div class="h-full p-2">
|
||||||
|
{@html htmlContent}
|
||||||
|
</div>
|
||||||
|
{:else if isPlainText}
|
||||||
|
<div class="whitespace-pre-line h-full">
|
||||||
|
{decompressed}
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<pre class="h-full"><code>{@html htmlContent}</code></pre>
|
||||||
|
{/if}
|
||||||
|
</div>
|
|
@ -62,12 +62,10 @@
|
||||||
type="text"
|
type="text"
|
||||||
bind:value={filter}
|
bind:value={filter}
|
||||||
bind:this={inputFilter}
|
bind:this={inputFilter}
|
||||||
class={$$restProps.class ?? ''}
|
class={$$restProps.class ?? ''} />
|
||||||
/>
|
|
||||||
<div
|
<div
|
||||||
class="absolute top-full left-0 w-full bg-gray-700 max-h-[90vh] overflow-y-auto"
|
class="absolute top-full left-0 w-full bg-gray-700 max-h-[90vh] overflow-y-auto"
|
||||||
bind:this={divContainer}
|
bind:this={divContainer}>
|
||||||
>
|
|
||||||
{#each filteredItems as item}
|
{#each filteredItems as item}
|
||||||
<div class="p-1 hover:bg-gray-600" on:click={() => selectItem(item)}>{item.text}</div>
|
<div class="p-1 hover:bg-gray-600" on:click={() => selectItem(item)}>{item.text}</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -78,8 +76,7 @@
|
||||||
readonly
|
readonly
|
||||||
value={value?.text ?? ''}
|
value={value?.text ?? ''}
|
||||||
class={$$restProps.class ?? ''}
|
class={$$restProps.class ?? ''}
|
||||||
on:click={showOptions}
|
on:click={showOptions} />
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,25 @@
|
||||||
await updateShareUrl()
|
await updateShareUrl()
|
||||||
isUrlInputVisible = true
|
isUrlInputVisible = true
|
||||||
await tick()
|
await tick()
|
||||||
|
urlInput.value = $shareUrl
|
||||||
|
urlInput.select()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function showMarkdownLink() {
|
||||||
|
await updateShareUrl()
|
||||||
|
isUrlInputVisible = true
|
||||||
|
await tick()
|
||||||
|
urlInput.value = `[Paste snippet](${$shareUrl})`
|
||||||
|
urlInput.select()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function showIframeCode() {
|
||||||
|
await updateShareUrl()
|
||||||
|
isUrlInputVisible = true
|
||||||
|
await tick()
|
||||||
|
// @ts-ignore
|
||||||
|
const height = Math.min(editor['doc'].height * 1.1 + 45, 500)
|
||||||
|
urlInput.value = `<iframe width="100%" height="${height}" frameborder="0" src="${$shareUrl}"></iframe>`
|
||||||
urlInput.select()
|
urlInput.select()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,11 +113,13 @@
|
||||||
<input
|
<input
|
||||||
bind:this={urlInput}
|
bind:this={urlInput}
|
||||||
type="text"
|
type="text"
|
||||||
class="border border-gray-300 bg-transparent p-1 grow"
|
class="border border-gray-300 bg-transparent p-1 grow" />
|
||||||
value={$shareUrl}
|
<button class="button" on:click={copyUrl} title="Copy">
|
||||||
/>
|
<Icon class="text-xl" icon="fluent:copy-16-regular" />
|
||||||
<button class="button" on:click={copyUrl}>Copy</button>
|
</button>
|
||||||
<button class="button" on:click={closeUrlInput}>Close</button>
|
<button class="button" on:click={closeUrlInput} title="Close">
|
||||||
|
<Icon class="text-xl" icon="material-symbols:close" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="flex justify-end gap-2">
|
<div class="flex justify-end gap-2">
|
||||||
|
@ -106,11 +127,8 @@
|
||||||
<ComboBox
|
<ComboBox
|
||||||
items={languages}
|
items={languages}
|
||||||
bind:value={selectedLanguage}
|
bind:value={selectedLanguage}
|
||||||
class="bg-gray-700 border border-gray-300 p-1"
|
class="bg-gray-700 border border-gray-300 p-1" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- Show link input-->
|
|
||||||
<button class="button" on:click={showUrlInput}>Get Link</button>
|
|
||||||
|
|
||||||
<!-- Toggle text wrap -->
|
<!-- Toggle text wrap -->
|
||||||
<button class="button" title="Toggle text wrap" on:click={() => (textWrap = !textWrap)}>
|
<button class="button" title="Toggle text wrap" on:click={() => (textWrap = !textWrap)}>
|
||||||
|
@ -121,6 +139,21 @@
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<!-- Show link input -->
|
||||||
|
<button class="button" on:click={showUrlInput} title="Get sharing link">
|
||||||
|
<Icon class="text-xl" icon="ph:link-bold" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Show markdown link -->
|
||||||
|
<button class="button" on:click={showMarkdownLink} title="Get markdown link">
|
||||||
|
<Icon class="text-xl" icon="simple-icons:markdown" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Show HTML iframe -->
|
||||||
|
<button class="button" on:click={showIframeCode} title="Get iframe code">
|
||||||
|
<Icon class="text-xl" icon="fluent:code-24-regular" />
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- Switch to readonly view -->
|
<!-- Switch to readonly view -->
|
||||||
<button class="button" on:click={goToPreview} title="Switch to read-only view">
|
<button class="button" on:click={goToPreview} title="Switch to read-only view">
|
||||||
<Icon class="text-xl" icon="fluent:eye-12-regular" />
|
<Icon class="text-xl" icon="fluent:eye-12-regular" />
|
||||||
|
|
|
@ -2,11 +2,10 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex flex-wrap justify-between items-center px-3 py-1 text-sm w-full z-10 shadow-md gap-2 font-mono bg-gray-700"
|
class="flex flex-wrap justify-between items-center px-3 py-1 text-sm w-full z-10 shadow-md gap-2 font-mono bg-gray-700">
|
||||||
>
|
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<h1 class="text-xl">
|
<h1 class="text-xl">
|
||||||
<a href="/create" title="Create a new note">Paste</a>
|
<a href="/new" title="Create a new note">Paste</a>
|
||||||
</h1>
|
</h1>
|
||||||
<span class="ml-8 text-xs">
|
<span class="ml-8 text-xs">
|
||||||
<a href="/about">About</a>
|
<a href="/about">About</a>
|
||||||
|
|
|
@ -34,3 +34,6 @@ export function getLangFromUrl() {
|
||||||
|
|
||||||
export const byId = (id: string) => document.getElementById(id)
|
export const byId = (id: string) => document.getElementById(id)
|
||||||
|
|
||||||
|
export function isInIframe(): boolean {
|
||||||
|
return window !== window.parent
|
||||||
|
}
|
||||||
|
|
|
@ -8,9 +8,11 @@
|
||||||
import rehypeStringify from 'rehype-stringify'
|
import rehypeStringify from 'rehype-stringify'
|
||||||
import hljs from 'highlight.js'
|
import hljs from 'highlight.js'
|
||||||
import 'highlight.js/styles/nord.min.css'
|
import 'highlight.js/styles/nord.min.css'
|
||||||
|
import { getLangFromUrl, isInIframe } from '$lib/utils'
|
||||||
import TopBar from '../components/TopBar.svelte'
|
import TopBar from '../components/TopBar.svelte'
|
||||||
import Icon from '@iconify/svelte'
|
import Icon from '@iconify/svelte'
|
||||||
import { getLangFromUrl } from '$lib/utils'
|
import CodeView from '../components/CodeView.svelte'
|
||||||
|
import { goto } from '$app/navigation'
|
||||||
|
|
||||||
let decompressed: string
|
let decompressed: string
|
||||||
let htmlContent: string
|
let htmlContent: string
|
||||||
|
@ -51,7 +53,7 @@
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Redirect to editor page
|
// Redirect to editor page
|
||||||
window.location.href = '/editor'
|
goto('/editor')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -61,30 +63,42 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="overflow-hidden h-screen flex flex-col">
|
<div class="overflow-hidden h-screen flex flex-col">
|
||||||
|
{#if !isInIframe()}
|
||||||
<TopBar>
|
<TopBar>
|
||||||
<a
|
<a
|
||||||
href={'/editor' + getUrlDataPart()}
|
href={'/editor' + getUrlDataPart()}
|
||||||
class="p-1 hover:bg-gray-600/50"
|
class="p-1 hover:bg-gray-600/50"
|
||||||
title="Edit a copy of this note"
|
title="Edit a copy of this note">
|
||||||
>
|
|
||||||
<Icon class="text-xl" icon="fluent:document-edit-16-regular" />
|
<Icon class="text-xl" icon="fluent:document-edit-16-regular" />
|
||||||
</a>
|
</a>
|
||||||
</TopBar>
|
</TopBar>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if htmlContent || decompressed}
|
{#if htmlContent || decompressed}
|
||||||
<div class="overflow-y-auto grow">
|
<div class="overflow-y-auto grow pb-4">
|
||||||
<div class="prose dark:prose-invert lg:py-12 p-[0.5em] md:max-w-3xl md:mx-auto lg:max-w-4xl">
|
{#if isInIframe()}
|
||||||
{#if isMarkdown}
|
<CodeView
|
||||||
{@html htmlContent}
|
class="prose dark:prose-invert w-full max-w-full h-full"
|
||||||
{:else if isPlainText}
|
{isMarkdown}
|
||||||
<div class="whitespace-pre-line">
|
{isPlainText}
|
||||||
{decompressed}
|
{decompressed}
|
||||||
</div>
|
{htmlContent} />
|
||||||
{:else}
|
{:else}
|
||||||
<pre><code>{@html htmlContent}</code></pre>
|
<CodeView
|
||||||
|
class="prose dark:prose-invert lg:py-12 p-[0.5em] md:max-w-3xl md:mx-auto lg:max-w-4xl"
|
||||||
|
{isMarkdown}
|
||||||
|
{isPlainText}
|
||||||
|
{decompressed}
|
||||||
|
{htmlContent} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<footer
|
||||||
|
class="absolute bottom-0 left-0 w-full bg-gray-700 px-4 py-1 font-mono text-xs"
|
||||||
|
class:hidden={!isInIframe()}>
|
||||||
|
<a href={window.location.href} target="_blank">Powered by Paste</a>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
|
@ -66,7 +66,6 @@
|
||||||
editor.setValue(decompressed)
|
editor.setValue(decompressed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -80,8 +79,7 @@ npm/codemirror@5.65.16/addon/mode/multiplex.min.js,
|
||||||
npm/codemirror@5.65.16/addon/mode/simple.min.js,
|
npm/codemirror@5.65.16/addon/mode/simple.min.js,
|
||||||
npm/codemirror@5.65.16/addon/scroll/simplescrollbars.js,
|
npm/codemirror@5.65.16/addon/scroll/simplescrollbars.js,
|
||||||
npm/codemirror@5.65.16/mode/meta.min.js"
|
npm/codemirror@5.65.16/mode/meta.min.js"
|
||||||
on:load={initCodeEditor}
|
on:load={initCodeEditor}></script>
|
||||||
></script>
|
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div class="flex flex-col font-mono h-screen bg-gray-700">
|
<div class="flex flex-col font-mono h-screen bg-gray-700">
|
||||||
|
|
Loading…
Reference in New Issue
Block a user