Skip to content

Commit b46abbc

Browse files
Merge pull request steam-bell-92#1727 from nishtha-agarwal-211/fix/console-copy-clear-1715
fix(playground): add clear console and copy output features (steam-bell-92#1715)
2 parents 68dc21b + 5e204b5 commit b46abbc

3 files changed

Lines changed: 125 additions & 5 deletions

File tree

web-app/css/styles.css

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,12 +1716,24 @@ main>.hero-section:has(.hero-code-snippets) {
17161716
align-items: center;
17171717
gap: 8px;
17181718
}
1719-
1720-
.editor-actions {
1719+
.editor-actions,
1720+
.console-actions {
17211721
display: flex;
17221722
gap: 6px;
17231723
}
17241724

1725+
.btn-panel-action.copy-success {
1726+
background: rgba(16, 185, 129, 0.12) !important;
1727+
border-color: rgba(16, 185, 129, 0.4) !important;
1728+
color: #10b981 !important;
1729+
}
1730+
1731+
.btn-panel-action.copy-error {
1732+
background: rgba(239, 68, 68, 0.12) !important;
1733+
border-color: rgba(239, 68, 68, 0.4) !important;
1734+
color: #ef4444 !important;
1735+
}
1736+
17251737
.draft-selector {
17261738
background: var(--bg-glass);
17271739
border: 1px solid var(--border);

web-app/index.html

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,16 @@ <h2 class="playground-title">🐍 Python Playground</h2>
377377
<div class="panel-header">
378378
<span><i aria-hidden="true" class="fas fa-terminal"></i> Output
379379
Console</span>
380-
<button class="btn-panel-action" id="clearConsole" title="Clear the console" type="button">
381-
<i aria-hidden="true" class="fas fa-times-circle"></i> Clear
382-
</button>
380+
<div class="console-actions">
381+
<button class="btn-panel-action" id="copyConsole" title="Copy console output to clipboard" type="button"
382+
aria-label="Copy console output to clipboard">
383+
<i aria-hidden="true" class="fas fa-copy"></i> Copy
384+
</button>
385+
<button class="btn-panel-action" id="clearConsole" title="Clear the console" type="button"
386+
aria-label="Clear console output">
387+
<i aria-hidden="true" class="fas fa-times-circle"></i> Clear
388+
</button>
389+
</div>
383390
</div>
384391
<pre aria-label="Console output" aria-live="polite" class="console-output" id="consoleOutput"></pre>
385392
</div>

web-app/js/playground.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
var statusDot = $id("statusDot");
130130
var statusText = $id("statusText");
131131
var clearConsoleBtn = $id("clearConsole");
132+
var copyConsoleBtn = $id("copyConsole");
132133
var clearEditorBtn = $id("clearEditor");
133134
var loadExampleBtn = $id("loadExample");
134135
var draftSelector = $id("draftSelector");
@@ -903,6 +904,106 @@
903904
});
904905
}
905906

907+
/* ──────────────────────────────────────────────────────────────
908+
Copy Console Button — Issue #1715
909+
Copy console output to clipboard with visual feedback
910+
────────────────────────────────────────────────────────────── */
911+
if (copyConsoleBtn) {
912+
copyConsoleBtn.addEventListener("click", function (event) {
913+
event.preventDefault();
914+
915+
var hasPlaceholder = consoleEl.querySelector(".pg-placeholder");
916+
var textToCopy = "";
917+
if (!hasPlaceholder) {
918+
textToCopy = consoleEl.innerText || consoleEl.textContent || "";
919+
}
920+
textToCopy = textToCopy.trim();
921+
922+
if (!textToCopy) {
923+
copyConsoleBtn.textContent = "Nothing to copy";
924+
copyConsoleBtn.classList.add("copy-error");
925+
copyConsoleBtn.setAttribute("aria-label", "Console is empty, nothing to copy");
926+
setTimeout(function () {
927+
copyConsoleBtn.innerHTML =
928+
'<i aria-hidden="true" class="fas fa-copy"></i> Copy';
929+
copyConsoleBtn.classList.remove("copy-error");
930+
copyConsoleBtn.setAttribute(
931+
"aria-label",
932+
"Copy console output to clipboard"
933+
);
934+
}, 1500);
935+
return;
936+
}
937+
938+
function fallbackCopy(text) {
939+
return new Promise(function (resolve, reject) {
940+
var textarea = document.createElement("textarea");
941+
textarea.value = text;
942+
textarea.style.position = "fixed";
943+
textarea.style.left = "-9999px";
944+
textarea.style.opacity = "0";
945+
textarea.setAttribute("aria-hidden", "true");
946+
textarea.setAttribute("tabindex", "-1");
947+
948+
document.body.appendChild(textarea);
949+
950+
try {
951+
textarea.select();
952+
var success = document.execCommand("copy");
953+
if (success) {
954+
resolve();
955+
} else {
956+
reject(new Error("execCommand copy failed"));
957+
}
958+
} catch (error) {
959+
reject(error);
960+
} finally {
961+
document.body.removeChild(textarea);
962+
}
963+
});
964+
}
965+
966+
var copyPromise =
967+
navigator.clipboard && navigator.clipboard.writeText
968+
? navigator.clipboard.writeText(textToCopy)
969+
: fallbackCopy(textToCopy);
970+
971+
copyPromise
972+
.then(function () {
973+
copyConsoleBtn.innerHTML =
974+
'<i aria-hidden="true" class="fas fa-check"></i> Copied!';
975+
copyConsoleBtn.classList.add("copy-success");
976+
copyConsoleBtn.setAttribute("aria-label", "Console output copied to clipboard");
977+
978+
setTimeout(function () {
979+
copyConsoleBtn.innerHTML =
980+
'<i aria-hidden="true" class="fas fa-copy"></i> Copy';
981+
copyConsoleBtn.classList.remove("copy-success");
982+
copyConsoleBtn.setAttribute(
983+
"aria-label",
984+
"Copy console output to clipboard"
985+
);
986+
}, 2000);
987+
})
988+
.catch(function (error) {
989+
console.error("Copy failed:", error);
990+
copyConsoleBtn.textContent = "Copy failed";
991+
copyConsoleBtn.classList.add("copy-error");
992+
copyConsoleBtn.setAttribute("aria-label", "Copy failed, try again");
993+
994+
setTimeout(function () {
995+
copyConsoleBtn.innerHTML =
996+
'<i aria-hidden="true" class="fas fa-copy"></i> Copy';
997+
copyConsoleBtn.classList.remove("copy-error");
998+
copyConsoleBtn.setAttribute(
999+
"aria-label",
1000+
"Copy console output to clipboard"
1001+
);
1002+
}, 2000);
1003+
});
1004+
});
1005+
}
1006+
9061007
// Keyboard shortcut for copy: Ctrl+Shift+C in editor
9071008
if (cmView) {
9081009
document.addEventListener("keydown", function (event) {

0 commit comments

Comments
 (0)