Skip to content

Commit 9e16bf0

Browse files
committed
updates
1 parent a16349d commit 9e16bf0

File tree

91 files changed

+3215
-1354
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+3215
-1354
lines changed

app/app.vue

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,28 @@
1111
import "./assets/style.css";
1212
import "highlight.js/styles/github-dark-dimmed.min.css"
1313
14-
</script>
1514
16-
<style lang="scss"></style>
15+
useSeoMeta({
16+
description: 'Explore how HTML is parsed by the browser and common libraries.',
17+
ogTitle: 'Dom-Explorer',
18+
ogDescription: 'Explore how HTML is parsed by the browser and common libraries.',
19+
ogImage: '/icon.svg',
20+
twitterTitle: 'Dom-Explorer',
21+
twitterDescription: 'Explore how HTML is parsed by the browser and common libraries.',
22+
twitterImage: '/icon.svg',
23+
twitterCard: 'summary'
24+
})
25+
26+
useHead({
27+
htmlAttrs: {
28+
lang: 'en'
29+
},
30+
link: [
31+
{
32+
rel: 'icon',
33+
type: 'image/png',
34+
href: '/icon.svg'
35+
}
36+
]
37+
})
38+
</script>

app/assets/style.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
@tailwind components;
33
@tailwind utilities;
44

5+
56
@layer base {
67
:root {
78
/* Name: custom color palette
89
Author: Ilias Ism
910
URL: https://gradient.page */
1011

1112
/* CSS: .bg-gradient { background: var(--gradient) } */
12-
--gradient: linear-gradient(to top left,#000C40,#607D8B);
13+
--gradient: linear-gradient(to top left, #000c40, #607d8b);
1314
--background: 243 100% 98.26%;
1415
--foreground: 243 10% 0.52%;
1516

@@ -41,7 +42,6 @@
4142

4243
--radius: 0.5rem;
4344

44-
4545
/* Name: custom color palette
4646
Author: Ilias Ism
4747
URL: https://gradient.page */
@@ -87,5 +87,5 @@
8787
}
8888

8989
html {
90-
@apply bg-black text-foreground;
90+
@apply text-foreground bg-black;
9191
}

app/components/CodeEditor.vue

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="group relative grid resize-y grid-cols-1 grid-rows-1">
2+
<div class="group/editor relative grid resize-y grid-cols-1 grid-rows-1">
33
<div
44
el="output"
55
class="col-start-1 row-start-1 max-w-full whitespace-pre-wrap break-all rounded-md border bg-card p-2 font-mono text-card-foreground"
@@ -12,11 +12,13 @@
1212
spellcheck="false"
1313
:placeholder="placeholder"
1414
:readonly="readOnly"
15+
:disabled="readOnly"
1516
rows="1"
16-
class="col-start-1 row-start-1 h-full resize-none whitespace-pre-wrap break-all rounded-md border-none bg-transparent p-2 font-mono text-transparent caret-black/80 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring dark:caret-white/80"
17+
class="col-start-1 row-start-1 h-full resize-none whitespace-pre-wrap break-all rounded-md border border-transparent bg-transparent p-2 font-mono text-transparent caret-black/80 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring dark:caret-white/80"
18+
@keydown="onKeyDown"
1719
/>
1820
<div
19-
class="absolute right-0 top-0 rounded-bl-md rounded-tr-md bg-muted px-1.5 pt-0.5 font-mono text-xs text-muted-foreground group-focus-within:bg-ring group-focus-within:text-white"
21+
class="absolute right-0 top-0 rounded-bl-md rounded-tr-md bg-muted px-1.5 pt-0.5 font-mono text-xs text-muted-foreground group-focus-within/editor:bg-ring group-focus-within/editor:text-white"
2022
>
2123
{{ shortLang }}
2224
</div>
@@ -70,4 +72,20 @@ const shortLang = computed(() => {
7072
}
7173
return props.lang;
7274
});
75+
76+
function onKeyDown(e: KeyboardEvent) {
77+
if (e.key === "Tab") {
78+
e.preventDefault();
79+
const el = textarea.value!;
80+
const start = el.selectionStart;
81+
const end = el.selectionEnd;
82+
83+
model.value =
84+
model.value.substring(0, start) + "\t" + model.value.substring(end);
85+
86+
nextTick(() => {
87+
el.selectionStart = el.selectionEnd = start + 1;
88+
});
89+
}
90+
}
7391
</script>

app/components/CopyButton.vue

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,37 @@
11
<template>
2-
<Tooltip :label="label">
3-
<slot :copy="copy">
4-
<Button size="icon" class="size-8">
5-
<Icon name="copy" class="size-6" @click="copy" />
6-
</Button>
7-
</slot>
8-
</Tooltip>
2+
<Button :tooltip="_tooltip" :icon="_icon" :label="_label" @click="copy" />
93
</template>
104

115
<script lang="ts" setup>
6+
import type { IconName } from "./ui/icon";
7+
128
const props = defineProps<{
139
value: string;
10+
noTooltip?: boolean;
11+
tooltip?: string;
12+
icon?: IconName;
13+
label?: string;
1414
}>();
1515
16-
const label = refAutoReset("Copy", 1000);
16+
const copied = refAutoReset(false, 1000);
1717
1818
function copy() {
19-
label.value = "Copied!";
19+
copied.value = true;
2020
navigator.clipboard.writeText(props.value);
2121
}
22+
23+
const _tooltip = computed(() => {
24+
if (!props.tooltip) return undefined;
25+
return copied.value ? "Copied!" : props.tooltip;
26+
});
27+
28+
const _label = computed(() => {
29+
if (!props.label) return undefined;
30+
return copied.value ? "Copied" : props.label;
31+
});
32+
33+
const _icon = computed(() => {
34+
if (!props.icon) return undefined;
35+
return copied.value ? "check" : props.icon;
36+
});
2237
</script>

app/components/DomExplorer/DomExplorerFrame.vue

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
autofocus
1414
:copy-code="false"
1515
/>
16-
<Pipeline v-if="pipeline" :input="state.input ?? ''" :pipeline="pipeline" />
16+
<Pipelines :state="state" :read-only="settings.readonly" is-embed />
1717
<a
18+
v-if="isEmbed"
1819
:href="href"
1920
target="_blank"
20-
class="absolute bottom-0 right-0 flex items-center rounded-tl border-l border-t border-[#00dc8266] bg-gray-900 px-2 text-[0.7rem] tracking-wide group-hover:pointer-events-none"
21+
class="fixed bottom-0 right-0 z-[100] flex items-center rounded-tl border-l border-t border-[#00dc8266] bg-gray-900 px-2 text-[0.7rem] tracking-wide"
2122
>
2223
<DomExplorerIcon class="size-4" />
2324
</a>
@@ -27,28 +28,18 @@
2728
<script setup lang="ts">
2829
import type { DomExplorerState } from "~/types";
2930
30-
definePageMeta({
31-
layout: "empty",
32-
});
33-
34-
const props = defineProps<{
31+
defineProps<{
3532
state: DomExplorerState;
36-
filter?: string;
33+
isEmbed?: boolean;
3734
}>();
3835
39-
const pipeline = computed(() => {
40-
if (props.filter) {
41-
return props.state.pipelines.find((p) => p.id === props.filter);
42-
}
43-
return props.state.pipelines.at(0);
44-
});
45-
4636
const settings = useDomExplorerSettings();
47-
37+
const route = useRoute();
4838
const href = computed(() => {
49-
const url = new URL("/Dom-Explorer/dom-explorer", window.location.origin);
50-
url.hash = window.location.hash;
51-
52-
return url.href;
39+
return resolveRemoteLink({
40+
name: "index",
41+
query: route.query,
42+
hash: route.hash,
43+
});
5344
});
5445
</script>
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
<template>
2+
<DualSheet
3+
title="Embed Options"
4+
description="Embed one or more pipeline into your website."
5+
>
6+
<template #trigger>
7+
<slot />
8+
</template>
9+
<template #center>
10+
<Card class="relative max-w-full resize overflow-auto rounded-md">
11+
<div class="rounded-t-md bg-secondary p-2">
12+
<CardTitle class="relative flex justify-between gap-2">
13+
Preview
14+
<div
15+
class="absolute -bottom-1 right-0 font-mono text-xs text-muted-foreground"
16+
>
17+
{{ Math.ceil(size.width.value) }}x{{
18+
Math.ceil(size.height.value)
19+
}}
20+
</div>
21+
</CardTitle>
22+
</div>
23+
<CardContent ref="frameContent" class="group p-0">
24+
<DomExplorerFrame :state="_state" />
25+
</CardContent>
26+
</Card>
27+
</template>
28+
<template #side>
29+
<div
30+
class="grid grid-flow-row auto-rows-[minmax(32px,auto)] grid-cols-[auto_1fr] gap-x-8"
31+
>
32+
<Label class="content-center"> Input </Label>
33+
<VisibilitySelect v-model="settings.input" />
34+
<Label class="content-center"> Title Bar </Label>
35+
<VisibilitySelect v-model="settings.titleBar" />
36+
<Label
37+
class="group col-span-full grid cursor-pointer grid-cols-[subgrid] content-center items-center"
38+
>
39+
Readonly
40+
<Checkbox
41+
id="readonly-check"
42+
v-model="settings.readonly"
43+
class="outline outline-1 outline-transparent transition-all group-hover:outline-blue-400"
44+
/>
45+
</Label>
46+
<h2 class="col-span-full pb-2 pt-4 text-lg font-light">
47+
Pipes Options
48+
</h2>
49+
<Label
50+
class="group col-span-full grid cursor-pointer grid-cols-[subgrid] content-center items-center"
51+
>
52+
Title bar
53+
<Checkbox
54+
id="readonly-check"
55+
v-model="settings.pipe.titleBar"
56+
class="outline outline-1 outline-transparent transition-all group-hover:outline-blue-400"
57+
/>
58+
</Label>
59+
<Label
60+
class="group col-span-full grid cursor-pointer grid-cols-[subgrid] content-center items-center"
61+
>
62+
Settings button
63+
<Checkbox
64+
id="readonly-check"
65+
v-model="settings.pipe.settings"
66+
class="outline outline-1 outline-transparent transition-all group-hover:outline-blue-400"
67+
/>
68+
</Label>
69+
70+
<Label
71+
class="group col-span-full grid cursor-pointer grid-cols-[subgrid] content-center items-center"
72+
>
73+
Render button
74+
<Checkbox
75+
id="readonly-check"
76+
v-model="settings.pipe.render"
77+
class="outline outline-1 outline-transparent transition-all group-hover:outline-blue-400"
78+
/>
79+
</Label>
80+
81+
<Label
82+
class="group col-span-full grid cursor-pointer grid-cols-[subgrid] content-center items-center"
83+
>
84+
Skip button
85+
<Checkbox
86+
id="readonly-check"
87+
v-model="settings.pipe.skip"
88+
class="outline outline-1 outline-transparent transition-all group-hover:outline-blue-400"
89+
/>
90+
</Label>
91+
</div>
92+
93+
<div class="flex flex-col gap-3 pb-4 pt-8">
94+
<h2 class="col-span-full pb-2 pt-4 text-lg font-light">Code</h2>
95+
<Textarea
96+
:model-value="code"
97+
spellcheck="false"
98+
class="min-h-24 min-w-0 overflow-auto break-all font-mono"
99+
/>
100+
<div class="flex justify-between gap-4 pt-2">
101+
<NuxtLink :to="url" target="_blank">
102+
<Button label="Open in new tab" icon="externalLink" />
103+
</NuxtLink>
104+
<CopyButton :value="code" icon="copy" no-tooltip label="Copy code" />
105+
</div>
106+
</div>
107+
</template>
108+
</DualSheet>
109+
</template>
110+
111+
<script lang="ts" setup>
112+
import type { DomExplorerState } from "~/types";
113+
114+
const props = defineProps<{
115+
state: DomExplorerState;
116+
}>();
117+
118+
const _state = ref(cloneState(props.state));
119+
120+
watch(
121+
() => props.state,
122+
(state) => {
123+
_state.value = cloneState(state);
124+
},
125+
);
126+
127+
const frameContent = ref();
128+
const size = useElementBounding(frameContent);
129+
130+
const settings = createDomExplorerSettings({
131+
input: "editable",
132+
titleBar: "readonly",
133+
readonly: true,
134+
pipe: {
135+
titleBar: true,
136+
settings: true,
137+
render: true,
138+
skip: true,
139+
},
140+
});
141+
142+
const url = computed(() => {
143+
return resolveRemoteLink({
144+
name: "frame",
145+
hash: "#" + b64EncodeUnicode(JSON.stringify(_state.value)),
146+
query: {
147+
input: settings.input,
148+
titleBar: settings.titleBar,
149+
readonly: settings.readonly ? "true" : "false",
150+
"pipe[titleBar]": settings.pipe.titleBar ? "true" : "false",
151+
"pipe[settings]": settings.pipe.settings ? "true" : "false",
152+
"pipe[render]": settings.pipe.render ? "true" : "false",
153+
"pipe[skip]": settings.pipe.skip ? "true" : "false",
154+
},
155+
});
156+
});
157+
158+
const code = computed(() => {
159+
const iframe = document.createElement("iframe");
160+
iframe.sandbox.add("allow-scripts", "allow-modals", "allow-popups");
161+
iframe.src = url.value;
162+
return iframe.outerHTML;
163+
});
164+
</script>

0 commit comments

Comments
 (0)