159 lines
6.7 KiB
JavaScript
159 lines
6.7 KiB
JavaScript
export const paneRouteConfig = {
|
|
primary: {
|
|
sourceKindParam: 'sourceKind',
|
|
rootUriParam: 'rootUri',
|
|
secondary: false,
|
|
},
|
|
secondary: {
|
|
documentIdParam: 'secondaryDocumentId',
|
|
sourceKindParam: 'secondarySourceKind',
|
|
rootUriParam: 'secondaryRootUri',
|
|
secondary: true,
|
|
},
|
|
};
|
|
|
|
export const secondaryQueryParamNames = [
|
|
paneRouteConfig.secondary.documentIdParam,
|
|
paneRouteConfig.secondary.sourceKindParam,
|
|
paneRouteConfig.secondary.rootUriParam,
|
|
];
|
|
|
|
export const currentUrl = () => new URL(window.location.href);
|
|
|
|
export const replaceUrlState = (url) => {
|
|
window.history.replaceState({}, '', url.pathname + url.search + url.hash);
|
|
};
|
|
|
|
export const pushUrlState = (url) => {
|
|
window.history.pushState({}, '', url.pathname + url.search + url.hash);
|
|
};
|
|
|
|
export const clearSecondaryParams = () => {
|
|
const url = currentUrl();
|
|
secondaryQueryParamNames.forEach((name) => url.searchParams.delete(name));
|
|
replaceUrlState(url);
|
|
};
|
|
|
|
export const secondaryUrlForDocument = (documentId, detail = {}) => {
|
|
const url = currentUrl();
|
|
url.searchParams.set(paneRouteConfig.secondary.documentIdParam, documentId);
|
|
const detailSourceKind = typeof detail.sourceKind === 'string' ? detail.sourceKind.trim() : '';
|
|
const detailRootUri = typeof detail.rootUri === 'string' ? detail.rootUri.trim() : '';
|
|
const primarySourceKind = (url.searchParams.get(paneRouteConfig.primary.sourceKindParam) || '').trim();
|
|
const primaryRootUri = (url.searchParams.get(paneRouteConfig.primary.rootUriParam) || '').trim();
|
|
const secondarySourceKind = detailSourceKind || primarySourceKind;
|
|
const secondaryRootUri = detailRootUri || primaryRootUri;
|
|
if (secondarySourceKind) url.searchParams.set(paneRouteConfig.secondary.sourceKindParam, secondarySourceKind);
|
|
else url.searchParams.delete(paneRouteConfig.secondary.sourceKindParam);
|
|
if (secondaryRootUri) url.searchParams.set(paneRouteConfig.secondary.rootUriParam, secondaryRootUri);
|
|
else url.searchParams.delete(paneRouteConfig.secondary.rootUriParam);
|
|
return { url, sourceKind: secondarySourceKind, rootUri: secondaryRootUri };
|
|
};
|
|
|
|
export const openDocumentInSecondaryPane = (documentId, detail = {}) => {
|
|
const id = typeof documentId === 'string' ? documentId.trim() : '';
|
|
if (!id) return false;
|
|
const target = secondaryUrlForDocument(id, detail);
|
|
if (typeof window.__mnoteDocumentPaneRuntime?.openSecondaryDocument === 'function') {
|
|
void window.__mnoteDocumentPaneRuntime.openSecondaryDocument({
|
|
documentId: id,
|
|
workspaceId: typeof detail.workspaceId === 'string' ? detail.workspaceId.trim() : '',
|
|
sourceKind: target.sourceKind || null,
|
|
rootUri: target.rootUri || null,
|
|
url: target.url,
|
|
});
|
|
return true;
|
|
}
|
|
window.location.assign(target.url.pathname + target.url.search + target.url.hash);
|
|
return true;
|
|
};
|
|
|
|
export const installSecondaryPaneOpenListeners = () => {
|
|
window.addEventListener('tree.page.open-right', (event) => {
|
|
const detail = event?.detail && typeof event.detail === 'object' ? event.detail : {};
|
|
const documentId = typeof detail.documentId === 'string' ? detail.documentId.trim() : '';
|
|
openDocumentInSecondaryPane(documentId, detail);
|
|
});
|
|
|
|
window.addEventListener('tree.page.open', (event) => {
|
|
const detail = event?.detail && typeof event.detail === 'object' ? event.detail : {};
|
|
const openTarget = typeof detail.openTarget === 'string' ? detail.openTarget.trim().toLowerCase() : '';
|
|
if (openTarget !== 'side') return;
|
|
const documentId = typeof detail.documentId === 'string' ? detail.documentId.trim() : '';
|
|
openDocumentInSecondaryPane(documentId, detail);
|
|
});
|
|
};
|
|
|
|
export const installSecondaryPaneCloseButtons = () => {
|
|
document.querySelectorAll('[data-mnote-pane-close="secondary"]').forEach((button) => {
|
|
button.addEventListener('click', (event) => {
|
|
event.preventDefault();
|
|
const url = currentUrl();
|
|
secondaryQueryParamNames.forEach((name) => url.searchParams.delete(name));
|
|
if (typeof window.__mnoteDocumentPaneRuntime?.closeSecondaryDocument === 'function') {
|
|
window.__mnoteDocumentPaneRuntime.closeSecondaryDocument({ url });
|
|
return;
|
|
}
|
|
window.location.assign(url.pathname + url.search + url.hash);
|
|
});
|
|
});
|
|
};
|
|
|
|
export const createSecondaryPaneWidthController = () => {
|
|
const workspace = document.querySelector('[data-testid="mnote-document-workspace"]');
|
|
const resizer = document.querySelector('[data-document-pane-resizer="true"]');
|
|
const secondaryWidthKey = 'mnote.document.secondary.width';
|
|
const applyStoredSecondaryWidth = () => {
|
|
if (!(workspace instanceof HTMLElement)) return;
|
|
if (workspace.getAttribute('data-has-secondary-pane') !== 'true') {
|
|
workspace.style.removeProperty('grid-template-columns');
|
|
return;
|
|
}
|
|
try {
|
|
const raw = window.localStorage ? window.localStorage.getItem(secondaryWidthKey) : '';
|
|
const width = Number(raw || 0);
|
|
if (Number.isFinite(width) && width >= 320) {
|
|
workspace.style.gridTemplateColumns = `minmax(0, 1fr) 6px minmax(320px, ${Math.round(width)}px)`;
|
|
}
|
|
} catch (_) {}
|
|
};
|
|
|
|
if (workspace instanceof HTMLElement && resizer instanceof HTMLElement) {
|
|
resizer.addEventListener('pointerdown', (event) => {
|
|
if (workspace.getAttribute('data-has-secondary-pane') !== 'true') return;
|
|
event.preventDefault();
|
|
const move = (nextEvent) => {
|
|
const rect = workspace.getBoundingClientRect();
|
|
const width = Math.min(Math.max(320, rect.right - nextEvent.clientX), Math.max(420, rect.width - 360));
|
|
workspace.style.gridTemplateColumns = `minmax(0, 1fr) 6px minmax(320px, ${Math.round(width)}px)`;
|
|
try {
|
|
if (window.localStorage) window.localStorage.setItem(secondaryWidthKey, String(Math.round(width)));
|
|
} catch (_) {}
|
|
};
|
|
const up = () => {
|
|
window.removeEventListener('pointermove', move);
|
|
window.removeEventListener('pointerup', up);
|
|
};
|
|
window.addEventListener('pointermove', move);
|
|
window.addEventListener('pointerup', up);
|
|
});
|
|
}
|
|
|
|
return { workspace, applyStoredSecondaryWidth };
|
|
};
|
|
|
|
export const buildPaneRuntime = (paneDescriptor, rootSelector) => {
|
|
const paneRole = typeof paneDescriptor?.role === 'string' ? paneDescriptor.role : 'primary';
|
|
const paneRoot = document.querySelector(`${rootSelector}[data-pane-role="${paneRole}"]`);
|
|
const observability = document.querySelector(`[data-editor-host-observability][data-pane-role="${paneRole}"]`);
|
|
if (!(paneRoot instanceof HTMLElement)) return null;
|
|
if (!paneDescriptor?.aggregate || !paneDescriptor?.bootstrap) return null;
|
|
return {
|
|
paneRole,
|
|
root: paneRoot,
|
|
observability,
|
|
aggregate: paneDescriptor.aggregate,
|
|
bootstrap: paneDescriptor.bootstrap,
|
|
};
|
|
};
|