← Commit history

v2.0.570 (insiders): Queued extension channel; Trusted-Types-safe annotate overlay; annotate on the extension lane; worker self-reload.

John Lauer ·9a57e96e98 ·1mo ago ·parent e29fdd3
2 files changed +21−9
src/extension/annotate-overlay.js+5−1
@@ -98,7 +98,11 @@ window.__pupStartAnnotate = function (initTool, initMode) {   function setCursor() {     if (S.tool === 'pen' || S.tool === 'arrow') {       cv.style.cursor = 'none';-      spr.innerHTML = S.tool === 'pen' ? penSvg() : arrowSvg();+      // No innerHTML: pages that enforce Trusted Types (Google Docs) refuse it. An <img> src is not a sink.+      while (spr.firstChild) spr.removeChild(spr.firstChild);+      const sprImg = document.createElement('img'); sprImg.width = 24; sprImg.height = 24; sprImg.draggable = false; sprImg.alt = '';+      sprImg.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(S.tool === 'pen' ? penSvg() : arrowSvg());+      spr.appendChild(sprImg);       sprHot = S.tool === 'pen' ? [5, 19] : [2, 2];       // shown on the next pointer move, so it never appears at a stale position     } else {
src/extension/worker.js+16−8
@@ -148,8 +148,7 @@ function pupExtWaitComplete(tabId, ms) { }  let pupExtDiag = { tries: 0, pkg: null, lastErr: '' };-async function pupExtPoll() {-  if (pupExtBusy) return;+async function pupExtPollOnce() {   pupExtDiag.tries++;   pupExtDiag.pkg = await packagedPort();   const found = await findPort();@@ -169,20 +168,20 @@ async function pupExtPoll() {   }   // Only the extension-driven browser serves this channel. A normal pup window loads the same extension   // and must NEVER answer another thread's ext commands.-  if (!_pkgLane) return;+  if (!_pkgLane) return false;   if (!found) {     // No pup reachable. Surface WHY on the action tooltip so a human (or a screenshot) can read it without     // needing the very channel that is broken.     try { chrome.action.setTitle({ title: `Adom Pup — CANNOT REACH BRIDGE (tries ${pupExtDiag.tries}, port.json ${pupExtDiag.pkg})` }); } catch (e) {}-    return;+    return false;   }   let cmd = null;   try {     const r = await fetch(`http://127.0.0.1:${found.port}/extcmd?lane=${encodeURIComponent(_pkgLane)}`, { signal: AbortSignal.timeout(2500) });     cmd = await r.json();-  } catch (e) { return; }-  if (!cmd || !cmd.id) return;-  pupExtBusy = true;+  } catch (e) { return false; }+  if (!cmd || !cmd.id) return false;+     let out = { id: cmd.id, ok: false, error: `unsupported action ${cmd.action}` };   try {     if (cmd.action === 'open') {@@ -399,7 +398,16 @@ async function pupExtPoll() {       method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(out),     });   } catch (e) {}-  pupExtBusy = false;+  return true;+}++// 2.0.570: the bridge queues commands; drain the queue on every poll (up to 12 per tick) instead of+// serving one command per 1.2 s, so a watcher polling every 500 ms and a verb do not starve each other.+async function pupExtPoll() {+  if (pupExtBusy) return;+  pupExtBusy = true;+  try { for (let k = 0; k < 12; k++) { if (!(await pupExtPollOnce())) break; } }+  finally { pupExtBusy = false; } }  // A tight poll keeps the MV3 worker alive while pup is driving; the alarm revives it if it ever