react-cheminfo 0.52.0 → 0.53.0
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/README.md +65 -31
- package/lib/i18n/core/chromeCatalog.d.ts +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
- package/lib/language/ui/siteLanguageContext.d.ts.map +1 -1
- package/lib/language/ui/siteLanguageContext.js +2 -1
- package/lib/language/ui/siteLanguageContext.js.map +1 -1
- package/lib/locales/de.json +5 -0
- package/lib/locales/en.json +5 -0
- package/lib/locales/es.json +5 -0
- package/lib/locales/fr.json +5 -0
- package/lib/locales/it.json +5 -0
- package/lib/router/core/history.d.ts +4 -3
- package/lib/router/core/history.d.ts.map +1 -1
- package/lib/router/core/history.js +9 -13
- package/lib/router/core/history.js.map +1 -1
- package/lib/router/core/index.d.ts +2 -0
- package/lib/router/core/index.d.ts.map +1 -1
- package/lib/router/core/index.js +1 -0
- package/lib/router/core/index.js.map +1 -1
- package/lib/router/core/pageAddress.d.ts +61 -0
- package/lib/router/core/pageAddress.d.ts.map +1 -0
- package/lib/router/core/pageAddress.js +69 -0
- package/lib/router/core/pageAddress.js.map +1 -0
- package/lib/share/core/index.d.ts +4 -0
- package/lib/share/core/index.d.ts.map +1 -1
- package/lib/share/core/index.js +2 -0
- package/lib/share/core/index.js.map +1 -1
- package/lib/share/core/preferences.d.ts +2 -2
- package/lib/share/core/preferences.d.ts.map +1 -1
- package/lib/share/core/preferences.js +8 -3
- package/lib/share/core/preferences.js.map +1 -1
- package/lib/share/core/seal.d.ts +42 -0
- package/lib/share/core/seal.d.ts.map +1 -0
- package/lib/share/core/seal.js +185 -0
- package/lib/share/core/seal.js.map +1 -0
- package/lib/share/core/sealedAddress.d.ts +31 -0
- package/lib/share/core/sealedAddress.d.ts.map +1 -0
- package/lib/share/core/sealedAddress.js +38 -0
- package/lib/share/core/sealedAddress.js.map +1 -0
- package/lib/share/ui/SealedLinkRefused.d.ts +17 -0
- package/lib/share/ui/SealedLinkRefused.d.ts.map +1 -0
- package/lib/share/ui/SealedLinkRefused.js +23 -0
- package/lib/share/ui/SealedLinkRefused.js.map +1 -0
- package/lib/share/ui/ShareConfigOptions.d.ts +12 -1
- package/lib/share/ui/ShareConfigOptions.d.ts.map +1 -1
- package/lib/share/ui/ShareConfigOptions.js +4 -3
- package/lib/share/ui/ShareConfigOptions.js.map +1 -1
- package/lib/share/ui/ShareDialogContent.d.ts.map +1 -1
- package/lib/share/ui/ShareDialogContent.js +20 -6
- package/lib/share/ui/ShareDialogContent.js.map +1 -1
- package/lib/share/ui/ShareLinkBar.d.ts +5 -0
- package/lib/share/ui/ShareLinkBar.d.ts.map +1 -1
- package/lib/share/ui/ShareLinkBar.js +4 -4
- package/lib/share/ui/ShareLinkBar.js.map +1 -1
- package/lib/share/ui/index.d.ts +2 -0
- package/lib/share/ui/index.d.ts.map +1 -1
- package/lib/share/ui/index.js +1 -0
- package/lib/share/ui/index.js.map +1 -1
- package/lib/share/ui/useSealedUrl.d.ts +17 -0
- package/lib/share/ui/useSealedUrl.d.ts.map +1 -0
- package/lib/share/ui/useSealedUrl.js +31 -0
- package/lib/share/ui/useSealedUrl.js.map +1 -0
- package/package.json +1 -1
- package/src/language/ui/siteLanguageContext.ts +2 -1
- package/src/locales/de.json +5 -0
- package/src/locales/en.json +5 -0
- package/src/locales/es.json +5 -0
- package/src/locales/fr.json +5 -0
- package/src/locales/it.json +5 -0
- package/src/router/core/history.ts +9 -15
- package/src/router/core/index.ts +8 -0
- package/src/router/core/pageAddress.ts +110 -0
- package/src/share/core/index.ts +10 -0
- package/src/share/core/preferences.ts +10 -10
- package/src/share/core/seal.ts +233 -0
- package/src/share/core/sealedAddress.ts +48 -0
- package/src/share/ui/SealedLinkRefused.tsx +43 -0
- package/src/share/ui/ShareConfigOptions.tsx +23 -1
- package/src/share/ui/ShareDialogContent.tsx +37 -6
- package/src/share/ui/ShareLinkBar.tsx +9 -1
- package/src/share/ui/index.ts +2 -0
- package/src/share/ui/useSealedUrl.ts +40 -0
|
@@ -12,13 +12,24 @@ export interface ShareConfigOptionsProps {
|
|
|
12
12
|
descriptions: SharePartDescriptions;
|
|
13
13
|
/** Called when the layout is switched. */
|
|
14
14
|
onEmbedChange: (embed: boolean) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the link is handed out sealed.
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
sealed?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Called when sealing is switched. Without it the switch is not offered.
|
|
22
|
+
* @default undefined
|
|
23
|
+
*/
|
|
24
|
+
onSealedChange?: (sealed: boolean) => void;
|
|
15
25
|
/** Called with the part and whether the link should switch it off. */
|
|
16
26
|
onPartChange: (part: string, hidden: boolean) => void;
|
|
17
27
|
/** Called with the part the pointer is on, or `null` when it leaves. */
|
|
18
28
|
onPartPointed: (part: string | null) => void;
|
|
19
29
|
}
|
|
20
30
|
/**
|
|
21
|
-
* The switches of the share dialog: the layout
|
|
31
|
+
* The switches of the share dialog: the layout — embedded, and sealed where the
|
|
32
|
+
* site opens sealed links — then one per part of the page.
|
|
22
33
|
* @param props - The draft's layout and parts, and how to change them.
|
|
23
34
|
* @returns The two sections.
|
|
24
35
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareConfigOptions.d.ts","sourceRoot":"","sources":["../../../src/share/ui/ShareConfigOptions.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,OAAO,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAKhE,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,KAAK,EAAE,OAAO,CAAC;IACf,+EAA+E;IAC/E,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,wCAAwC;IACxC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,sDAAsD;IACtD,YAAY,EAAE,qBAAqB,CAAC;IACpC,0CAA0C;IAC1C,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,sEAAsE;IACtE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD,wEAAwE;IACxE,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC9C;AAED
|
|
1
|
+
{"version":3,"file":"ShareConfigOptions.d.ts","sourceRoot":"","sources":["../../../src/share/ui/ShareConfigOptions.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,OAAO,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAKhE,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,KAAK,EAAE,OAAO,CAAC;IACf,+EAA+E;IAC/E,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,wCAAwC;IACxC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,sDAAsD;IACtD,YAAY,EAAE,qBAAqB,CAAC;IACpC,0CAA0C;IAC1C,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,sEAAsE;IACtE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD,wEAAwE;IACxE,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC9C;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,uBAAuB,GAC7B,YAAY,CAkDd"}
|
|
@@ -5,13 +5,14 @@ import { SharePartOptions } from "./SharePartOptions.js";
|
|
|
5
5
|
import { SharePartRow } from "./SharePartRow.js";
|
|
6
6
|
const SECTION_STYLE = { marginBottom: 14 };
|
|
7
7
|
/**
|
|
8
|
-
* The switches of the share dialog: the layout
|
|
8
|
+
* The switches of the share dialog: the layout — embedded, and sealed where the
|
|
9
|
+
* site opens sealed links — then one per part of the page.
|
|
9
10
|
* @param props - The draft's layout and parts, and how to change them.
|
|
10
11
|
* @returns The two sections.
|
|
11
12
|
*/
|
|
12
13
|
export function ShareConfigOptions(props) {
|
|
13
|
-
const { embed, parts, hidden, descriptions, onEmbedChange, onPartChange, onPartPointed, } = props;
|
|
14
|
+
const { embed, parts, hidden, descriptions, onEmbedChange, sealed = false, onSealedChange, onPartChange, onPartPointed, } = props;
|
|
14
15
|
const t = useChromeT();
|
|
15
|
-
return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "share-section", style: SECTION_STYLE, children: [_jsx(H6, { children: t('share.layout') }), _jsx(SharePartRow, { label: t('share.embed'), description: t('share.embedHint'), on: embed, descriptions: descriptions, onChange: onEmbedChange })] }), parts.length > 0 ? (_jsxs("section", { className: "share-section", style: SECTION_STYLE, children: [_jsx(H6, { children: t('share.showOnPage') }), _jsx(SharePartOptions, { parts: parts, hidden: hidden, descriptions: descriptions, onChange: onPartChange, onPointed: onPartPointed })] })) : null] }));
|
|
16
|
+
return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "share-section", style: SECTION_STYLE, children: [_jsx(H6, { children: t('share.layout') }), _jsx(SharePartRow, { label: t('share.embed'), description: t('share.embedHint'), on: embed, descriptions: descriptions, onChange: onEmbedChange }), onSealedChange === undefined ? null : (_jsx(SharePartRow, { label: t('share.protect'), description: t('share.protectHint'), on: sealed, descriptions: descriptions, onChange: onSealedChange }))] }), parts.length > 0 ? (_jsxs("section", { className: "share-section", style: SECTION_STYLE, children: [_jsx(H6, { children: t('share.showOnPage') }), _jsx(SharePartOptions, { parts: parts, hidden: hidden, descriptions: descriptions, onChange: onPartChange, onPointed: onPartPointed })] })) : null] }));
|
|
16
17
|
}
|
|
17
18
|
//# sourceMappingURL=ShareConfigOptions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareConfigOptions.js","sourceRoot":"","sources":["../../../src/share/ui/ShareConfigOptions.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAGvC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAwB,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAC;AAElD,MAAM,aAAa,GAAkB,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"ShareConfigOptions.js","sourceRoot":"","sources":["../../../src/share/ui/ShareConfigOptions.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAGvC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAwB,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAC;AAElD,MAAM,aAAa,GAAkB,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;AA6B1D;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAA8B;IAE9B,MAAM,EACJ,KAAK,EACL,KAAK,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,GAAG,KAAK,EACd,cAAc,EACd,YAAY,EACZ,aAAa,GACd,GAAG,KAAK,CAAC;IACV,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IAEvB,OAAO,CACL,8BACE,mBAAS,SAAS,EAAC,eAAe,EAAC,KAAK,EAAE,aAAa,aACrD,KAAC,EAAE,cAAE,CAAC,CAAC,cAAc,CAAC,GAAM,EAC5B,KAAC,YAAY,IACX,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EACvB,WAAW,EAAE,CAAC,CAAC,iBAAiB,CAAC,EACjC,EAAE,EAAE,KAAK,EACT,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,aAAa,GACvB,EACD,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACrC,KAAC,YAAY,IACX,KAAK,EAAE,CAAC,CAAC,eAAe,CAAC,EACzB,WAAW,EAAE,CAAC,CAAC,mBAAmB,CAAC,EACnC,EAAE,EAAE,MAAM,EACV,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,cAAc,GACxB,CACH,IACO,EAET,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAClB,mBAAS,SAAS,EAAC,eAAe,EAAC,KAAK,EAAE,aAAa,aACrD,KAAC,EAAE,cAAE,CAAC,CAAC,kBAAkB,CAAC,GAAM,EAChC,KAAC,gBAAgB,IACf,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAE,aAAa,GACxB,IACM,CACX,CAAC,CAAC,CAAC,IAAI,IACP,CACJ,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareDialogContent.d.ts","sourceRoot":"","sources":["../../../src/share/ui/ShareDialogContent.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,OAAO,CAAC;AAIzD,OAAO,KAAK,EAGV,gBAAgB,EAIjB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ShareDialogContent.d.ts","sourceRoot":"","sources":["../../../src/share/ui/ShareDialogContent.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,OAAO,CAAC;AAIzD,OAAO,KAAK,EAGV,gBAAgB,EAIjB,MAAM,kBAAkB,CAAC;AAc1B,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,mBAAmB,CAAC;AAetE,gFAAgF;AAChF,MAAM,MAAM,uBAAuB,CACjC,MAAM,SAAS,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IACrD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC,CAAC;AAE3D;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,SAAS,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACvD,KAAK,EAAE,uBAAuB,CAAC,MAAM,CAAC,GAAG,YAAY,CAoJtD"}
|
|
@@ -2,13 +2,14 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { DialogFooter } from '@blueprintjs/core';
|
|
3
3
|
import { useRef, useState } from 'react';
|
|
4
4
|
import { useContainerSize } from "../../hooks/ui/useContainerSize.js";
|
|
5
|
-
import { applySharePreset, buildEmbedCode, buildShareUrl, findSharePreset, isShareConfigured, parseShareConfig, suggestedShareConfig, visibleShareParts, } from "../core/index.js";
|
|
5
|
+
import { applySharePreset, buildEmbedCode, buildShareUrl, canOpenSealedAddresses, findSharePreset, isShareConfigured, parseShareConfig, suggestedShareConfig, visibleShareParts, } from "../core/index.js";
|
|
6
6
|
import { ShareConfigOptions } from "./ShareConfigOptions.js";
|
|
7
7
|
import { ShareLinkBar } from "./ShareLinkBar.js";
|
|
8
8
|
import { SharePanes } from "./SharePanes.js";
|
|
9
9
|
import { SharePresetTabs } from "./SharePresetTabs.js";
|
|
10
10
|
import { SharePreview } from "./SharePreview.js";
|
|
11
11
|
import { withPart } from "./draft.js";
|
|
12
|
+
import { useSealedUrl } from "./useSealedUrl.js";
|
|
12
13
|
const NO_PRESETS = [];
|
|
13
14
|
/** Width below which the two panes stop fitting side by side and become tabs. */
|
|
14
15
|
const TWO_PANE_WIDTH = 720;
|
|
@@ -26,6 +27,7 @@ export function ShareDialogContent(props) {
|
|
|
26
27
|
const base = baseUrl ?? address?.href ?? '';
|
|
27
28
|
const query = search ?? address?.search ?? '';
|
|
28
29
|
const [config, setConfig] = useState(() => initialDraft(query, vocabulary, findPreset(presets, defaultPreset ?? null)));
|
|
30
|
+
const [sealed, setSealed] = useState(false);
|
|
29
31
|
const [pointed, setPointed] = useState(null);
|
|
30
32
|
const [presetKey, setPresetKey] = useState(() => findSharePreset(config, presets, vocabulary)?.key ?? null);
|
|
31
33
|
const body = useRef(null);
|
|
@@ -36,6 +38,8 @@ export function ShareDialogContent(props) {
|
|
|
36
38
|
const narrow = width > 0 && width < TWO_PANE_WIDTH;
|
|
37
39
|
function setEmbed(embed) {
|
|
38
40
|
setConfig((previous) => ({ ...previous, embed }));
|
|
41
|
+
// A sealed page is always embedded, so leaving the frame drops the seal.
|
|
42
|
+
setSealed((previous) => previous && embed);
|
|
39
43
|
}
|
|
40
44
|
function setPartHidden(part, hidden) {
|
|
41
45
|
setConfig((previous) => ({
|
|
@@ -62,17 +66,27 @@ export function ShareDialogContent(props) {
|
|
|
62
66
|
setPartHidden,
|
|
63
67
|
setParam,
|
|
64
68
|
};
|
|
65
|
-
const
|
|
69
|
+
const shown = embeddedWhenSealed(config, sealed);
|
|
70
|
+
const url = buildShareUrl({ base, search: query, config: shown, vocabulary });
|
|
71
|
+
const { link, ready } = useSealedUrl(url, sealed);
|
|
66
72
|
const frame = buildEmbedCode({
|
|
67
|
-
url,
|
|
73
|
+
url: link,
|
|
68
74
|
title: frameTitle ?? title,
|
|
69
75
|
height: frameHeight,
|
|
70
76
|
});
|
|
71
|
-
const options = (_jsx(ShareConfigOptions, { embed:
|
|
77
|
+
const options = (_jsx(ShareConfigOptions, { embed: shown.embed, parts: visibleShareParts(vocabulary.parts, shown.embed), hidden: config.hidden, descriptions: partDescriptions, onEmbedChange: setEmbed, sealed: sealed, onSealedChange: offeredWhenOpened(setSealed), onPartChange: setPartHidden, onPartPointed: setPointed }));
|
|
72
78
|
const openPreset = findPreset(presets, presetKey);
|
|
73
79
|
const optionsPane = (_jsxs("div", { className: "share-dialog__options", children: [openPreset === undefined ? (options) : (_jsx("p", { className: "share-dialog__preset", children: openPreset.description })), children === undefined ? null : (_jsx("section", { className: "share-section", style: SECTION_STYLE, children: typeof children === 'function' ? children(draft) : children }))] }));
|
|
74
|
-
const previewPane = preview ? (_jsx(SharePreview, { url:
|
|
75
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "share-dialog__body", ref: body, children: [presets.length === 0 ? null : (_jsx("div", { className: "share-dialog__top", children: _jsx(SharePresetTabs, { presets: presets, selected: presetKey, onSelect: selectPreset }) })), _jsx(SharePanes, { options: optionsPane, preview: previewPane, narrow: narrow })] }), _jsx(DialogFooter, { actions: _jsx(ShareLinkBar, { url:
|
|
80
|
+
const previewPane = preview ? (_jsx(SharePreview, { url: link, title: frameTitle ?? title, highlight: highlightOf(vocabulary.parts, pointed) })) : null;
|
|
81
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "share-dialog__body", ref: body, children: [presets.length === 0 ? null : (_jsx("div", { className: "share-dialog__top", children: _jsx(SharePresetTabs, { presets: presets, selected: presetKey, onSelect: selectPreset }) })), _jsx(SharePanes, { options: optionsPane, preview: previewPane, narrow: narrow })] }), _jsx(DialogFooter, { actions: _jsx(ShareLinkBar, { url: link, frame: frame, disabled: !ready, onCopied: onClose }) })] }));
|
|
82
|
+
}
|
|
83
|
+
// A sealed page is always embedded, whatever a preset said.
|
|
84
|
+
function embeddedWhenSealed(config, sealed) {
|
|
85
|
+
return sealed ? { ...config, embed: true } : config;
|
|
86
|
+
}
|
|
87
|
+
// A site that never opens a sealed address must not hand one out.
|
|
88
|
+
function offeredWhenOpened(setSealed) {
|
|
89
|
+
return canOpenSealedAddresses() ? setSealed : undefined;
|
|
76
90
|
}
|
|
77
91
|
function initialDraft(search, vocabulary, preset) {
|
|
78
92
|
const current = parseShareConfig(search, vocabulary);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareDialogContent.js","sourceRoot":"","sources":["../../../src/share/ui/ShareDialogContent.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAStE,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAA0B,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"ShareDialogContent.js","sourceRoot":"","sources":["../../../src/share/ui/ShareDialogContent.tsx"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,11 @@ export interface ShareLinkBarProps {
|
|
|
9
9
|
* @default undefined
|
|
10
10
|
*/
|
|
11
11
|
onCopied?: () => void;
|
|
12
|
+
/**
|
|
13
|
+
* Whether the link is not ready to hand out yet, as while it is being sealed.
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
disabled?: boolean;
|
|
12
17
|
}
|
|
13
18
|
/**
|
|
14
19
|
* The three things one does with a share link, in the dialog's footer and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareLinkBar.d.ts","sourceRoot":"","sources":["../../../src/share/ui/ShareLinkBar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAM1C,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"ShareLinkBar.d.ts","sourceRoot":"","sources":["../../../src/share/ui/ShareLinkBar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAM1C,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAoDnE"}
|
|
@@ -17,17 +17,17 @@ import { useChromeT } from "../../i18n/ui/useT.js";
|
|
|
17
17
|
* @returns The bar.
|
|
18
18
|
*/
|
|
19
19
|
export function ShareLinkBar(props) {
|
|
20
|
-
const { url, frame, onCopied } = props;
|
|
20
|
+
const { url, frame, onCopied, disabled = false } = props;
|
|
21
21
|
const t = useChromeT();
|
|
22
22
|
return (_jsxs("div", { className: "share-linkbar", children: [_jsx(HelpTooltip, { content: {
|
|
23
23
|
title: t('share.copyLinkHelpTitle'),
|
|
24
24
|
body: t('share.copyLinkHelp'),
|
|
25
|
-
}, children: _jsx(CopyButton, { content: url, label: t('share.copyLink'), title: "", onCopied: onCopied }) }), _jsx(HelpTooltip, { content: {
|
|
25
|
+
}, children: _jsx(CopyButton, { content: url, label: t('share.copyLink'), title: "", disabled: disabled, onCopied: onCopied }) }), _jsx(HelpTooltip, { content: {
|
|
26
26
|
title: t('share.openInNewTabHelpTitle'),
|
|
27
27
|
body: t('share.openInNewTabHelp'),
|
|
28
|
-
}, children: _jsx(AnchorButton, { icon: "share", text: t('share.openInNewTab'), href: url, target: "_blank", rel: "noopener noreferrer" }) }), _jsx(HelpTooltip, { content: {
|
|
28
|
+
}, children: _jsx(AnchorButton, { icon: "share", text: t('share.openInNewTab'), href: url, disabled: disabled, target: "_blank", rel: "noopener noreferrer" }) }), _jsx(HelpTooltip, { content: {
|
|
29
29
|
title: t('share.copyIframeHelpTitle'),
|
|
30
30
|
body: t('share.copyIframeHelp'),
|
|
31
|
-
}, children: _jsx(CopyButton, { content: frame, icon: "code", label: t('share.copyIframe'), title: "", onCopied: onCopied }) })] }));
|
|
31
|
+
}, children: _jsx(CopyButton, { content: frame, icon: "code", label: t('share.copyIframe'), title: "", disabled: disabled, onCopied: onCopied }) })] }));
|
|
32
32
|
}
|
|
33
33
|
//# sourceMappingURL=ShareLinkBar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareLinkBar.js","sourceRoot":"","sources":["../../../src/share/ui/ShareLinkBar.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"ShareLinkBar.js","sourceRoot":"","sources":["../../../src/share/ui/ShareLinkBar.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAmBnD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC;IACzD,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IAEvB,OAAO,CACL,eAAK,SAAS,EAAC,eAAe,aAC5B,KAAC,WAAW,IACV,OAAO,EAAE;oBACP,KAAK,EAAE,CAAC,CAAC,yBAAyB,CAAC;oBACnC,IAAI,EAAE,CAAC,CAAC,oBAAoB,CAAC;iBAC9B,YAED,KAAC,UAAU,IACT,OAAO,EAAE,GAAG,EACZ,KAAK,EAAE,CAAC,CAAC,gBAAgB,CAAC,EAC1B,KAAK,EAAC,EAAE,EACR,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,GAClB,GACU,EACd,KAAC,WAAW,IACV,OAAO,EAAE;oBACP,KAAK,EAAE,CAAC,CAAC,6BAA6B,CAAC;oBACvC,IAAI,EAAE,CAAC,CAAC,wBAAwB,CAAC;iBAClC,YAED,KAAC,YAAY,IACX,IAAI,EAAC,OAAO,EACZ,IAAI,EAAE,CAAC,CAAC,oBAAoB,CAAC,EAC7B,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAC,QAAQ,EACf,GAAG,EAAC,qBAAqB,GACzB,GACU,EACd,KAAC,WAAW,IACV,OAAO,EAAE;oBACP,KAAK,EAAE,CAAC,CAAC,2BAA2B,CAAC;oBACrC,IAAI,EAAE,CAAC,CAAC,sBAAsB,CAAC;iBAChC,YAED,KAAC,UAAU,IACT,OAAO,EAAE,KAAK,EACd,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,CAAC,CAAC,kBAAkB,CAAC,EAC5B,KAAK,EAAC,EAAE,EACR,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,GAClB,GACU,IACV,CACP,CAAC;AACJ,CAAC"}
|
package/lib/share/ui/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export { HiddenPartsProvider } from './HiddenPartsProvider.tsx';
|
|
|
3
3
|
export { useIsHidden } from './hiddenParts.ts';
|
|
4
4
|
export type { PagePartProps } from './PagePart.tsx';
|
|
5
5
|
export { PagePart } from './PagePart.tsx';
|
|
6
|
+
export type { SealedLinkRefusedProps } from './SealedLinkRefused.tsx';
|
|
7
|
+
export { SealedLinkRefused } from './SealedLinkRefused.tsx';
|
|
6
8
|
export type { ShareButtonProps, ShareButtonVariant } from './ShareButton.tsx';
|
|
7
9
|
export { ShareButton } from './ShareButton.tsx';
|
|
8
10
|
export type { ShareDialogProps } from './ShareDialog.tsx';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/share/ui/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/share/ui/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,YAAY,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
package/lib/share/ui/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { HiddenPartsProvider } from "./HiddenPartsProvider.js";
|
|
2
2
|
export { useIsHidden } from "./hiddenParts.js";
|
|
3
3
|
export { PagePart } from "./PagePart.js";
|
|
4
|
+
export { SealedLinkRefused } from "./SealedLinkRefused.js";
|
|
4
5
|
export { ShareButton } from "./ShareButton.js";
|
|
5
6
|
export { ShareDialog } from "./ShareDialog.js";
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/share/ui/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA2B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAgB,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAmB,CAAC;AAGhD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/share/ui/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA2B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAgB,CAAC;AAE1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAyB,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAmB,CAAC;AAGhD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAmB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** The link the dialog hands out, and whether it may be handed out yet. */
|
|
2
|
+
export interface SealedUrl {
|
|
3
|
+
/** The link: sealed when asked and ready, else the share link itself. */
|
|
4
|
+
link: string;
|
|
5
|
+
/** False while the link is being sealed, when only the plain one exists. */
|
|
6
|
+
ready: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The link the dialog hands out: the share link itself, or its sealed form.
|
|
10
|
+
* Sealing is asynchronous, so a sealed link is not ready at once, and a link
|
|
11
|
+
* sealed for an older draft is never answered for the current one.
|
|
12
|
+
* @param url - The share link.
|
|
13
|
+
* @param sealed - Whether to hand out its sealed form.
|
|
14
|
+
* @returns The link, and whether it is ready.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useSealedUrl(url: string, sealed: boolean): SealedUrl;
|
|
17
|
+
//# sourceMappingURL=useSealedUrl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSealedUrl.d.ts","sourceRoot":"","sources":["../../../src/share/ui/useSealedUrl.ts"],"names":[],"mappings":"AAIA,2EAA2E;AAC3E,MAAM,WAAW,SAAS;IACxB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,CAmBpE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { sealShareUrl } from "../core/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* The link the dialog hands out: the share link itself, or its sealed form.
|
|
5
|
+
* Sealing is asynchronous, so a sealed link is not ready at once, and a link
|
|
6
|
+
* sealed for an older draft is never answered for the current one.
|
|
7
|
+
* @param url - The share link.
|
|
8
|
+
* @param sealed - Whether to hand out its sealed form.
|
|
9
|
+
* @returns The link, and whether it is ready.
|
|
10
|
+
*/
|
|
11
|
+
export function useSealedUrl(url, sealed) {
|
|
12
|
+
const [result, setResult] = useState(null);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (!sealed)
|
|
15
|
+
return;
|
|
16
|
+
let current = true;
|
|
17
|
+
void sealShareUrl(url).then((to) => {
|
|
18
|
+
if (current)
|
|
19
|
+
setResult({ from: url, to });
|
|
20
|
+
});
|
|
21
|
+
return () => {
|
|
22
|
+
current = false;
|
|
23
|
+
};
|
|
24
|
+
}, [url, sealed]);
|
|
25
|
+
if (!sealed)
|
|
26
|
+
return { link: url, ready: true };
|
|
27
|
+
if (result?.from === url)
|
|
28
|
+
return { link: result.to, ready: true };
|
|
29
|
+
return { link: url, ready: false };
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=useSealedUrl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSealedUrl.js","sourceRoot":"","sources":["../../../src/share/ui/useSealedUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAUhD;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,MAAe;IACvD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAClC,IAAI,CACL,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,KAAK,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE;YACjC,IAAI,OAAO;gBAAE,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAElB,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC/C,IAAI,MAAM,EAAE,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAClE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACrC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-cheminfo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React components, hooks and framework-free helpers shared by the cheminfo sites: site chrome, citations, sharing, routing, pedagogy, charts, and the structure, orbital and 3D molecule viewers",
|
|
6
6
|
"author": "Luc Patiny",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createContext, use } from 'react';
|
|
2
2
|
|
|
3
|
+
import { pageLocation } from '../../router/core/pageAddress.ts';
|
|
3
4
|
import { readLanguageParam } from '../core/languageParam.ts';
|
|
4
5
|
|
|
5
6
|
/** What a site declares the page is being read in. */
|
|
@@ -16,5 +17,5 @@ export const SiteLanguageContext = createContext<string | undefined>(undefined);
|
|
|
16
17
|
export function useSiteLanguage(): string | undefined {
|
|
17
18
|
const declared = use(SiteLanguageContext);
|
|
18
19
|
if (declared !== undefined) return declared;
|
|
19
|
-
return readLanguageParam(
|
|
20
|
+
return readLanguageParam(pageLocation()?.search ?? '');
|
|
20
21
|
}
|
package/src/locales/de.json
CHANGED
|
@@ -54,6 +54,8 @@
|
|
|
54
54
|
"share.layout": "Darstellung",
|
|
55
55
|
"share.embed": "In eine andere Seite einbetten",
|
|
56
56
|
"share.embedHint": "Lässt Kopfzeile und Navigation der Website weg, damit die Seite in einer Seite von Ihnen sitzt.",
|
|
57
|
+
"share.protect": "Diesen Link schützen",
|
|
58
|
+
"share.protectHint": "Die Klasse kann weder lesen noch ändern, was der Link einstellt, und die Adresse der Seite bleibt fest. Die Seite wird eingebettet.",
|
|
57
59
|
"share.on": "Ein",
|
|
58
60
|
"share.off": "Aus",
|
|
59
61
|
"share.showOnPage": "Auf der Seite zeigen",
|
|
@@ -76,6 +78,9 @@
|
|
|
76
78
|
"share.copyIframe": "Iframe kopieren",
|
|
77
79
|
"share.copyIframeHelpTitle": "Die Seite in Ihre einbauen",
|
|
78
80
|
"share.copyIframeHelp": "Ein HTML-Schnipsel, das dort eingefügt wird, wo das HTML Ihrer Seite bearbeitet wird: das Werkzeug läuft dann darin.",
|
|
81
|
+
"seal.refusedTitle": "Dieser Link lässt sich nicht öffnen",
|
|
82
|
+
"seal.refusedBody": "Er wurde nach dem Erstellen verändert oder ist unvollständig, daher wurde nichts geöffnet. Bitten Sie erneut um den Link.",
|
|
83
|
+
"seal.openWithout": "Das Werkzeug ohne den Link öffnen",
|
|
79
84
|
"cite.button": "Zitieren",
|
|
80
85
|
"cite.copyReferenceAs": "Literaturangabe kopieren als",
|
|
81
86
|
"cite.pleaseCiteBoth": "Bitte zitieren Sie beide Arbeiten",
|
package/src/locales/en.json
CHANGED
|
@@ -54,6 +54,8 @@
|
|
|
54
54
|
"share.layout": "Layout",
|
|
55
55
|
"share.embed": "Embed in another page",
|
|
56
56
|
"share.embedHint": "Drops the site header and its navigation, so the page sits inside a page of your own.",
|
|
57
|
+
"share.protect": "Protect this link",
|
|
58
|
+
"share.protectHint": "The class can neither read nor change what the link sets up, and the page's address stays fixed. The page is embedded.",
|
|
57
59
|
"share.on": "On",
|
|
58
60
|
"share.off": "Off",
|
|
59
61
|
"share.showOnPage": "Show on the page",
|
|
@@ -76,6 +78,9 @@
|
|
|
76
78
|
"share.copyIframe": "Copy the iframe",
|
|
77
79
|
"share.copyIframeHelpTitle": "Put the page inside yours",
|
|
78
80
|
"share.copyIframeHelp": "A snippet of HTML to paste where your own page's HTML is edited: the tool then runs inside it.",
|
|
81
|
+
"seal.refusedTitle": "This link cannot be opened",
|
|
82
|
+
"seal.refusedBody": "It was changed after it was made, or it is incomplete, so nothing was opened. Ask for the link again.",
|
|
83
|
+
"seal.openWithout": "Open the tool without it",
|
|
79
84
|
"cite.button": "Cite",
|
|
80
85
|
"cite.copyReferenceAs": "Copy the reference as",
|
|
81
86
|
"cite.pleaseCiteBoth": "Please cite both works",
|
package/src/locales/es.json
CHANGED
|
@@ -54,6 +54,8 @@
|
|
|
54
54
|
"share.layout": "Disposición",
|
|
55
55
|
"share.embed": "Incrustar en otra página",
|
|
56
56
|
"share.embedHint": "Quita la cabecera del sitio y su navegación, para que la página quede dentro de una página suya.",
|
|
57
|
+
"share.protect": "Proteger este enlace",
|
|
58
|
+
"share.protectHint": "La clase no puede leer ni cambiar lo que configura el enlace, y la dirección de la página queda fija. La página se integra.",
|
|
57
59
|
"share.on": "Sí",
|
|
58
60
|
"share.off": "No",
|
|
59
61
|
"share.showOnPage": "Mostrar en la página",
|
|
@@ -76,6 +78,9 @@
|
|
|
76
78
|
"share.copyIframe": "Copiar el iframe",
|
|
77
79
|
"share.copyIframeHelpTitle": "Poner la página dentro de la tuya",
|
|
78
80
|
"share.copyIframeHelp": "Un fragmento de HTML para pegar donde se edita el HTML de tu página: la herramienta funciona dentro de él.",
|
|
81
|
+
"seal.refusedTitle": "Este enlace no se puede abrir",
|
|
82
|
+
"seal.refusedBody": "Se modificó después de crearse, o está incompleto, así que no se abrió nada. Pide el enlace de nuevo.",
|
|
83
|
+
"seal.openWithout": "Abrir la herramienta sin el enlace",
|
|
79
84
|
"cite.button": "Citar",
|
|
80
85
|
"cite.copyReferenceAs": "Copiar la referencia como",
|
|
81
86
|
"cite.pleaseCiteBoth": "Por favor, cite ambos trabajos",
|
package/src/locales/fr.json
CHANGED
|
@@ -54,6 +54,8 @@
|
|
|
54
54
|
"share.layout": "Disposition",
|
|
55
55
|
"share.embed": "Intégrer dans une autre page",
|
|
56
56
|
"share.embedHint": "Retire l'en-tête du site et sa navigation, pour que la page prenne place dans une page à vous.",
|
|
57
|
+
"share.protect": "Protéger ce lien",
|
|
58
|
+
"share.protectHint": "La classe ne peut ni lire ni modifier ce que le lien règle, et l'adresse de la page reste fixe. La page est intégrée.",
|
|
57
59
|
"share.on": "Oui",
|
|
58
60
|
"share.off": "Non",
|
|
59
61
|
"share.showOnPage": "Afficher sur la page",
|
|
@@ -76,6 +78,9 @@
|
|
|
76
78
|
"share.copyIframe": "Copier l'iframe",
|
|
77
79
|
"share.copyIframeHelpTitle": "Mettre la page dans la vôtre",
|
|
78
80
|
"share.copyIframeHelp": "Un extrait de HTML à coller là où le HTML de votre page s'édite : l'outil s'exécute alors à l'intérieur.",
|
|
81
|
+
"seal.refusedTitle": "Ce lien ne peut pas être ouvert",
|
|
82
|
+
"seal.refusedBody": "Il a été modifié après sa création, ou il est incomplet : rien n'a été ouvert. Demandez à nouveau le lien.",
|
|
83
|
+
"seal.openWithout": "Ouvrir l'outil sans ce lien",
|
|
79
84
|
"cite.button": "Citer",
|
|
80
85
|
"cite.copyReferenceAs": "Copier la référence en",
|
|
81
86
|
"cite.pleaseCiteBoth": "Merci de citer les deux travaux",
|
package/src/locales/it.json
CHANGED
|
@@ -54,6 +54,8 @@
|
|
|
54
54
|
"share.layout": "Disposizione",
|
|
55
55
|
"share.embed": "Incorporare in un'altra pagina",
|
|
56
56
|
"share.embedHint": "Toglie l'intestazione del sito e la sua navigazione, così la pagina sta dentro una pagina propria.",
|
|
57
|
+
"share.protect": "Proteggi questo link",
|
|
58
|
+
"share.protectHint": "La classe non può né leggere né modificare ciò che il link imposta, e l'indirizzo della pagina resta fisso. La pagina viene incorporata.",
|
|
57
59
|
"share.on": "Sì",
|
|
58
60
|
"share.off": "No",
|
|
59
61
|
"share.showOnPage": "Mostra nella pagina",
|
|
@@ -76,6 +78,9 @@
|
|
|
76
78
|
"share.copyIframe": "Copia l'iframe",
|
|
77
79
|
"share.copyIframeHelpTitle": "Mettere la pagina dentro la tua",
|
|
78
80
|
"share.copyIframeHelp": "Un frammento di HTML da incollare dove si modifica l'HTML della tua pagina: lo strumento funziona al suo interno.",
|
|
81
|
+
"seal.refusedTitle": "Questo link non può essere aperto",
|
|
82
|
+
"seal.refusedBody": "È stato modificato dopo la creazione, o è incompleto, quindi non si è aperto nulla. Chiedi di nuovo il link.",
|
|
83
|
+
"seal.openWithout": "Apri lo strumento senza il link",
|
|
79
84
|
"cite.button": "Cita",
|
|
80
85
|
"cite.copyReferenceAs": "Copia il riferimento come",
|
|
81
86
|
"cite.pleaseCiteBoth": "Si prega di citare entrambi i lavori",
|
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
* The tab router bound to the browser: read the address on screen, write a new
|
|
3
3
|
* one through the History API, and hear every move.
|
|
4
4
|
*
|
|
5
|
-
* The router itself stays pure. Everything here reads
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* The router itself stays pure. Everything here reads and writes the address
|
|
6
|
+
* through `pageLocation` and `pageHistory` — the browser's, or the one a sealed
|
|
7
|
+
* link holds in memory — and does nothing where neither exists, so a prerender
|
|
8
|
+
* script can import a module that uses it.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
import { EMBED_PARAM, HIDE_PARAM } from '../../share/core/config.ts';
|
|
11
12
|
|
|
13
|
+
import { pageHistory, pageLocation } from './pageAddress.ts';
|
|
12
14
|
import type { QueryEntry } from './query.ts';
|
|
13
15
|
import { formatQueryEntries } from './query.ts';
|
|
14
16
|
import type { TabRoute, TabRouteInput, TabRouter } from './tabRouter.ts';
|
|
@@ -34,7 +36,7 @@ export function readRoute<Tab extends string>(
|
|
|
34
36
|
const address = currentAddress();
|
|
35
37
|
const adopted = router.legacyAddress(address);
|
|
36
38
|
if (adopted === null) return router.parse(address);
|
|
37
|
-
const history =
|
|
39
|
+
const history = pageHistory();
|
|
38
40
|
history?.replaceState(history.state, '', adopted);
|
|
39
41
|
globalThis.dispatchEvent?.(new Event(ROUTE_CHANGE_EVENT));
|
|
40
42
|
return router.parse(adopted);
|
|
@@ -78,8 +80,8 @@ export function writeRoute<Tab extends string>(
|
|
|
78
80
|
): string {
|
|
79
81
|
const current = currentAddress();
|
|
80
82
|
const address = withKeptParams(router, route, current, options.keep ?? []);
|
|
81
|
-
const location =
|
|
82
|
-
const history =
|
|
83
|
+
const location = pageLocation();
|
|
84
|
+
const history = pageHistory();
|
|
83
85
|
if (location === undefined || history === undefined) return address;
|
|
84
86
|
|
|
85
87
|
const shown =
|
|
@@ -126,7 +128,7 @@ export function subscribeToRoute<Tab extends string>(
|
|
|
126
128
|
* @returns It, or `/` where there is no browser.
|
|
127
129
|
*/
|
|
128
130
|
export function currentAddress(): string {
|
|
129
|
-
const location =
|
|
131
|
+
const location = pageLocation();
|
|
130
132
|
if (location === undefined) return '/';
|
|
131
133
|
return `${location.pathname}${location.search}${location.hash}`;
|
|
132
134
|
}
|
|
@@ -150,11 +152,3 @@ function withKeptParams<Tab extends string>(
|
|
|
150
152
|
const separator = target.includes('?') ? '&' : '?';
|
|
151
153
|
return `${target}${separator}${formatQueryEntries(kept)}`;
|
|
152
154
|
}
|
|
153
|
-
|
|
154
|
-
function browserLocation(): Location | undefined {
|
|
155
|
-
return globalThis.location;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function browserHistory(): History | undefined {
|
|
159
|
-
return globalThis.history;
|
|
160
|
-
}
|
package/src/router/core/index.ts
CHANGED
|
@@ -18,6 +18,14 @@ export type {
|
|
|
18
18
|
LegacyHashOptions,
|
|
19
19
|
} from './legacyHash.ts';
|
|
20
20
|
export { adoptLegacyHashAddress, pathFromLegacyHash } from './legacyHash.ts';
|
|
21
|
+
export type { PageHistory, PageLocation } from './pageAddress.ts';
|
|
22
|
+
export {
|
|
23
|
+
holdPageAddress,
|
|
24
|
+
isPageAddressHeld,
|
|
25
|
+
pageHistory,
|
|
26
|
+
pageLocation,
|
|
27
|
+
releasePageAddress,
|
|
28
|
+
} from './pageAddress.ts';
|
|
21
29
|
export type { QueryEntry, QueryStringOptions } from './query.ts';
|
|
22
30
|
export {
|
|
23
31
|
firstQueryValues,
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a page reads its own address and writes it back. Normally that is the
|
|
3
|
+
* browser's `location` and `history`; a page opened from a sealed link holds
|
|
4
|
+
* its address in memory instead, so the app navigates as usual while the
|
|
5
|
+
* address bar keeps showing the link that was handed out.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** The part of `window.location` a page reads its address from. */
|
|
9
|
+
export interface PageLocation {
|
|
10
|
+
/** The path of the address. */
|
|
11
|
+
readonly pathname: string;
|
|
12
|
+
/** The query string, with its leading `?` or empty. */
|
|
13
|
+
readonly search: string;
|
|
14
|
+
/** The fragment, with its leading `#` or empty. */
|
|
15
|
+
readonly hash: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** The part of `window.history` a page writes its address through. */
|
|
19
|
+
export interface PageHistory {
|
|
20
|
+
/** The state of the current entry. */
|
|
21
|
+
readonly state: unknown;
|
|
22
|
+
/**
|
|
23
|
+
* Add an entry.
|
|
24
|
+
* @param data - The state of the new entry.
|
|
25
|
+
* @param unused - Ignored by browsers.
|
|
26
|
+
* @param url - The new address, absolute or relative to the current one.
|
|
27
|
+
*/
|
|
28
|
+
pushState(data: unknown, unused: string, url: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Rewrite the current entry without adding one.
|
|
31
|
+
* @param data - The state to keep.
|
|
32
|
+
* @param unused - Ignored by browsers.
|
|
33
|
+
* @param url - The new address, absolute or relative to the current one.
|
|
34
|
+
*/
|
|
35
|
+
replaceState(data: unknown, unused: string, url: string): void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Only parses addresses relative to the held one; never fetched or shown.
|
|
39
|
+
const HELD_ORIGIN = 'https://held.invalid';
|
|
40
|
+
|
|
41
|
+
let held: HeldAddress | undefined;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The address the page reads: the held one when there is one, else the
|
|
45
|
+
* browser's.
|
|
46
|
+
* @returns It, or `undefined` where there is no browser.
|
|
47
|
+
*/
|
|
48
|
+
export function pageLocation(): PageLocation | undefined {
|
|
49
|
+
return held ?? globalThis.location;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The history the page writes its address through: the held address when
|
|
54
|
+
* there is one, else the browser's.
|
|
55
|
+
* @returns It, or `undefined` where there is no browser.
|
|
56
|
+
*/
|
|
57
|
+
export function pageHistory(): PageHistory | undefined {
|
|
58
|
+
return held ?? globalThis.history;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Hold the page's address in memory from now on. Every read through
|
|
63
|
+
* {@link pageLocation} and every write through {@link pageHistory} uses it, and
|
|
64
|
+
* the browser's address bar is never written again.
|
|
65
|
+
* @param address - The address the page opens on: path, query and fragment.
|
|
66
|
+
*/
|
|
67
|
+
export function holdPageAddress(address: string): void {
|
|
68
|
+
held = new HeldAddress(address);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Whether the page's address is held in memory.
|
|
73
|
+
* @returns True after {@link holdPageAddress}.
|
|
74
|
+
*/
|
|
75
|
+
export function isPageAddressHeld(): boolean {
|
|
76
|
+
return held !== undefined;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Go back to reading and writing the browser's own address. */
|
|
80
|
+
export function releasePageAddress(): void {
|
|
81
|
+
held = undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
class HeldAddress implements PageLocation, PageHistory {
|
|
85
|
+
pathname = '/';
|
|
86
|
+
search = '';
|
|
87
|
+
hash = '';
|
|
88
|
+
state: unknown = null;
|
|
89
|
+
|
|
90
|
+
constructor(address: string) {
|
|
91
|
+
this.go(null, address);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
pushState(data: unknown, unused: string, url: string): void {
|
|
95
|
+
this.go(data, url);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
replaceState(data: unknown, unused: string, url: string): void {
|
|
99
|
+
this.go(data, url);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private go(data: unknown, url: string): void {
|
|
103
|
+
const base = `${HELD_ORIGIN}${this.pathname}${this.search}${this.hash}`;
|
|
104
|
+
const next = new URL(url, base);
|
|
105
|
+
this.pathname = next.pathname;
|
|
106
|
+
this.search = next.search;
|
|
107
|
+
this.hash = next.hash;
|
|
108
|
+
this.state = data;
|
|
109
|
+
}
|
|
110
|
+
}
|