Compare commits
2 commits
4ab42f9543
...
64d01a9b45
Author | SHA1 | Date | |
---|---|---|---|
64d01a9b45 | |||
8033b18a64 |
8 changed files with 140 additions and 53 deletions
21
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
21
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myValues">
|
||||||
|
<value>
|
||||||
|
<list size="7">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="nobr" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="noembed" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="comment" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="noscript" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="embed" />
|
||||||
|
<item index="5" class="java.lang.String" itemvalue="script" />
|
||||||
|
<item index="6" class="java.lang.String" itemvalue="oom-comments" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myCustomValuesEnabled" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
25
.idea/jsonSchemas.xml
generated
Normal file
25
.idea/jsonSchemas.xml
generated
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JsonSchemaMappingsProjectConfiguration">
|
||||||
|
<state>
|
||||||
|
<map>
|
||||||
|
<entry key="Azure Static Web Apps configuration file">
|
||||||
|
<value>
|
||||||
|
<SchemaInfo>
|
||||||
|
<option name="name" value="Azure Static Web Apps configuration file" />
|
||||||
|
<option name="relativePathToSchema" value="https://www.schemastore.org/staticwebapp.config.json" />
|
||||||
|
<option name="applicationDefined" value="true" />
|
||||||
|
<option name="patterns">
|
||||||
|
<list>
|
||||||
|
<Item>
|
||||||
|
<option name="path" value="staticwebapp.config.json" />
|
||||||
|
</Item>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</SchemaInfo>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</state>
|
||||||
|
</component>
|
||||||
|
</project>
|
1
.idea/mercury.iml
generated
1
.idea/mercury.iml
generated
|
@ -10,5 +10,6 @@
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="n20171213" level="application" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
|
@ -234,6 +234,9 @@ const domain = Astro.url.host
|
||||||
|
|
||||||
// Initialize with default config
|
// Initialize with default config
|
||||||
initSearch();
|
initSearch();
|
||||||
|
|
||||||
|
// Re-initialize when Astro's view transitions occur, this provides fix for SPA navigation
|
||||||
|
document.addEventListener('astro:page-load', initSearch);
|
||||||
</script>}
|
</script>}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -8,7 +8,11 @@ const ArtalkInstanceDomain = siteConfig.comments.artalk.instanceDomain
|
||||||
<div id="comments" data-path={Astro.url.pathname} data-server={ArtalkInstanceDomain}></div>
|
<div id="comments" data-path={Astro.url.pathname} data-server={ArtalkInstanceDomain}></div>
|
||||||
<script>
|
<script>
|
||||||
import Artalk from "artalk";
|
import Artalk from "artalk";
|
||||||
|
|
||||||
|
function initArtalk() {
|
||||||
const atkElement = document.querySelector('#comments');
|
const atkElement = document.querySelector('#comments');
|
||||||
|
|
||||||
|
if (!atkElement) return;
|
||||||
Artalk.init({
|
Artalk.init({
|
||||||
el: '#comments',
|
el: '#comments',
|
||||||
pageKey: atkElement?.getAttribute('data-path') || window.location.pathname,
|
pageKey: atkElement?.getAttribute('data-path') || window.location.pathname,
|
||||||
|
@ -16,5 +20,14 @@ const ArtalkInstanceDomain = siteConfig.comments.artalk.instanceDomain
|
||||||
darkMode: "auto",
|
darkMode: "auto",
|
||||||
versionCheck: false
|
versionCheck: false
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize on page load
|
||||||
|
document.addEventListener('DOMContentLoaded', initArtalk);
|
||||||
|
|
||||||
|
// Re-initialize on view transitions, fix issues with Astro's ClientRouter
|
||||||
|
document.addEventListener('astro:page-load', () => {
|
||||||
|
initArtalk();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
|
@ -54,25 +54,34 @@ const { encryptedData, iv } = encrypt(content, password);
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Client-side decryption logic
|
// Define the function that sets up the decryption logic
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
function setupDecryption() {
|
||||||
const containers = document.querySelectorAll('.encrypted-content');
|
const containers = document.querySelectorAll('.encrypted-content');
|
||||||
|
|
||||||
containers.forEach(container => {
|
containers.forEach(container => {
|
||||||
const encryptedData = container.getAttribute('data-encrypted');
|
const encryptedData = container.getAttribute('data-encrypted');
|
||||||
const iv = container.getAttribute('data-iv');
|
const iv = container.getAttribute('data-iv');
|
||||||
const passwordInput = container.querySelector('.decrypt-password');
|
const passwordInput = container.querySelector<HTMLInputElement>('.decrypt-password');
|
||||||
const decryptButton = container.querySelector('.decrypt-button');
|
const decryptButton = container.querySelector<HTMLButtonElement>('.decrypt-button');
|
||||||
const contentContainer = container.querySelector('.content-container');
|
const contentContainer = container.querySelector<HTMLDivElement>('.content-container');
|
||||||
const passwordForm = container.querySelector('.password-form');
|
const passwordForm = container.querySelector<HTMLDivElement>('.password-form');
|
||||||
|
|
||||||
|
if (!encryptedData || !iv || !passwordInput || !decryptButton || !contentContainer || !passwordForm) {
|
||||||
|
console.error('Missing required elements for decryption');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if already initialized to prevent duplicate event listeners
|
||||||
|
if (container.getAttribute("initialized") === 'true') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
decryptButton.addEventListener('click', async () => {
|
decryptButton.addEventListener('click', async () => {
|
||||||
try {
|
try {
|
||||||
const password = passwordInput.value;
|
const password = passwordInput.value;
|
||||||
if (!password) return;
|
if (!password) return;
|
||||||
|
|
||||||
const content = await decrypt(encryptedData, iv, password);
|
contentContainer.innerHTML = await decrypt(encryptedData, iv, password);
|
||||||
contentContainer.innerHTML = content;
|
|
||||||
contentContainer.classList.remove('hidden');
|
contentContainer.classList.remove('hidden');
|
||||||
passwordForm.classList.add('hidden');
|
passwordForm.classList.add('hidden');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -82,14 +91,18 @@ const { encryptedData, iv } = encrypt(content, password);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allow pressing Enter to decrypt
|
// Allow pressing Enter to decrypt
|
||||||
passwordInput.addEventListener('keydown', (e) => {
|
passwordInput.addEventListener('keydown', (e: KeyboardEvent) => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
decryptButton.click();
|
decryptButton.click();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
async function decrypt(encryptedData, iv, password) {
|
// Mark as initialized to prevent duplicate event listeners
|
||||||
|
container.setAttribute("initialized", 'true');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function decrypt(encryptedData: string, iv: string, password: string): Promise<string> {
|
||||||
// Convert base64 to array buffer
|
// Convert base64 to array buffer
|
||||||
const encryptedBytes = Uint8Array.from(atob(encryptedData), c => c.charCodeAt(0));
|
const encryptedBytes = Uint8Array.from(atob(encryptedData), c => c.charCodeAt(0));
|
||||||
const ivBytes = Uint8Array.from(atob(iv), c => c.charCodeAt(0));
|
const ivBytes = Uint8Array.from(atob(iv), c => c.charCodeAt(0));
|
||||||
|
@ -129,5 +142,10 @@ const { encryptedData, iv } = encrypt(content, password);
|
||||||
const decoder = new TextDecoder();
|
const decoder = new TextDecoder();
|
||||||
return decoder.decode(decryptedBytes);
|
return decoder.decode(decryptedBytes);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
// Initialize on page load
|
||||||
|
document.addEventListener('DOMContentLoaded', setupDecryption);
|
||||||
|
|
||||||
|
// Re-initialize when Astro's view transitions occur, this provides fix for SPA navigation
|
||||||
|
document.addEventListener('astro:page-load', setupDecryption);
|
||||||
</script>
|
</script>
|
|
@ -9,6 +9,7 @@ export const siteConfig = {
|
||||||
email: 'hi@mercury.info',
|
email: 'hi@mercury.info',
|
||||||
},
|
},
|
||||||
// features
|
// features
|
||||||
|
spa: false, // enable single page application mode, this will enable navigation (with fade transitions) without reloading the page, and enable client-side routing
|
||||||
noClientJavaScript: false, // disable client-side javascript, this will:
|
noClientJavaScript: false, // disable client-side javascript, this will:
|
||||||
// 1. disable most built-in client-side javascript from rendering (protected content component and umami still needs javascript to function, sorry)
|
// 1. disable most built-in client-side javascript from rendering (protected content component and umami still needs javascript to function, sorry)
|
||||||
// 2. the full text search will be redirected to a search engine
|
// 2. the full text search will be redirected to a search engine
|
||||||
|
|
|
@ -19,6 +19,9 @@ interface Props {
|
||||||
ogImage?: string;
|
ogImage?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import { ClientRouter } from "astro:transitions";
|
||||||
|
const spaEnabled = siteConfig.spa
|
||||||
|
|
||||||
const noscript = siteConfig.noClientJavaScript
|
const noscript = siteConfig.noClientJavaScript
|
||||||
|
|
||||||
const statisticsEnabled = siteConfig.siteAnalytics.enabled
|
const statisticsEnabled = siteConfig.siteAnalytics.enabled
|
||||||
|
@ -44,6 +47,8 @@ const { title = pageTitle, author = siteConfig.defaultAuthor.name,description =
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator} />
|
||||||
<Meta title={pageTitle} author={author} description={description} ogImage={ogImage} />
|
<Meta title={pageTitle} author={author} description={description} ogImage={ogImage} />
|
||||||
<title>{pageTitle}</title>
|
<title>{pageTitle}</title>
|
||||||
|
{spaEnabled && <ClientRouter fallback="animate" />}
|
||||||
|
<!--transitional animation is broken in firefox though-->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue