Greasy Fork is available in English.
Export the content generated by the variant as an HTML file
// ==UserScript==
// @name Variant Export
// @description Export the content generated by the variant as an HTML file
// @namespace Violentmonkey Scripts
// @match https://variant.com/*
// @match https://variant.ai/*
// @grant none
// @version 1.0.1
// @author skye-z
// @license MIT
// @description 2026/3/31 17:14:19
// ==/UserScript==
(function() {
'use strict';
const buttonStyle = `
position: absolute;
bottom: 5px;
left: 5px;
z-index: 9999;
padding: 4px 8px;
background: #409eff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
opacity: 0.2;
transition: opacity 0.2s;
`;
const hoverStyle = `
opacity: 1;
background: #337ecc;
`;
function createExportButton(iframe) {
if (iframe.dataset.exportBtnAdded) return;
if (window.getComputedStyle(iframe).position === 'static') {
iframe.style.position = 'relative';
}
const exportBtn = document.createElement('button');
exportBtn.innerText = 'Export';
exportBtn.style.cssText = buttonStyle;
exportBtn.dataset.iframeId = iframe.id || `iframe-${Date.now()}`;
exportBtn.addEventListener('mouseover', () => {
exportBtn.style.cssText = buttonStyle + hoverStyle;
});
exportBtn.addEventListener('mouseout', () => {
exportBtn.style.cssText = buttonStyle;
});
exportBtn.addEventListener('click', () => {
try {
let iframeDoc;
try {
iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
} catch (e) {
alert('Export error: CORS');
return;
}
const htmlContent = `<!DOCTYPE html>${iframeDoc.documentElement.outerHTML}`;
const blob = new Blob([htmlContent], { type: 'text/html' });
const downloadLink = document.createElement('a');
downloadLink.href = URL.createObjectURL(blob);
const fileName = `iframe-export-${new Date().getTime()}.html`;
downloadLink.download = fileName;
downloadLink.click();
URL.revokeObjectURL(downloadLink.href);
} catch (error) {
alert(`Export error: ${error.message}`);
}
});
iframe.parentNode.appendChild(exportBtn);
iframe.dataset.exportBtnAdded = 'true';
const observer = new MutationObserver(() => {
if (!document.body.contains(iframe)) {
exportBtn.remove();
observer.disconnect();
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
function initExportButtons() {
const iframes = document.querySelectorAll('iframe');
iframes.forEach(iframe => {
createExportButton(iframe);
});
}
const iframeObserver = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.tagName === 'IFRAME') {
createExportButton(node);
}
if (node.querySelectorAll) {
const newIframes = node.querySelectorAll('iframe');
newIframes.forEach(iframe => {
createExportButton(iframe);
});
}
});
});
});
iframeObserver.observe(document.body, {
childList: true,
subtree: true
});
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initExportButtons);
} else {
initExportButtons();
}
})();