Bump version, refine element hydration, fix animation, fix title in blog post
This commit is contained in:
parent
858142f09a
commit
4543680a92
|
@ -654,7 +654,10 @@ onMounted(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<canvas id="ecmaportal" class="fixed top-0 left-0 opacity-0 parallax -z-10">
|
||||
<canvas
|
||||
id="ecmaportal"
|
||||
class="fixed top-0 left-0 opacity-0 transition-portal -z-10"
|
||||
>
|
||||
<span>
|
||||
Your browser does not support the <canvas /> element, which is
|
||||
required for parallax animation.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: The hidden features of the Windows OOBE
|
||||
title: The Hidden Features of the Windows OOBE
|
||||
description: The Windows 11 OOBE is a mess, but it's excellent for bulk deployment and has some hidden features and customization options!
|
||||
authors: ['Enderman']
|
||||
created: 2024-03-01T23:30:10Z
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "enderapp",
|
||||
"version": "0.2.5",
|
||||
"version": "0.3.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { formatDate } from 'date-fns'
|
||||
import chestAnimation from '~/assets/images/chest.webp'
|
||||
import { render } from 'vue'
|
||||
|
||||
const config = useAppConfig()
|
||||
const route = useRoute()
|
||||
|
@ -37,6 +38,20 @@ useSeoMeta({
|
|||
twitterCard: 'summary_large_image',
|
||||
})
|
||||
|
||||
const clipboard = (el: HTMLElement) => {
|
||||
if (el.textContent)
|
||||
navigator.clipboard
|
||||
.writeText(el.textContent)
|
||||
.then(() => {
|
||||
alert(`successfully copied ${el.textContent}`)
|
||||
})
|
||||
.catch(() => {
|
||||
alert('something went wrong')
|
||||
})
|
||||
}
|
||||
|
||||
const content = ref<Element | null>(null)
|
||||
|
||||
if (data.value) {
|
||||
thumbnail =
|
||||
data.value.thumbnail ??
|
||||
|
@ -60,52 +75,21 @@ if (data.value) {
|
|||
|
||||
// Hydrate the rendered items.
|
||||
onMounted(() => {
|
||||
document.querySelectorAll('pre').forEach((pre) => {
|
||||
const icon = document.createElement('iconify-icon')
|
||||
|
||||
icon.setAttribute('icon', 'mdi:content-copy')
|
||||
icon.setAttribute('inline', 'true')
|
||||
|
||||
icon.classList.add('button')
|
||||
|
||||
pre.appendChild(icon)
|
||||
})
|
||||
|
||||
document
|
||||
.querySelectorAll('code:not(pre *), pre > iconify-icon.button')
|
||||
.forEach((code) => {
|
||||
if (code instanceof HTMLElement) {
|
||||
code.onclick = () => {
|
||||
const area = document.createElement('textarea')
|
||||
|
||||
area.textContent =
|
||||
code.nodeName && code.nodeName.toLowerCase() === 'code'
|
||||
? code.textContent
|
||||
: code.parentElement!.textContent
|
||||
|
||||
// It's necessary to create the textarea element every time you copy to get access to the select() method.
|
||||
area.setSelectionRange(0, 99999) // An iOS gotcha.
|
||||
area.select()
|
||||
|
||||
// Copy the text inside the textarea.
|
||||
navigator.clipboard.writeText(area.value)
|
||||
|
||||
// TODO: Alert the user text has been successfully copied.
|
||||
|
||||
// Remove the textarea element.
|
||||
area.remove()
|
||||
}
|
||||
}
|
||||
content.value
|
||||
?.querySelectorAll('code:not(pre *)')
|
||||
.forEach((code: Element) => {
|
||||
if (code instanceof HTMLElement) code.onclick = () => clipboard(code)
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
document.querySelectorAll('code').forEach((code) => {
|
||||
code.onclick = null
|
||||
})
|
||||
content.value?.querySelectorAll('pre').forEach((pre: HTMLElement) => {
|
||||
const icon = h('iconify-icon', {
|
||||
icon: 'mdi:content-copy',
|
||||
inline: true,
|
||||
class: 'button',
|
||||
onClick: () => clipboard(pre),
|
||||
})
|
||||
|
||||
document.querySelectorAll('pre').forEach((pre) => {
|
||||
pre.querySelector('.clipboard')?.remove()
|
||||
render(icon, pre)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -127,7 +111,7 @@ useHead({
|
|||
|
||||
<template>
|
||||
<div
|
||||
v-if="status === 'pending'"
|
||||
v-if="!data"
|
||||
class="flex flex-col items-center justify-center gap-4 w-full select-none text-center"
|
||||
>
|
||||
<img draggable="false" :src="chestAnimation" alt="The Ender Chest" />
|
||||
|
@ -139,7 +123,7 @@ useHead({
|
|||
</div>
|
||||
</div>
|
||||
<article
|
||||
v-else-if="status === 'success' && data"
|
||||
v-else-if="data"
|
||||
class="flex-grow post snap-normal fade-mask-sm flex flex-col gap-4 overflow-x-hidden overflow-y-auto sm:py-4 sm:pe-4"
|
||||
>
|
||||
<div class="grid-thumbnail grid max-w-[768px] snap-end">
|
||||
|
@ -189,7 +173,7 @@ useHead({
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section class="page snap-start">
|
||||
<section ref="content" class="page snap-start">
|
||||
<ContentRenderer :value="data" />
|
||||
</section>
|
||||
</article>
|
||||
|
|
Loading…
Reference in New Issue