Skip to content

Instantly share code, notes, and snippets.

@markflorkowski
Created September 23, 2024 21:52
Show Gist options
  • Save markflorkowski/4269bc529324dceb2858c77b7609704c to your computer and use it in GitHub Desktop.
Save markflorkowski/4269bc529324dceb2858c77b7609704c to your computer and use it in GitHub Desktop.
ReplicateUI
(async function downloadCompleteHTML() {
// Helper function to fetch content of external files (CSS, JS, images)
async function fetchResource(url, isBinary = false) {
try {
const response = await fetch(url);
if (isBinary) {
const blob = await response.blob();
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
} else {
return await response.text();
}
} catch (error) {
console.warn('Failed to fetch resource:', url);
return '';
}
}
// Helper function to inline external CSS and convert relative URLs to absolute
async function inlineCSS(linkElement) {
const href = linkElement.href;
const cssContent = await fetchResource(href);
// Resolve relative URLs within CSS (for images, fonts, etc.)
const resolvedCSS = cssContent.replace(/url\((?!['"]?(?:data|https?|ftp):)['"]?([^'")]+)['"]?\)/g, function(match, relativeUrl) {
const absoluteUrl = new URL(relativeUrl, href).href;
return `url(${absoluteUrl})`;
});
// Create a <style> tag with the inlined CSS
const styleElement = document.createElement('style');
styleElement.textContent = resolvedCSS;
return styleElement;
}
// Helper function to convert images to base64-encoded data URIs
async function inlineImages(element) {
const images = element.querySelectorAll('img');
for (let img of images) {
if (img.src.startsWith('http')) {
const dataUri = await fetchResource(img.src, true);
img.src = dataUri; // Replace the src with base64-encoded data URI
}
}
}
// Get the entire DOM HTML structure
const html = document.documentElement.outerHTML;
// Create a new document to parse and modify the HTML content
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
// Inline all external CSS files
const linkElements = [...doc.querySelectorAll('link[rel="stylesheet"]')];
for (let link of linkElements) {
const inlineStyleElement = await inlineCSS(link);
link.replaceWith(inlineStyleElement);
}
// Inline all images as base64 data URIs
await inlineImages(doc);
// Get the final HTML including the modified DOM
const finalHTML = doc.documentElement.outerHTML;
// Create a downloadable HTML file
const downloadHTML = (content, fileName) => {
const a = document.createElement("a");
const file = new Blob([content], { type: "text/html" });
a.href = URL.createObjectURL(file);
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
// Download the final HTML file
downloadHTML(finalHTML, "index.html");
// Hide loading overlay
loadingOverlay.style.display = 'none';
})();
@StKotok
Copy link

StKotok commented Sep 25, 2024

@MuwMx,
You can create a bookmarklet and use it bookmarklet on any page you want to save.
Just click it, and a downloadable file will be created automatically.
Screenshot 2024-09-25 at 23 51 12

How to create the bookmarklet

  1. Initiate creating a new bookmark in your browser.

    If you cannot initiate the creation of a new bookmark...

    ..., you can edit any existing one by changing its name and the link to the program code.

  2. Give it a name. I named it "💾".

  3. Paste the code below as the URL of the bookmark.

    javascript:(async function downloadCompleteHTML() { async function fetchResource(url, isBinary = false) { try { const response = await fetch(url); if (isBinary) { const blob = await response.blob(); return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.onerror = reject; reader.readAsDataURL(blob); }); } else { return await response.text(); } } catch (error) { console.warn('Failed to fetch resource:', url); return ''; } } async function inlineCSS(linkElement) { const href = linkElement.href; const cssContent = await fetchResource(href); const resolvedCSS = cssContent.replace(/url\((?!['"]?(?:data|https?|ftp):)['"]?([^'")]+)['"]?\)/g, function(match, relativeUrl) { const absoluteUrl = new URL(relativeUrl, href).href; return `url(${absoluteUrl})`; }); const styleElement = document.createElement('style'); styleElement.textContent = resolvedCSS; return styleElement; } async function inlineImages(element) { const images = element.querySelectorAll('img'); for (let img of images) { if (img.src.startsWith('http')) { const dataUri = await fetchResource(img.src, true); img.src = dataUri; } } } const html = document.documentElement.outerHTML; const parser = new DOMParser(); const doc = parser.parseFromString(html, "text/html"); const linkElements = [...doc.querySelectorAll('link[rel="stylesheet"]')]; for (let link of linkElements) { const inlineStyleElement = await inlineCSS(link); link.replaceWith(inlineStyleElement); } await inlineImages(doc); const finalHTML = doc.documentElement.outerHTML; const downloadHTML = (content, fileName) => { const a = document.createElement("a"); const file = new Blob([content], { type: "text/html" }); a.href = URL.createObjectURL(file); a.download = fileName; document.body.appendChild(a); a.click(); document.body.removeChild(a); }; downloadHTML(finalHTML, "index.html"); })();
    
  4. Save the bookmark. 🎉, you have just created the "💾" bookmarklet.


👉🏻 Note: It may not work on some websites (e.g., GitHub) due to security policies.

@CyberClarence
Copy link

@MuwMx
i made a website to make it easier to use: https://nocodexport.com/

@crutch12
Copy link

crutch12 commented Sep 26, 2024

I've added Tampermonkey (https://www.tampermonkey.net/) script for this implementation.

Tampermonkey is plugin to run scripts on any page
e.g. in Chrome: https://chromewebstore.google.com/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo

Here is the script and guide
https://gist.github.com/crutch12/a43178a7c45d2dc8ecfbbcb05a9246e3

@TowhidKashem
Copy link

@MuwMx i made a website to make it easier to use: https://nocodexport.com/

Nice homie!

@2PyKu
Copy link

2PyKu commented Oct 10, 2024

https://drive.google.com/file/d/14yRZZf4_gEdBdZJ0auwmnXVQf73iBZMu/view?usp=sharing

Hi.

  1. Unpack dlindexhtml.zip
  2. Installing the extension to Chrome:
    Open Chrome and go to the chrome://extensions/ page.
    Turn on developer mode in the top right corner.
    Click “Download unzipped extension” and select the folder with your extension.

@steinathan
Copy link

Cool

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment