Preview HTML code on chatgpt.com by adding an iframe below code blocks with class 'language-html'. Allows downloading of the HTML preview.
// ==UserScript== // @name ChatGPT 代码预览助手 - Code Previewer for ChatGPT // @namespace http://xyde.net.cn // @version 1.5 // @description Preview HTML code on chatgpt.com by adding an iframe below code blocks with class 'language-html'. Allows downloading of the HTML preview. // @author You // @match https://chatgpt.com/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // Function to create preview container function createPreviewContainer(htmlCode, id) { // Create container div const container = document.createElement('div'); container.style.border = '1px solid #ddd'; container.style.borderRadius = '5px'; container.style.marginTop = '10px'; container.style.padding = '10px'; container.style.backgroundColor = '#f9f9f9'; container.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)'; container.style.position = 'relative'; // Ensure relative positioning container.id = 'container-' + id; // Create title const title = document.createElement('div'); title.textContent = 'HTML Code Preview 网页代码预览'; title.style.fontWeight = 'bold'; title.style.marginBottom = '10px'; title.style.textAlign = 'center'; // Create iframe const iframe = document.createElement('iframe'); iframe.className = 'html-preview-iframe'; iframe.style.width = '100%'; iframe.style.height = '300px'; iframe.style.border = 'none'; iframe.id = 'code-preview-' + id; // Wait for iframe to load before setting content iframe.onload = function() { const doc = iframe.contentDocument || iframe.contentWindow.document; doc.open(); doc.write(htmlCode); doc.close(); }; // Create download button const downloadButton = document.createElement('a'); downloadButton.href = 'data:text/html;charset=utf-8,' + encodeURIComponent(htmlCode); downloadButton.download = 'preview.html'; downloadButton.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" style="position: absolute; top: 5px; right: 5px; cursor: pointer;"> <path d="M12 15.41l6.29-6.29 1.41 1.41L12 18.23 4.3 10.12l1.41-1.41z"/> </svg> `; downloadButton.style.position = 'absolute'; downloadButton.style.top = '5px'; downloadButton.style.right = '5px'; downloadButton.style.cursor = 'pointer'; // Append title, iframe, and download button to container container.appendChild(title); container.appendChild(downloadButton); container.appendChild(iframe); return container; } // Function to find and process code elements function processCodeElements() { // Find all code elements with class 'language-html' const codeElements = document.querySelectorAll('code.language-html'); // Iterate through each code element codeElements.forEach(codeElement => { // Check if it has already been processed if (codeElement.dataset.previewed){ if(new Date().getSeconds() % 5 != 0){ return; } let iframeToRemove = document.querySelector("#container-" + codeElement.dataset.id); iframeToRemove.parentNode.removeChild(iframeToRemove); } // Mark as previewed codeElement.dataset.previewed = true; codeElement.dataset.id = Math.ceil(Math.random()*100000); // Get parent element of code block const parentElement = codeElement.closest('.flex-col'); // Create a preview container const previewContainer = createPreviewContainer(codeElement.textContent, codeElement.dataset.id); // Insert container below the code element parentElement.appendChild(previewContainer); }); } // Run processCodeElements initially and then every 3 seconds processCodeElements(); setInterval(processCodeElements, 3000); })();