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
|
@@ -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
|
+
}
|