seemore 1.5.2 → 1.5.4

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "seemore",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "description": "Let AI write the Markdown. Let seemore show it better — zero config documentation framework.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,6 +15,7 @@ import { useSearchHighlight } from '../features/highlight.js';
15
15
  import { useHashScroll } from '../features/anchors.js';
16
16
  import { InlineEditor } from '../features/edit.js';
17
17
  import { SeemoreProvider } from './Provider.js';
18
+ import { useExternalLinkBridge } from './ExternalLinkBridge.js';
18
19
  import { Header } from './Header.js';
19
20
  import { Sidebar } from './Sidebar.js';
20
21
  import { Breadcrumb } from './Breadcrumb.js';
@@ -28,6 +29,7 @@ import { IntegratedToc, Toc, TocProvider } from './Toc.js';
28
29
  */
29
30
  export function DocsLayout({ children }: { children: React.ReactNode }) {
30
31
  const tree = usePageTree();
32
+ useExternalLinkBridge();
31
33
 
32
34
  return (
33
35
  <SeemoreProvider>
@@ -0,0 +1,43 @@
1
+ import { useEffect } from 'react';
2
+
3
+ /**
4
+ * Opens away-links in the reader's browser — from inside the VS Code extension's webview.
5
+ *
6
+ * Only matters embedded there: the page runs inside a nested, cross-origin iframe (see
7
+ * `panelHtml.ts`), and VS Code only routes `target="_blank"` to the system browser for links
8
+ * in the webview's *own* top document. A click inside the iframe has no honoured popup path
9
+ * at all — the frame instead drags the view off to a page that cannot render, and the reader
10
+ * is left with a blank webview. So while embedded, a click on any cross-origin link is
11
+ * intercepted and posted up over the same bridge the copy button uses, and the extension host
12
+ * opens it with `vscode.env.openExternal` (see `panel.ts`), the one side actually allowed to
13
+ * launch the browser. A plain browser tab already does this natively and is never embedded,
14
+ * so no listener is installed there.
15
+ */
16
+ export function useExternalLinkBridge(): void {
17
+ useEffect(() => {
18
+ if (window.parent === window) return;
19
+
20
+ function openExternally(event: MouseEvent): void {
21
+ if (event.defaultPrevented) return;
22
+ const target = event.target;
23
+ if (!(target instanceof Element)) return;
24
+ const anchor = target.closest('a');
25
+ if (anchor === null) return;
26
+ const url = new URL(anchor.href, window.location.href);
27
+ // Same-origin addresses navigate the iframe fine on their own; only away-links need
28
+ // the host (this also leaves hash links and router Links untouched).
29
+ if (url.origin === window.location.origin) return;
30
+ event.preventDefault();
31
+ window.parent.postMessage({ type: 'seemore:open-external', url: url.toString() }, '*');
32
+ }
33
+
34
+ // Capture phase, so the interception happens before anything downstream can act on the
35
+ // click; `auxclick` covers middle-click, which would hit the same dead end.
36
+ document.addEventListener('click', openExternally, true);
37
+ document.addEventListener('auxclick', openExternally, true);
38
+ return () => {
39
+ document.removeEventListener('click', openExternally, true);
40
+ document.removeEventListener('auxclick', openExternally, true);
41
+ };
42
+ }, []);
43
+ }