Complete workbench P0 resource tab cutover
This commit is contained in:
@@ -3184,6 +3184,19 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
|
||||
return 'file';
|
||||
};
|
||||
|
||||
const resolveResourceOpen = (input = {}) => {
|
||||
const kind = normalizeResourceTabKind(input);
|
||||
const badgeKind = resourceTabBadgeKind(input, kind);
|
||||
const rawTarget = String(input?.openTarget || '').trim().toLowerCase();
|
||||
const openTarget = rawTarget === 'new-window' || rawTarget === 'side' ? rawTarget : 'active-tab';
|
||||
const editable = kind === 'markdown' || kind === 'text' || kind === 'code';
|
||||
const defaultOpenMode = kind === 'office' && openTarget === 'active-tab' ? 'active-tab-iframe' : openTarget;
|
||||
const viewerUrl = kind === 'office'
|
||||
? String(input?.officeUrl || input?.href || '').trim()
|
||||
: String(input?.href || '').trim();
|
||||
return { editorKind: kind, badgeKind, defaultOpenMode, editable, viewerUrl, openTarget };
|
||||
};
|
||||
|
||||
const touchResourceTabMru = (key) => {
|
||||
const id = String(key || '').trim();
|
||||
if (!id) return;
|
||||
@@ -3193,6 +3206,11 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
|
||||
if (resourceTabMru.length > resourceTabMruMax) resourceTabMru.length = resourceTabMruMax;
|
||||
};
|
||||
|
||||
const setResourceTabLastActive = (key) => {
|
||||
const entry = resourceTabRegistry.get(String(key || '').trim());
|
||||
if (entry?.session) entry.session.lastActiveAt = Date.now();
|
||||
};
|
||||
|
||||
const removeFromResourceTabMru = (key) => {
|
||||
const index = resourceTabMru.indexOf(key);
|
||||
if (index >= 0) resourceTabMru.splice(index, 1);
|
||||
@@ -3239,7 +3257,10 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
|
||||
const activateMainEditorTab = (objectIdentity) => {
|
||||
const nodes = resourceTabHostNodes();
|
||||
const activeResource = String(objectIdentity || '').trim();
|
||||
if (activeResource) touchResourceTabMru(activeResource);
|
||||
if (activeResource) {
|
||||
touchResourceTabMru(activeResource);
|
||||
setResourceTabLastActive(activeResource);
|
||||
}
|
||||
if (nodes.pageTab instanceof HTMLElement) {
|
||||
const activePage = !activeResource;
|
||||
nodes.pageTab.classList.toggle('is-active', activePage);
|
||||
@@ -3289,6 +3310,20 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
|
||||
activateMainEditorTab(lastActiveResourceTabKey());
|
||||
};
|
||||
|
||||
const markResourceTabError = (entry) => {
|
||||
if (!entry) return;
|
||||
entry.kind = 'error';
|
||||
if (entry.tab instanceof HTMLElement) {
|
||||
entry.tab.setAttribute('data-mnote-tab-kind', 'error');
|
||||
entry.tab.setAttribute('data-mnote-tab-badge-kind', 'file');
|
||||
entry.tab.classList.add('is-error');
|
||||
}
|
||||
if (entry.panel instanceof HTMLElement) {
|
||||
entry.panel.setAttribute('data-resource-kind', 'error');
|
||||
entry.panel.innerHTML = '<div class="mnote-resource-tab-error" data-resource-tab-error="true"><div class="mnote-resource-tab-error-inner"><h1>资源打开失败</h1><p>无法加载此资源,请检查文件路径和访问权限。</p></div></div>';
|
||||
}
|
||||
};
|
||||
|
||||
const createResourceTabDom = (input) => {
|
||||
const nodes = resourceTabHostNodes();
|
||||
if (!(nodes.strip instanceof HTMLElement) || !(nodes.panelRoot instanceof HTMLElement)) return null;
|
||||
@@ -3356,6 +3391,7 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
|
||||
fileVersion: conflictDetectionKey,
|
||||
lastExternalConflictDetectionKey: conflictDetectionKey,
|
||||
readOnly: false,
|
||||
lastActiveAt: 0,
|
||||
dirty: false,
|
||||
saving: false,
|
||||
hasExternalConflict: false,
|
||||
@@ -3464,7 +3500,7 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.warn('mnote resource tab 打开失败', error);
|
||||
entry.panel.innerHTML = '<div class="mnote-resource-tab-text-shell" data-resource-tab-error="true">资源打开失败</div>';
|
||||
markResourceTabError(entry);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -3530,6 +3566,7 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
|
||||
if (url instanceof URL) replaceUrlState(url);
|
||||
return true;
|
||||
},
|
||||
resolveResourceOpen: (input) => resolveResourceOpen(input),
|
||||
openResourceInActiveTab: openResourceInActiveTab,
|
||||
closeSecondaryDocument: ({ url } = {}) => {
|
||||
closeSecondaryPane(url instanceof URL ? url : currentUrl());
|
||||
@@ -4246,6 +4283,15 @@ mod tests {
|
||||
"const tiptapDocument = pageBodyTiptapDocument(pageBody, '', runtimeDescriptor.bootstrap);"
|
||||
));
|
||||
assert!(!html.contains("mnote-web-document-shell"));
|
||||
|
||||
// Resource open resolver contract
|
||||
assert!(html.contains("normalizeResourceTabKind"));
|
||||
assert!(html.contains("data-resource-tab-error"));
|
||||
assert!(html.contains("resourceTabCloseGuardReason"));
|
||||
assert!(html.contains("closeResourceTab"));
|
||||
assert!(html.contains("resourceTabRegistry.delete(key)"));
|
||||
assert!(html.contains("activateMainEditorTab(lastActiveResourceTabKey())"));
|
||||
assert!(html.contains("resourceTabBadgeKind(input, kind)"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user