Hi there! Lately, I’ve been working a lot with text generation and AI in general. During testing, seeing the result is critical, and the standard “extended” preview of 200 characters feels completely insufficient.
So, with some spare time and enthusiasm, I created a script for Tampermonkey that allows you to open a popup with the copied text right after clicking the copy button. This makes it convenient to preview text from any AI or other nodes.
The code is still quite rough and sometimes triggers on adjacent buttons due to the specific structure of the output elements. However, it currently meets all my needs for working with text, and I’d love to share it with others.
If anyone is interested in improving it or making their own changes, feel free to jump in!
Here’s the full code:
// ==UserScript==
// @name Output Popup Latenode v0.1
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Show copied text in a draggable and resizable popup after clicking on an SVG icon
// @author
// @match *://*/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const buttonSelector = 'span svg[data-icon="copy"]';
const styles = `
#copy-popup {
position: fixed;
background: #343541;
color: #FFFFFF;
border: 1px solid #202123;
padding: 0;
z-index: 10000;
width: 400px;
font-size: 14px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
resize: both;
overflow: hidden;
display: flex;
flex-direction: column;
min-width: 200px;
min-height: 250px;
}
#copy-popup-header {
padding: 10px;
cursor: move;
background: #444654;
border-bottom: 1px solid #202123;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
display: flex;
align-items: center;
flex-shrink: 0;
}
#copy-popup-content {
padding: 10px;
flex-grow: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
#copy-popup-content textarea {
width: 100%;
flex-grow: 1;
background: #343541;
color: #FFFFFF;
border: 1px solid #202123;
resize: none;
box-sizing: border-box;
padding: 10px;
margin-bottom: 10px;
overflow-y: auto;
font-family: Consolas, "Courier New", monospace;
font-size: 14px;
line-height: 1.5;
}
#copy-popup-content textarea:focus {
outline: none;
border: 1px solid #00a884;
}
#copy-popup-content .buttons-container {
display: flex;
justify-content: flex-start;
gap: 10px;
flex-shrink: 0;
}
#copy-popup-content button.action-button {
padding: 5px 10px;
background: #00a884;
color: #FFFFFF;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
#copy-popup-content button.action-button:hover {
background: #019d7f;
}
`;
const styleSheet = document.createElement("style");
styleSheet.type = "text/css";
styleSheet.innerText = styles;
document.head.appendChild(styleSheet);
function createPopup(text) {
const popup = document.createElement('div');
popup.id = 'copy-popup';
popup.style.width = '400px';
const header = document.createElement('div');
header.id = 'copy-popup-header';
header.innerText = 'Copied text';
const content = document.createElement('div');
content.id = 'copy-popup-content';
const textarea = document.createElement('textarea');
textarea.readOnly = true;
textarea.value = text;
textarea.style.flexGrow = '1';
const buttonsContainer = document.createElement('div');
buttonsContainer.className = 'buttons-container';
const copyButton = document.createElement('button');
copyButton.textContent = 'Copy';
copyButton.className = 'action-button';
copyButton.addEventListener('click', function() {
textarea.select();
document.execCommand('copy');
copyButton.textContent = 'Copied!';
setTimeout(() => {
copyButton.textContent = 'Copy';
}, 2000);
});
const closeButton = document.createElement('button');
closeButton.textContent = 'Close';
closeButton.className = 'action-button';
closeButton.style.marginLeft = 'auto';
closeButton.addEventListener('click', function() {
document.body.removeChild(popup);
});
buttonsContainer.appendChild(copyButton);
buttonsContainer.appendChild(closeButton);
content.appendChild(textarea);
content.appendChild(buttonsContainer);
popup.appendChild(header);
popup.appendChild(content);
document.body.appendChild(popup);
const popupRect = popup.getBoundingClientRect();
const popupWidth = popupRect.width;
const popupHeight = popupRect.height;
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
let left = (viewportWidth - popupWidth) / 2;
let top = (viewportHeight - popupHeight) / 2;
popup.style.left = `${left}px`;
popup.style.top = `${top}px`;
makePopupDraggable(popup, header);
}
function makePopupDraggable(popup, header) {
let isDragging = false;
let dragOffsetX = 0;
let dragOffsetY = 0;
header.addEventListener('mousedown', function(e) {
e.preventDefault();
isDragging = true;
const rect = popup.getBoundingClientRect();
dragOffsetX = e.clientX - rect.left;
dragOffsetY = e.clientY - rect.top;
document.body.style.userSelect = 'none';
});
document.addEventListener('mousemove', function(e) {
if (isDragging) {
let left = e.clientX - dragOffsetX;
let top = e.clientY - dragOffsetY;
const maxLeft = window.innerWidth - popup.offsetWidth;
const maxTop = window.innerHeight - popup.offsetHeight;
if (left < 0) left = 0;
if (top < 0) top = 0;
if (left > maxLeft) left = maxLeft;
if (top > maxTop) top = maxTop;
popup.style.left = `${left}px`;
popup.style.top = `${top}px`;
}
});
document.addEventListener('mouseup', function() {
isDragging = false;
document.body.style.userSelect = 'auto';
});
popup.addEventListener('mousedown', function(e) {
e.stopPropagation();
});
}
document.addEventListener('click', function(event) {
const button = event.target.closest(buttonSelector);
if (button && button.tagName.toLowerCase() === 'svg') {
navigator.clipboard.readText().then(text => {
createPopup(text);
}).catch(err => {
console.error('Error reading clipboard: ', err);
});
}
});
})();
How to install it:
-
Download the Tampermonkey extension (this extension allows you to run JavaScript in your browser).
-
Click “Create a new script” and paste the code.
4. Done! Now you have a new feature available.
A similar solution is on the platform’s roadmap and will be implemented in the future. However, I wanted to have this functionality right now.
Good luck!