shadok-ai 0.12.6 → 0.12.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/public/index.html +40 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shadok-ai",
3
- "version": "0.12.6",
3
+ "version": "0.12.7",
4
4
  "main": "dist/session.js",
5
5
  "scripts": {
6
6
  "test": "node --import tsx --test test/*.ts context/*/test/*.test.mjs",
package/public/index.html CHANGED
@@ -897,6 +897,22 @@
897
897
  overflow-x: auto;
898
898
  }
899
899
  .bubble.md pre code { background: none; padding: 0; }
900
+ /* Copy on a fenced code block. The button sits on a WRAPPER around the <pre>,
901
+ not inside it: the <pre> scrolls sideways, and a button within would scroll
902
+ away. Always visible (a phone has no hover), small, top-right — the <pre>'s
903
+ own top padding keeps the first line clear of it. */
904
+ .bubble.md .md-code { position: relative; }
905
+ .bubble.md .md-code-copy {
906
+ position: absolute; top: 6px; right: 6px;
907
+ padding: 2px 7px; font-family: var(--mono); font-size: 10px; line-height: 1.4;
908
+ cursor: pointer; background: var(--bg-inset); border: 1px solid var(--line);
909
+ border-radius: 6px; color: var(--text-dim); opacity: 0.75;
910
+ transition: color 0.12s, border-color 0.12s, opacity 0.12s;
911
+ }
912
+ .bubble.md .md-code-copy:hover, .bubble.md .md-code-copy:focus-visible {
913
+ opacity: 1; color: var(--amber); border-color: var(--amber);
914
+ }
915
+ .bubble.md .md-code-copy.done { opacity: 1; color: var(--ok, #7ac77a); border-color: currentColor; }
900
916
  /* The horizontal scroll for a wide table lives on this wrapper (added in JS
901
917
  after sanitising), NOT on the <table>: `display:block` on a table breaks its
902
918
  own layout — thead and tbody stop sharing column widths, so the header row
@@ -4144,6 +4160,30 @@
4144
4160
  t.replaceWith(wrap);
4145
4161
  wrap.appendChild(t);
4146
4162
  }
4163
+ // A copy button on every fenced code block — the thing you most often want
4164
+ // to lift out of an answer. It goes on a wrapper AROUND the <pre> (the
4165
+ // <pre> scrolls; a button inside would scroll off), and copies the code's
4166
+ // own text, not the whole message.
4167
+ for (const pre of bubble.querySelectorAll("pre")) {
4168
+ const code = pre.querySelector("code") || pre;
4169
+ const wrap = document.createElement("div");
4170
+ wrap.className = "md-code";
4171
+ pre.replaceWith(wrap);
4172
+ wrap.appendChild(pre);
4173
+ const btn = document.createElement("button");
4174
+ btn.type = "button";
4175
+ btn.className = "md-code-copy";
4176
+ btn.textContent = "⧉ copy";
4177
+ btn.title = "Copy this code";
4178
+ btn.addEventListener("click", async (e) => {
4179
+ e.stopPropagation();
4180
+ const ok = await copyText(code.textContent.replace(/\n$/, ""));
4181
+ btn.textContent = ok ? "✓ copied" : "⚠ failed";
4182
+ btn.classList.toggle("done", ok);
4183
+ setTimeout(() => { btn.textContent = "⧉ copy"; btn.classList.remove("done"); }, 1500);
4184
+ });
4185
+ wrap.appendChild(btn);
4186
+ }
4147
4187
  } else {
4148
4188
  bubble.textContent = text;
4149
4189
  }