refactor: split sidebar filetree open runtime

This commit is contained in:
lix-2026
2026-05-26 01:58:00 +08:00
parent f2d4ec8086
commit 34f2d5280a
6 changed files with 508 additions and 415 deletions
@@ -165,7 +165,7 @@ cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib routes::web_shell
- [x] C1. `sidebar-workspace-runtime.js`workspace source switch、sidebar tabs、collapse/resize 状态。
- [ ] C2. `sidebar-page-tree-runtime.js`page tree row selection、rename title patch、breadcrumb/title sync。
- [ ] C3. `sidebar-filetree-open-runtime.js`local markdown / resource open target、active resource tab dispatch。
- [x] C3. `sidebar-filetree-open-runtime.js`local markdown / resource open target、active resource tab dispatch。
- [ ] C4. `sidebar-filetree-command-runtime.js`create/rename/delete/copy/move/trash/restore/purge command payload。
- [ ] C5. `sidebar-filetree-upload-runtime.js`local upload target plan、drop/paste preflight、readonly guard。
- [ ] C6. `sidebar-attachment-open-runtime.js`OnlyOffice/PDF/code/image open mode guard。
@@ -0,0 +1,422 @@
export const createSidebarFileTreeOpenRuntime = (dependencies = {}) => {
const {
copyWorkspaceSourceParams,
currentDocumentId,
currentRootUri,
fileTreeIconKindForFileName,
getNavigationInFlight,
isCodeAttachmentFileName,
isNonOfficeAttachmentName,
openCodeEditorAttachment,
resolveWorkspaceId,
setNavigationInFlight,
shouldOpenLocalResourceInNewWindow,
uploadedFileSize,
} = dependencies;
function inferOnlyOfficeFileType(fileName, mimeType) {
var name = String(fileName || '').trim().toLowerCase();
var mt = String(mimeType || '').trim().toLowerCase();
var ext = name.indexOf('.') >= 0 ? name.split('.').pop() : '';
if (['doc', 'docx', 'odt', 'rtf'].indexOf(ext) >= 0) return ext;
if (['ppt', 'pptx', 'odp'].indexOf(ext) >= 0) return ext;
if (['xls', 'xlsx', 'ods', 'csv'].indexOf(ext) >= 0) return ext;
if (isNonOfficeAttachmentName(name, ext)) return '';
if (mt.indexOf('wordprocessingml') >= 0) return 'docx';
if (mt.indexOf('presentationml') >= 0) return 'pptx';
if (mt.indexOf('spreadsheetml') >= 0) return 'xlsx';
return '';
}
function buildOnlyOfficeOpenUrl(input) {
var target = new URL('/onlyoffice', window.location.origin);
var fileUrl = String(input.fileUrl || '').trim();
if (fileUrl) {
try {
fileUrl = new URL(fileUrl, window.location.origin).toString();
} catch (_error) {}
}
target.searchParams.set('fileUrl', fileUrl);
target.searchParams.set('fileName', input.fileName || '未命名资源');
target.searchParams.set('fileType', input.fileType || 'docx');
if (input.assetId) target.searchParams.set('assetId', input.assetId);
if (input.documentId) target.searchParams.set('documentId', input.documentId);
if (input.userId) target.searchParams.set('userId', input.userId);
target.searchParams.set('mode', input.mode || 'view');
return target.toString();
}
function buildOnlyOfficeOpenPath(input) {
var _rto_ = window.__mnoteResourceOpenRuntime;
if (_rto_ && typeof _rto_.buildOnlyOfficeOpenPath === 'function') {
return _rto_.buildOnlyOfficeOpenPath(input);
}
var params = new URLSearchParams();
params.set('fileUrl', input.fileUrl || '');
params.set('fileName', input.fileName || '未命名资源');
params.set('fileType', input.fileType || 'docx');
if (input.assetId) params.set('assetId', input.assetId);
if (input.documentId) params.set('documentId', input.documentId);
if (input.userId) params.set('userId', input.userId);
params.set('mode', input.mode || 'view');
if (input.documentId && input.assetId) {
return '/office/' + encodeURIComponent(input.documentId) + '/' + encodeURIComponent(input.assetId) + '?' + params.toString();
}
return '/onlyoffice?' + params.toString();
}
function buildLocalOnlyOfficeOpenUrl(relativePath, fileName, documentId, assetId, mode) {
var fileType = inferOnlyOfficeFileType(fileName || relativePath || '', '');
if (!fileType) return '';
var fileUrl = buildLocalFileOpenUrl(relativePath, false);
if (!fileUrl) return '';
return buildOnlyOfficeOpenUrl({
fileUrl: fileUrl,
fileName: fileName || relativePath || '未命名资源',
fileType: fileType,
assetId: assetId || ('local-file:' + relativePath),
documentId: documentId || currentDocumentId() || '',
userId: '',
mode: mode || 'view'
});
}
async function openLocalOfficeFileInActiveTab(detail, mode) {
var localFilePath = localFilePathFromAssetId(detail.assetId);
if (!localFilePath) return false;
var localFileName = localFilePath.split('/').pop() || localFilePath;
var localOfficeUrl = buildLocalOnlyOfficeOpenUrl(localFilePath, localFileName, String(detail.documentId || currentDocumentId() || '').trim(), detail.assetId, mode || 'view');
if (!localOfficeUrl) return false;
var opened = await openLocalResourceInActiveTab({
path: localFilePath,
title: detail.fileName || localFileName,
kind: 'office',
assetId: detail.assetId,
documentId: detail.documentId || currentDocumentId() || '',
workspaceId: detail.workspaceId || resolveWorkspaceId(document.body) || '',
href: buildLocalFileOpenUrl(localFilePath, false),
officeUrl: localOfficeUrl,
paneRole: detail.paneRole || 'primary'
});
if (!opened) window.open(localOfficeUrl, '_blank', 'noopener,noreferrer');
return true;
}
function buildMindmapOpenPath(documentId, assetId) {
var doc = String(documentId || '').trim();
var map = String(assetId || '').trim();
if (!doc || !map) return '';
var targetUrl = new URL('/mindmap/' + encodeURIComponent(doc) + '/' + encodeURIComponent(map), window.location.origin);
copyWorkspaceSourceParams(targetUrl);
return targetUrl.pathname + targetUrl.search;
}
function navigateToMindmapObject(documentId, assetId, workspaceId) {
var mindmapPath = buildMindmapOpenPath(documentId, assetId);
if (!mindmapPath) return false;
var targetUrl = new URL(mindmapPath, window.location.origin);
var url = targetUrl.pathname + targetUrl.search;
if (getNavigationInFlight() === url) return true;
if (typeof window.__mnoteDocumentPaneRuntime?.openPrimaryMindmap === 'function') {
setNavigationInFlight(url);
document.documentElement.setAttribute('data-mnote-navigation-pending', 'true');
document.documentElement.setAttribute('data-mnote-navigation-target', assetId);
window.__mnoteDocumentPaneRuntime.openPrimaryMindmap({
documentId: documentId,
mindmapId: assetId,
workspaceId: workspaceId || '',
url: targetUrl
}).then(function(){
if (getNavigationInFlight() === url) setNavigationInFlight('');
document.documentElement.removeAttribute('data-mnote-navigation-pending');
}).catch(function(error){
console.warn('mnote mindmap pane 内导航失败,将回退整页导航', error);
if (window.__mnoteTreeLiveEventSource && typeof window.__mnoteTreeLiveEventSource.close === 'function') {
window.__mnoteTreeLiveEventSource.close();
}
window.location.assign(url);
});
return true;
}
setNavigationInFlight(url);
document.documentElement.setAttribute('data-mnote-navigation-pending', 'true');
document.documentElement.setAttribute('data-mnote-navigation-target', assetId);
if (window.__mnoteTreeLiveEventSource && typeof window.__mnoteTreeLiveEventSource.close === 'function') {
window.__mnoteTreeLiveEventSource.close();
}
window.location.assign(url);
return true;
}
function isMindmapAssetDetail(detail) {
var assetId = String(detail && detail.assetId || '').trim();
var assetType = String(detail && detail.assetType || '').trim();
if (assetType === 'mindmap') return true;
var fileName = assetId.indexOf('/') >= 0 ? assetId.split('/').pop() : assetId;
return assetId.indexOf('mindmap_') === 0
|| assetId.indexOf('mindmap-') === 0
|| /\.mindmap\.json$/i.test(fileName)
|| (/^思维导图/i.test(fileName) && /\.json$/i.test(fileName));
}
function localFilePathFromAssetId(assetId) {
var _rto_ = window.__mnoteResourceOpenRuntime;
if (_rto_ && typeof _rto_.localFilePathFromAssetId === 'function') {
return _rto_.localFilePathFromAssetId(assetId);
}
var value = String(assetId || '').trim();
return value.indexOf('local-file:') === 0 ? value.slice('local-file:'.length) : value.indexOf('local:asset:') === 0 ? value.slice('local:asset:'.length) : '';
}
function buildLocalFileOpenUrl(relativePath, download) {
var _rto_ = window.__mnoteResourceOpenRuntime;
if (_rto_ && typeof _rto_.buildLocalFileOpenUrl === 'function') {
return _rto_.buildLocalFileOpenUrl(relativePath, download);
}
var rootUri = currentRootUri();
if (!rootUri || !relativePath) return '';
var url = new URL('/api/local-folder/files/open', window.location.origin);
url.searchParams.set('rootUri', rootUri);
url.searchParams.set('path', relativePath);
if (download) url.searchParams.set('download', 'true');
return url.toString();
}
async function openLocalResourceInActiveTab(input) {
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab !== 'function') return false;
var relativePath = String(input && input.path || '').trim();
var rootUri = String(input && input.rootUri || currentRootUri() || '').trim();
if (!relativePath || !rootUri) return false;
var title = String(input && input.title || '').trim() || relativePath.split('/').pop() || relativePath;
var kind = String(input && input.kind || fileTreeIconKindForFileName(title) || '').trim();
var objectIdentity = 'resource:file:' + rootUri + ':' + relativePath;
return await window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
objectIdentity: objectIdentity,
assetId: String(input && input.assetId || '').trim() || 'local-file:' + relativePath,
title: title,
fileName: title,
kind: kind,
rootUri: rootUri,
path: relativePath,
href: String(input && input.href || buildLocalFileOpenUrl(relativePath, false) || '').trim(),
officeUrl: String(input && input.officeUrl || '').trim(),
documentId: String(input && input.documentId || currentDocumentId() || '').trim(),
workspaceId: String(input && input.workspaceId || resolveWorkspaceId(document.body) || '').trim(),
paneRole: String(input && input.paneRole || 'primary').trim() || 'primary'
});
}
function readFileTreeObjectIdentity(row) {
if (!row) return null;
var raw = row.getAttribute('data-object-identity') || '';
if (!raw) return null;
try {
var parsed = JSON.parse(raw);
return parsed && typeof parsed === 'object' ? parsed : null;
} catch (_error) {
return null;
}
}
async function fetchCurrentOnlyOfficeUserId() {
try {
var response = await fetch('/api/auth/whoami', {
method: 'GET',
credentials: 'include',
cache: 'no-store'
});
var payload = await response.json().catch(function() { return null; });
return String(payload && payload.userId || '').trim();
} catch (_error) {
return '';
}
}
async function openConvexAssetFromFileTree(detail) {
var assetId = String(detail && detail.assetId || '').trim();
if (!assetId) return;
var openTarget = String(detail && detail.openTarget || '').trim().toLowerCase();
var forceNewWindow = openTarget === 'new-window';
var forceEditMode = openTarget === 'edit-mode';
if (openTarget === 'side') {
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceAsSideTarget === 'function') {
var sideLocalFilePath = localFilePathFromAssetId(assetId);
var sideRootUri = String(detail.rootUri || currentRootUri() || '').trim();
var sideFileName = String(detail.title || detail.fileName || (sideLocalFilePath ? sideLocalFilePath.split('/').pop() : '') || assetId || '').trim();
var sideKind = String(detail.iconKind || detail.assetType || fileTreeIconKindForFileName(sideFileName) || 'file').trim();
var sideHref = sideLocalFilePath ? buildLocalFileOpenUrl(sideLocalFilePath, false) : '';
var sideOfficeUrl = sideLocalFilePath ? buildLocalOnlyOfficeOpenUrl(sideLocalFilePath, sideFileName, String(detail.documentId || currentDocumentId() || '').trim(), assetId, 'view') : '';
if (sideOfficeUrl) sideKind = 'office';
void window.__mnoteDocumentPaneRuntime.openResourceAsSideTarget({
objectIdentity: sideLocalFilePath && sideRootUri ? 'resource:file:' + sideRootUri + ':' + sideLocalFilePath : String(detail.objectIdentity || detail.assetId || ''),
assetId: assetId,
title: sideFileName,
fileName: sideFileName,
kind: sideKind,
path: sideLocalFilePath,
rootUri: sideRootUri,
href: sideHref,
officeUrl: sideOfficeUrl,
documentId: String(detail.documentId || currentDocumentId() || ''),
workspaceId: String(detail.workspaceId || resolveWorkspaceId(document.body) || '')
});
}
return;
}
var localFilePath = localFilePathFromAssetId(assetId);
if (localFilePath) {
var localFileName = localFilePath.split('/').pop() || localFilePath;
if (isMindmapAssetDetail(detail) || String(detail && detail.assetType || '').trim() === 'mindmap') {
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') {
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'mindmap-resource-tab');
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId);
void window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
objectIdentity: 'resource:mindmap:' + String(detail && detail.documentId || currentDocumentId() || '').trim() + ':' + assetId,
assetId: assetId,
mindmapId: assetId,
title: String(detail && detail.title || localFileName || '思维导图').trim(),
fileName: localFileName,
kind: 'mindmap',
documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(),
workspaceId: String(detail.workspaceId || '').trim()
});
return;
}
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'local-mindmap-object-shell');
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId);
navigateToMindmapObject(String(detail && detail.documentId || currentDocumentId() || '').trim(), assetId, String(detail.workspaceId || '').trim());
return;
}
var requestedOfficeMode = forceNewWindow || forceEditMode ? 'edit' : 'view';
var localOfficeUrl = buildLocalOnlyOfficeOpenUrl(localFilePath, localFileName, String(detail && detail.documentId || currentDocumentId() || '').trim(), assetId, requestedOfficeMode);
if (localOfficeUrl) {
if (!forceNewWindow && await openLocalResourceInActiveTab({
path: localFilePath,
title: localFileName,
kind: 'office',
assetId: assetId,
documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(),
workspaceId: String(detail.workspaceId || '').trim(),
officeUrl: localOfficeUrl
})) return;
window.open(localOfficeUrl, '_blank', 'noopener,noreferrer');
return;
}
var localFileUrl = buildLocalFileOpenUrl(localFilePath, false);
if (localFileUrl) {
var shouldOpenInNewWindow = forceNewWindow || shouldOpenLocalResourceInNewWindow(localFileName);
if (!shouldOpenInNewWindow && await openLocalResourceInActiveTab({
path: localFilePath,
title: localFileName,
kind: fileTreeIconKindForFileName(localFileName),
assetId: assetId,
documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(),
workspaceId: String(detail.workspaceId || '').trim(),
href: localFileUrl
})) return;
window.open(localFileUrl, '_blank', 'noopener,noreferrer');
}
return;
}
var documentId = String(detail && detail.documentId || '').trim();
if (isMindmapAssetDetail(detail) && documentId) {
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') {
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'mindmap-resource-tab');
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId);
void window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
objectIdentity: 'resource:mindmap:' + documentId + ':' + assetId,
assetId: assetId,
mindmapId: assetId,
title: String(detail.title || '思维导图').trim(),
fileName: String(detail.title || '思维导图').trim(),
kind: 'mindmap',
documentId: documentId,
workspaceId: String(detail.workspaceId || '').trim()
});
return;
}
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'mindmap-object-shell');
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId);
navigateToMindmapObject(documentId, assetId, String(detail.workspaceId || '').trim());
return;
}
try {
var response = await fetch('/api/media/sign?assetId=' + encodeURIComponent(assetId), {
method: 'GET',
credentials: 'include'
});
var payload = await response.json().catch(function() { return null; });
if (!response.ok) {
throw new Error(payload && payload.error ? payload.error : '生成签名链接失败');
}
var asset = payload && payload.asset && typeof payload.asset === 'object' ? payload.asset : {};
var fileUrl = String(payload && payload.signedUrl || asset.file_url || asset.signed_url || '').trim();
if (!fileUrl) throw new Error('附件链接不可用');
var fileName = String(asset.file_name || detail.fileName || '未命名资源').trim() || '未命名资源';
var fileType = inferOnlyOfficeFileType(fileName, asset.mime_type);
if (fileType) {
var userId = await fetchCurrentOnlyOfficeUserId();
var officeUrl = buildOnlyOfficeOpenUrl({
fileUrl: fileUrl,
fileName: fileName,
fileType: fileType,
assetId: assetId,
documentId: String(asset.document_id || detail.documentId || '').trim(),
userId: userId,
mode: forceEditMode ? 'edit' : 'view'
});
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') {
var didOpen = await window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
objectIdentity: 'resource:onlyoffice:' + String(asset.document_id || detail.documentId || '').trim() + ':' + assetId,
assetId: assetId,
title: fileName,
fileName: fileName,
kind: 'office',
officeUrl: officeUrl,
documentId: String(asset.document_id || detail.documentId || '').trim(),
workspaceId: String(detail.workspaceId || '').trim()
});
if (didOpen) return;
}
window.open(officeUrl, '_blank', 'noopener,noreferrer');
return;
}
if (isCodeAttachmentFileName(fileName) && String(asset.document_id || detail.documentId || '').trim() === currentDocumentId()) {
await openCodeEditorAttachment({
href: fileUrl,
fileUrl: fileUrl,
fileName: fileName,
assetId: assetId,
documentId: String(asset.document_id || detail.documentId || '').trim(),
fileSize: uploadedFileSize(asset)
});
return;
}
window.open(fileUrl, '_blank', 'noopener,noreferrer');
} catch (error) {
window.alert(error && error.message ? error.message : '打开附件失败');
}
}
window.addEventListener('tree.asset.open', function(event) {
void openConvexAssetFromFileTree(event.detail || {});
});
return {
buildLocalFileOpenUrl,
buildLocalOnlyOfficeOpenUrl,
buildMindmapOpenPath,
buildOnlyOfficeOpenPath,
buildOnlyOfficeOpenUrl,
fetchCurrentOnlyOfficeUserId,
inferOnlyOfficeFileType,
isMindmapAssetDetail,
localFilePathFromAssetId,
navigateToMindmapObject,
openConvexAssetFromFileTree,
openLocalOfficeFileInActiveTab,
openLocalResourceInActiveTab,
readFileTreeObjectIdentity,
};
};
@@ -1,5 +1,6 @@
import { createSidebarWorkspaceRuntime } from './sidebar-workspace-runtime.js';
import { createSidebarTreeLiveApplyRuntime } from './sidebar-tree-live-apply-runtime.js';
import { createSidebarFileTreeOpenRuntime } from './sidebar-filetree-open-runtime.js';
(function(){
if (window.__mnoteSidebarTreeRuntimeStarted) return;
@@ -849,393 +850,34 @@ import { createSidebarTreeLiveApplyRuntime } from './sidebar-tree-live-apply-run
window.dispatchEvent(new CustomEvent(name, { detail: detail }));
}
function inferOnlyOfficeFileType(fileName, mimeType) {
var name = String(fileName || '').trim().toLowerCase();
var mt = String(mimeType || '').trim().toLowerCase();
var ext = name.indexOf('.') >= 0 ? name.split('.').pop() : '';
if (['doc', 'docx', 'odt', 'rtf'].indexOf(ext) >= 0) return ext;
if (['ppt', 'pptx', 'odp'].indexOf(ext) >= 0) return ext;
if (['xls', 'xlsx', 'ods', 'csv'].indexOf(ext) >= 0) return ext;
if (isNonOfficeAttachmentName(name, ext)) return '';
if (mt.indexOf('wordprocessingml') >= 0) return 'docx';
if (mt.indexOf('presentationml') >= 0) return 'pptx';
if (mt.indexOf('spreadsheetml') >= 0) return 'xlsx';
return '';
}
function buildOnlyOfficeOpenUrl(input) {
var target = new URL('/onlyoffice', window.location.origin);
var fileUrl = String(input.fileUrl || '').trim();
if (fileUrl) {
try {
fileUrl = new URL(fileUrl, window.location.origin).toString();
} catch (_error) {}
}
target.searchParams.set('fileUrl', fileUrl);
target.searchParams.set('fileName', input.fileName || '未命名资源');
target.searchParams.set('fileType', input.fileType || 'docx');
if (input.assetId) target.searchParams.set('assetId', input.assetId);
if (input.documentId) target.searchParams.set('documentId', input.documentId);
if (input.userId) target.searchParams.set('userId', input.userId);
target.searchParams.set('mode', input.mode || 'view');
return target.toString();
}
function buildOnlyOfficeOpenPath(input) {
var _rto_ = window.__mnoteResourceOpenRuntime;
if (_rto_ && typeof _rto_.buildOnlyOfficeOpenPath === 'function') {
return _rto_.buildOnlyOfficeOpenPath(input);
}
var params = new URLSearchParams();
params.set('fileUrl', input.fileUrl || '');
params.set('fileName', input.fileName || '未命名资源');
params.set('fileType', input.fileType || 'docx');
if (input.assetId) params.set('assetId', input.assetId);
if (input.documentId) params.set('documentId', input.documentId);
if (input.userId) params.set('userId', input.userId);
params.set('mode', input.mode || 'view');
if (input.documentId && input.assetId) {
return '/office/' + encodeURIComponent(input.documentId) + '/' + encodeURIComponent(input.assetId) + '?' + params.toString();
}
return '/onlyoffice?' + params.toString();
}
function buildLocalOnlyOfficeOpenUrl(relativePath, fileName, documentId, assetId, mode) {
var fileType = inferOnlyOfficeFileType(fileName || relativePath || '', '');
if (!fileType) return '';
var fileUrl = buildLocalFileOpenUrl(relativePath, false);
if (!fileUrl) return '';
return buildOnlyOfficeOpenUrl({
fileUrl: fileUrl,
fileName: fileName || relativePath || '未命名资源',
fileType: fileType,
assetId: assetId || ('local-file:' + relativePath),
documentId: documentId || currentDocumentId() || '',
userId: '',
mode: mode || 'view'
});
}
async function openLocalOfficeFileInActiveTab(detail, mode) {
var localFilePath = localFilePathFromAssetId(detail.assetId);
if (!localFilePath) return false;
var localFileName = localFilePath.split('/').pop() || localFilePath;
var localOfficeUrl = buildLocalOnlyOfficeOpenUrl(localFilePath, localFileName, String(detail.documentId || currentDocumentId() || '').trim(), detail.assetId, mode || 'view');
if (!localOfficeUrl) return false;
var opened = await openLocalResourceInActiveTab({
path: localFilePath,
title: detail.fileName || localFileName,
kind: 'office',
assetId: detail.assetId,
documentId: detail.documentId || currentDocumentId() || '',
workspaceId: detail.workspaceId || resolveWorkspaceId(document.body) || '',
href: buildLocalFileOpenUrl(localFilePath, false),
officeUrl: localOfficeUrl,
paneRole: detail.paneRole || 'primary'
});
if (!opened) window.open(localOfficeUrl, '_blank', 'noopener,noreferrer');
return true;
}
function buildMindmapOpenPath(documentId, assetId) {
var doc = String(documentId || '').trim();
var map = String(assetId || '').trim();
if (!doc || !map) return '';
var targetUrl = new URL('/mindmap/' + encodeURIComponent(doc) + '/' + encodeURIComponent(map), window.location.origin);
copyWorkspaceSourceParams(targetUrl);
return targetUrl.pathname + targetUrl.search;
}
function navigateToMindmapObject(documentId, assetId, workspaceId) {
var mindmapPath = buildMindmapOpenPath(documentId, assetId);
if (!mindmapPath) return false;
var targetUrl = new URL(mindmapPath, window.location.origin);
var url = targetUrl.pathname + targetUrl.search;
if (mnoteNavigationInFlight === url) return true;
if (typeof window.__mnoteDocumentPaneRuntime?.openPrimaryMindmap === 'function') {
mnoteNavigationInFlight = url;
document.documentElement.setAttribute('data-mnote-navigation-pending', 'true');
document.documentElement.setAttribute('data-mnote-navigation-target', assetId);
window.__mnoteDocumentPaneRuntime.openPrimaryMindmap({
documentId: documentId,
mindmapId: assetId,
workspaceId: workspaceId || '',
url: targetUrl
}).then(function(){
if (mnoteNavigationInFlight === url) mnoteNavigationInFlight = '';
document.documentElement.removeAttribute('data-mnote-navigation-pending');
}).catch(function(error){
console.warn('mnote mindmap pane 内导航失败,将回退整页导航', error);
if (window.__mnoteTreeLiveEventSource && typeof window.__mnoteTreeLiveEventSource.close === 'function') {
window.__mnoteTreeLiveEventSource.close();
}
window.location.assign(url);
});
return true;
}
mnoteNavigationInFlight = url;
document.documentElement.setAttribute('data-mnote-navigation-pending', 'true');
document.documentElement.setAttribute('data-mnote-navigation-target', assetId);
if (window.__mnoteTreeLiveEventSource && typeof window.__mnoteTreeLiveEventSource.close === 'function') {
window.__mnoteTreeLiveEventSource.close();
}
window.location.assign(url);
return true;
}
function isMindmapAssetDetail(detail) {
var assetId = String(detail && detail.assetId || '').trim();
var assetType = String(detail && detail.assetType || '').trim();
if (assetType === 'mindmap') return true;
var fileName = assetId.indexOf('/') >= 0 ? assetId.split('/').pop() : assetId;
return assetId.indexOf('mindmap_') === 0
|| assetId.indexOf('mindmap-') === 0
|| /\.mindmap\.json$/i.test(fileName)
|| (/^思维导图/i.test(fileName) && /\.json$/i.test(fileName));
}
function localFilePathFromAssetId(assetId) {
var _rto_ = window.__mnoteResourceOpenRuntime;
if (_rto_ && typeof _rto_.localFilePathFromAssetId === 'function') {
return _rto_.localFilePathFromAssetId(assetId);
}
var value = String(assetId || '').trim();
return value.indexOf('local-file:') === 0 ? value.slice('local-file:'.length) : value.indexOf('local:asset:') === 0 ? value.slice('local:asset:'.length) : '';
}
function buildLocalFileOpenUrl(relativePath, download) {
var _rto_ = window.__mnoteResourceOpenRuntime;
if (_rto_ && typeof _rto_.buildLocalFileOpenUrl === 'function') {
return _rto_.buildLocalFileOpenUrl(relativePath, download);
}
var rootUri = currentRootUri();
if (!rootUri || !relativePath) return '';
var url = new URL('/api/local-folder/files/open', window.location.origin);
url.searchParams.set('rootUri', rootUri);
url.searchParams.set('path', relativePath);
if (download) url.searchParams.set('download', 'true');
return url.toString();
}
async function openLocalResourceInActiveTab(input) {
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab !== 'function') return false;
var relativePath = String(input && input.path || '').trim();
var rootUri = String(input && input.rootUri || currentRootUri() || '').trim();
if (!relativePath || !rootUri) return false;
var title = String(input && input.title || '').trim() || relativePath.split('/').pop() || relativePath;
var kind = String(input && input.kind || fileTreeIconKindForFileName(title) || '').trim();
var objectIdentity = 'resource:file:' + rootUri + ':' + relativePath;
return await window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
objectIdentity: objectIdentity,
assetId: String(input && input.assetId || '').trim() || 'local-file:' + relativePath,
title: title,
fileName: title,
kind: kind,
rootUri: rootUri,
path: relativePath,
href: String(input && input.href || buildLocalFileOpenUrl(relativePath, false) || '').trim(),
officeUrl: String(input && input.officeUrl || '').trim(),
documentId: String(input && input.documentId || currentDocumentId() || '').trim(),
workspaceId: String(input && input.workspaceId || resolveWorkspaceId(document.body) || '').trim(),
paneRole: String(input && input.paneRole || 'primary').trim() || 'primary'
});
}
function readFileTreeObjectIdentity(row) {
if (!row) return null;
var raw = row.getAttribute('data-object-identity') || '';
if (!raw) return null;
try {
var parsed = JSON.parse(raw);
return parsed && typeof parsed === 'object' ? parsed : null;
} catch (_error) {
return null;
}
}
async function fetchCurrentOnlyOfficeUserId() {
try {
var response = await fetch('/api/auth/whoami', {
method: 'GET',
credentials: 'include',
cache: 'no-store'
});
var payload = await response.json().catch(function() { return null; });
return String(payload && payload.userId || '').trim();
} catch (_error) {
return '';
}
}
async function openConvexAssetFromFileTree(detail) {
var assetId = String(detail && detail.assetId || '').trim();
if (!assetId) return;
var openTarget = String(detail && detail.openTarget || '').trim().toLowerCase();
var forceNewWindow = openTarget === 'new-window';
var forceEditMode = openTarget === 'edit-mode';
if (openTarget === 'side') {
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceAsSideTarget === 'function') {
var sideLocalFilePath = localFilePathFromAssetId(assetId);
var sideRootUri = String(detail.rootUri || currentRootUri() || '').trim();
var sideFileName = String(detail.title || detail.fileName || (sideLocalFilePath ? sideLocalFilePath.split('/').pop() : '') || assetId || '').trim();
var sideKind = String(detail.iconKind || detail.assetType || fileTreeIconKindForFileName(sideFileName) || 'file').trim();
var sideHref = sideLocalFilePath ? buildLocalFileOpenUrl(sideLocalFilePath, false) : '';
var sideOfficeUrl = sideLocalFilePath ? buildLocalOnlyOfficeOpenUrl(sideLocalFilePath, sideFileName, String(detail.documentId || currentDocumentId() || '').trim(), assetId, 'view') : '';
if (sideOfficeUrl) sideKind = 'office';
void window.__mnoteDocumentPaneRuntime.openResourceAsSideTarget({
objectIdentity: sideLocalFilePath && sideRootUri ? 'resource:file:' + sideRootUri + ':' + sideLocalFilePath : String(detail.objectIdentity || detail.assetId || ''),
assetId: assetId,
title: sideFileName,
fileName: sideFileName,
kind: sideKind,
path: sideLocalFilePath,
rootUri: sideRootUri,
href: sideHref,
officeUrl: sideOfficeUrl,
documentId: String(detail.documentId || currentDocumentId() || ''),
workspaceId: String(detail.workspaceId || resolveWorkspaceId(document.body) || '')
});
}
return;
}
var localFilePath = localFilePathFromAssetId(assetId);
if (localFilePath) {
var localFileName = localFilePath.split('/').pop() || localFilePath;
if (isMindmapAssetDetail(detail) || String(detail && detail.assetType || '').trim() === 'mindmap') {
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') {
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'mindmap-resource-tab');
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId);
void window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
objectIdentity: 'resource:mindmap:' + String(detail && detail.documentId || currentDocumentId() || '').trim() + ':' + assetId,
assetId: assetId,
mindmapId: assetId,
title: String(detail && detail.title || localFileName || '思维导图').trim(),
fileName: localFileName,
kind: 'mindmap',
documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(),
workspaceId: String(detail.workspaceId || '').trim()
});
return;
}
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'local-mindmap-object-shell');
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId);
navigateToMindmapObject(String(detail && detail.documentId || currentDocumentId() || '').trim(), assetId, String(detail.workspaceId || '').trim());
return;
}
var requestedOfficeMode = forceNewWindow || forceEditMode ? 'edit' : 'view';
var localOfficeUrl = buildLocalOnlyOfficeOpenUrl(localFilePath, localFileName, String(detail && detail.documentId || currentDocumentId() || '').trim(), assetId, requestedOfficeMode);
if (localOfficeUrl) {
if (!forceNewWindow && await openLocalResourceInActiveTab({
path: localFilePath,
title: localFileName,
kind: 'office',
assetId: assetId,
documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(),
workspaceId: String(detail.workspaceId || '').trim(),
officeUrl: localOfficeUrl
})) return;
window.open(localOfficeUrl, '_blank', 'noopener,noreferrer');
return;
}
var localFileUrl = buildLocalFileOpenUrl(localFilePath, false);
if (localFileUrl) {
var shouldOpenInNewWindow = forceNewWindow || shouldOpenLocalResourceInNewWindow(localFileName);
if (!shouldOpenInNewWindow && await openLocalResourceInActiveTab({
path: localFilePath,
title: localFileName,
kind: fileTreeIconKindForFileName(localFileName),
assetId: assetId,
documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(),
workspaceId: String(detail.workspaceId || '').trim(),
href: localFileUrl
})) return;
window.open(localFileUrl, '_blank', 'noopener,noreferrer');
}
return;
}
var documentId = String(detail && detail.documentId || '').trim();
if (isMindmapAssetDetail(detail) && documentId) {
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') {
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'mindmap-resource-tab');
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId);
void window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
objectIdentity: 'resource:mindmap:' + documentId + ':' + assetId,
assetId: assetId,
mindmapId: assetId,
title: String(detail.title || '思维导图').trim(),
fileName: String(detail.title || '思维导图').trim(),
kind: 'mindmap',
documentId: documentId,
workspaceId: String(detail.workspaceId || '').trim()
});
return;
}
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-open-mode', 'mindmap-object-shell');
document.documentElement.setAttribute('data-mnote-last-mindmap-asset-id', assetId);
navigateToMindmapObject(documentId, assetId, String(detail.workspaceId || '').trim());
return;
}
try {
var response = await fetch('/api/media/sign?assetId=' + encodeURIComponent(assetId), {
method: 'GET',
credentials: 'include'
});
var payload = await response.json().catch(function() { return null; });
if (!response.ok) {
throw new Error(payload && payload.error ? payload.error : '生成签名链接失败');
}
var asset = payload && payload.asset && typeof payload.asset === 'object' ? payload.asset : {};
var fileUrl = String(payload && payload.signedUrl || asset.file_url || asset.signed_url || '').trim();
if (!fileUrl) throw new Error('附件链接不可用');
var fileName = String(asset.file_name || detail.fileName || '未命名资源').trim() || '未命名资源';
var fileType = inferOnlyOfficeFileType(fileName, asset.mime_type);
if (fileType) {
var userId = await fetchCurrentOnlyOfficeUserId();
var officeUrl = buildOnlyOfficeOpenUrl({
fileUrl: fileUrl,
fileName: fileName,
fileType: fileType,
assetId: assetId,
documentId: String(asset.document_id || detail.documentId || '').trim(),
userId: userId,
mode: forceEditMode ? 'edit' : 'view'
});
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab === 'function') {
var didOpen = await window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
objectIdentity: 'resource:onlyoffice:' + String(asset.document_id || detail.documentId || '').trim() + ':' + assetId,
assetId: assetId,
title: fileName,
fileName: fileName,
kind: 'office',
officeUrl: officeUrl,
documentId: String(asset.document_id || detail.documentId || '').trim(),
workspaceId: String(detail.workspaceId || '').trim()
});
if (didOpen) return;
}
window.open(officeUrl, '_blank', 'noopener,noreferrer');
return;
}
if (isCodeAttachmentFileName(fileName) && String(asset.document_id || detail.documentId || '').trim() === currentDocumentId()) {
await openCodeEditorAttachment({
href: fileUrl,
fileUrl: fileUrl,
fileName: fileName,
assetId: assetId,
documentId: String(asset.document_id || detail.documentId || '').trim(),
fileSize: uploadedFileSize(asset)
});
return;
}
window.open(fileUrl, '_blank', 'noopener,noreferrer');
} catch (error) {
window.alert(error && error.message ? error.message : '打开附件失败');
}
}
window.addEventListener('tree.asset.open', function(event) {
void openConvexAssetFromFileTree(event.detail || {});
const sidebarFileTreeOpen = createSidebarFileTreeOpenRuntime({
copyWorkspaceSourceParams,
currentDocumentId,
currentRootUri,
fileTreeIconKindForFileName: (...args) => fileTreeIconKindForFileName(...args),
getNavigationInFlight: () => mnoteNavigationInFlight,
isCodeAttachmentFileName: (...args) => isCodeAttachmentFileName(...args),
isNonOfficeAttachmentName: (...args) => isNonOfficeAttachmentName(...args),
openCodeEditorAttachment: (...args) => openCodeEditorAttachment(...args),
resolveWorkspaceId,
setNavigationInFlight: (value) => { mnoteNavigationInFlight = String(value || ''); },
shouldOpenLocalResourceInNewWindow: (...args) => shouldOpenLocalResourceInNewWindow(...args),
uploadedFileSize: (...args) => uploadedFileSize(...args),
});
const inferOnlyOfficeFileType = (...args) => sidebarFileTreeOpen.inferOnlyOfficeFileType(...args);
const buildOnlyOfficeOpenUrl = (...args) => sidebarFileTreeOpen.buildOnlyOfficeOpenUrl(...args);
const buildOnlyOfficeOpenPath = (...args) => sidebarFileTreeOpen.buildOnlyOfficeOpenPath(...args);
const buildLocalOnlyOfficeOpenUrl = (...args) => sidebarFileTreeOpen.buildLocalOnlyOfficeOpenUrl(...args);
const openLocalOfficeFileInActiveTab = (...args) => sidebarFileTreeOpen.openLocalOfficeFileInActiveTab(...args);
const buildMindmapOpenPath = (...args) => sidebarFileTreeOpen.buildMindmapOpenPath(...args);
const navigateToMindmapObject = (...args) => sidebarFileTreeOpen.navigateToMindmapObject(...args);
const isMindmapAssetDetail = (...args) => sidebarFileTreeOpen.isMindmapAssetDetail(...args);
const localFilePathFromAssetId = (...args) => sidebarFileTreeOpen.localFilePathFromAssetId(...args);
const buildLocalFileOpenUrl = (...args) => sidebarFileTreeOpen.buildLocalFileOpenUrl(...args);
const openLocalResourceInActiveTab = (...args) => sidebarFileTreeOpen.openLocalResourceInActiveTab(...args);
const readFileTreeObjectIdentity = (...args) => sidebarFileTreeOpen.readFileTreeObjectIdentity(...args);
const fetchCurrentOnlyOfficeUserId = (...args) => sidebarFileTreeOpen.fetchCurrentOnlyOfficeUserId(...args);
const openConvexAssetFromFileTree = (...args) => sidebarFileTreeOpen.openConvexAssetFromFileTree(...args);
function fileTreeRowsForUploadPreflight() {
var runtimeFn = fileTreeRuntimeFunction('fileTreeRowsForUploadPreflight');
+5
View File
@@ -134,6 +134,10 @@ pub fn build_router(state: AppState) -> Router {
"/api/mnote-browser-runtime/sidebar-tree-live-apply-runtime.js",
get(web_shell::sidebar_tree_live_apply_runtime_asset),
)
.route(
"/api/mnote-browser-runtime/sidebar-filetree-open-runtime.js",
get(web_shell::sidebar_filetree_open_runtime_asset),
)
.route(
"/api/mnote-browser-runtime/sidebar-tree-runtime.js",
get(web_shell::sidebar_tree_runtime_asset),
@@ -589,6 +593,7 @@ mod tests {
"/api/mnote-browser-runtime/sidebar-shell-runtime.js",
"/api/mnote-browser-runtime/sidebar-workspace-runtime.js",
"/api/mnote-browser-runtime/sidebar-tree-live-apply-runtime.js",
"/api/mnote-browser-runtime/sidebar-filetree-open-runtime.js",
"/api/mnote-browser-runtime/sidebar-tree-runtime.js",
"/api/mnote-browser-runtime/tree-live-controller.js",
"/api/mnote-browser-runtime/tree-shell-runtime.js",
@@ -770,6 +770,20 @@ pub async fn sidebar_tree_live_apply_runtime_asset() -> Response {
.unwrap_or_else(|_| Response::new(Body::empty()))
}
pub async fn sidebar_filetree_open_runtime_asset() -> Response {
const JS: &str = include_str!("../../browser/sidebar-filetree-open-runtime.js");
Response::builder()
.status(StatusCode::OK)
.header(
header::CONTENT_TYPE,
"application/javascript; charset=utf-8",
)
.header(header::CACHE_CONTROL, "no-store")
.header(HEADER_MNOTE_WEB_OWNER, "mnote-web")
.body(Body::from(JS))
.unwrap_or_else(|_| Response::new(Body::empty()))
}
pub async fn filetree_keyboard_runtime_asset() -> Response {
const JS: &str = include_str!("../../browser/filetree-keyboard-runtime.js");
Response::builder()
+38 -28
View File
@@ -201,6 +201,8 @@ mod tests {
const SIDEBAR_TREE_RUNTIME_JS: &str = include_str!("../../../browser/sidebar-tree-runtime.js");
const SIDEBAR_TREE_LIVE_APPLY_RUNTIME_JS: &str =
include_str!("../../../browser/sidebar-tree-live-apply-runtime.js");
const SIDEBAR_FILETREE_OPEN_RUNTIME_JS: &str =
include_str!("../../../browser/sidebar-filetree-open-runtime.js");
const SIDEBAR_SHELL_RUNTIME_JS: &str =
include_str!("../../../browser/sidebar-shell-runtime.js");
const SIDEBAR_WORKSPACE_RUNTIME_JS: &str =
@@ -279,29 +281,33 @@ mod tests {
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("openConvexAssetFromFileTree"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("buildMindmapOpenPath"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("isMindmapAssetDetail"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("^思维导图"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("^思维导图"));
assert!(!SIDEBAR_TREE_RUNTIME_JS.contains("openMindmapAssetInDocumentShell"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("data-mnote-last-mindmap-asset-open-mode"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("mindmap-object-shell"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("navigateToMindmapObject(documentId, assetId"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("__mnoteDocumentPaneRuntime?.openPrimaryMindmap"));
assert!(
SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("data-mnote-last-mindmap-asset-open-mode")
);
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("mindmap-object-shell"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS
.contains("navigateToMindmapObject(documentId, assetId"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS
.contains("__mnoteDocumentPaneRuntime?.openPrimaryMindmap"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("shortMindmapFileName"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("assetType: assetType || null"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("data-object-identity"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("readFileTreeObjectIdentity"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("objectIdentity: objectIdentity"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("workspaceId: resolveWorkspaceId(fileRow)"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("/api/media/sign?assetId="));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function localFilePathFromAssetId"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("/api/local-folder/files/open"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("local-file:"));
assert!(SIDEBAR_TREE_RUNTIME_JS
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("/api/media/sign?assetId="));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("function localFilePathFromAssetId"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("/api/local-folder/files/open"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("local-file:"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS
.contains("value.indexOf('local:asset:') === 0 ? value.slice('local:asset:'.length)"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("fetchCurrentOnlyOfficeUserId"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("/api/auth/whoami"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("/api/auth/whoami"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("buildOnlyOfficeOpenUrl"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("target.searchParams.set('userId'"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("window.open(officeUrl,"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("target.searchParams.set('userId'"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("window.open(officeUrl,"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("tree.filetree.internal-drop"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("tree.filetree.external-drop"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("beginFileTreeInlineRename"));
@@ -805,7 +811,7 @@ mod tests {
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("url.searchParams.set('rootUri', rootUri)"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("if (!parentRow && currentSourceKind() === 'local_folder' && objectKind === 'mindmap') return false;"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("if (!appended && currentSourceKind() === 'local_folder') void refreshLocalFolderSidebarSnapshot();"));
assert!(SIDEBAR_TREE_RUNTIME_JS
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS
.contains("data-mnote-last-mindmap-asset-open-mode', 'local-mindmap-object-shell'"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("buildLocalOnlyOfficeOpenUrl"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("isLocalAsset ? onlyOfficeUrl"));
@@ -858,8 +864,8 @@ mod tests {
assert!(SIDEBAR_TREE_RUNTIME_JS
.contains("function shouldOpenLocalResourceInNewWindow(fileName)"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("return false;"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("var shouldOpenInNewWindow = forceNewWindow || shouldOpenLocalResourceInNewWindow(localFileName);"));
assert!(SIDEBAR_TREE_RUNTIME_JS
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("var shouldOpenInNewWindow = forceNewWindow || shouldOpenLocalResourceInNewWindow(localFileName);"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS
.contains("if (!shouldOpenInNewWindow && await openLocalResourceInActiveTab({"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains(
"openTarget: e.shiftKey || e.ctrlKey || e.metaKey ? 'new-window' : 'active-tab'"
@@ -1099,10 +1105,10 @@ mod tests {
#[test]
fn sidebar_tree_runtime_keeps_pdf_and_code_assets_out_of_onlyoffice() {
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function inferOnlyOfficeFileType"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("isNonOfficeAttachmentName(name, ext)"));
assert!(!SIDEBAR_TREE_RUNTIME_JS.contains("if (ext === 'pdf') return ext;"));
assert!(!SIDEBAR_TREE_RUNTIME_JS.contains("mt.indexOf('pdf') >= 0"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("function inferOnlyOfficeFileType"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("isNonOfficeAttachmentName(name, ext)"));
assert!(!SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("if (ext === 'pdf') return ext;"));
assert!(!SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("mt.indexOf('pdf') >= 0"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("mnote-uploaded-attachment-pdf"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("mnote-uploaded-attachment-code"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("'toml'"));
@@ -1118,14 +1124,18 @@ mod tests {
#[test]
fn sidebar_tree_runtime_opens_office_assets_through_resource_shell() {
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("function buildOnlyOfficeOpenPath"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains(
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("function buildOnlyOfficeOpenPath"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains(
"return '/office/' + encodeURIComponent(input.documentId) + '/' + encodeURIComponent(input.assetId)"
));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("return '/onlyoffice?' + params.toString();"));
assert!(SIDEBAR_TREE_RUNTIME_JS
assert!(
SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("return '/onlyoffice?' + params.toString();")
);
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS
.contains("target.searchParams.set('mode', input.mode || 'view');"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("params.set('mode', input.mode || 'view');"));
assert!(
SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("params.set('mode', input.mode || 'view');")
);
assert!(SIDEBAR_TREE_RUNTIME_JS.contains(
"{ action: 'open-edit-mode', icon: 'edit_note', label: '使用编辑模式打开' }"
));
@@ -1139,7 +1149,7 @@ mod tests {
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("void openEditorAttachmentEditTab(detail);"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("openLocalOfficeFileInActiveTab(detail, 'edit')"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("openEditorAttachmentNewWindow(detail, 'edit')"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("forceEditMode ? 'edit' : 'view'"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("forceEditMode ? 'edit' : 'view'"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("url.searchParams.set('mode', requestedMode);"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("mode: requestedMode"));
}
@@ -1158,9 +1168,9 @@ mod tests {
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("inferCodeAttachmentLanguage"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("if (isPdfAttachmentFileName(detail.fileName))"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("if (isCodeAttachmentFileName(detail.fileName))"));
assert!(SIDEBAR_TREE_RUNTIME_JS
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS
.contains("if (isCodeAttachmentFileName(fileName) && String(asset.document_id"));
assert!(SIDEBAR_TREE_RUNTIME_JS.contains("await openCodeEditorAttachment({"));
assert!(SIDEBAR_FILETREE_OPEN_RUNTIME_JS.contains("await openCodeEditorAttachment({"));
}
#[test]