refactor: extract conflict diff panel runtime
This commit is contained in:
@@ -81,7 +81,94 @@ function createSessionConflictPanel(session, message, deps) {
|
||||
return panel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在已有 diffPanel 中填充 current/disk/merge DOM 并绑定回调。
|
||||
* 不处理 fetch、persist、status 等业务逻辑。
|
||||
* @param {HTMLElement} panel - 已清空的 diffPanel 元素
|
||||
* @param {Object} context
|
||||
* @param {string} context.currentText - 当前编辑器的文本(含占位文案)
|
||||
* @param {string} context.diskText - 磁盘版本的文本(含占位文案)
|
||||
* @param {string} [context.currentMergeText] - 写入合并区域的当前编辑器原始文本
|
||||
* @param {string} [context.diskMergeText] - 写入合并区域的磁盘版本原始文本
|
||||
* @param {string} [context.mergeDefaultText] - 合并区域默认文本
|
||||
* @param {Object} deps
|
||||
* @param {Function} [deps.onUseCurrent] - 可选:返回当前版本写入合并区域的文本
|
||||
* @param {Function} [deps.onUseDisk] - 可选:返回磁盘版本写入合并区域的文本
|
||||
* @param {Function} deps.onSaveMerge - 保存合并结果回调,接收合并文本字符串
|
||||
*/
|
||||
function populateSessionConflictDiffPanel(panel, context, deps) {
|
||||
context = context || {};
|
||||
deps = deps || {};
|
||||
var currentText = context.currentText || '';
|
||||
var diskText = context.diskText || '';
|
||||
var currentMergeText = Object.prototype.hasOwnProperty.call(context, 'currentMergeText')
|
||||
? String(context.currentMergeText || '')
|
||||
: currentText;
|
||||
var diskMergeText = Object.prototype.hasOwnProperty.call(context, 'diskMergeText')
|
||||
? String(context.diskMergeText || '')
|
||||
: diskText;
|
||||
var mergeDefaultText = context.mergeDefaultText || currentText || diskText || '';
|
||||
|
||||
var current = document.createElement('pre');
|
||||
current.setAttribute('data-testid', 'mnote-conflict-current-text');
|
||||
current.textContent = currentText;
|
||||
var disk = document.createElement('pre');
|
||||
disk.setAttribute('data-testid', 'mnote-conflict-disk-text');
|
||||
disk.textContent = diskText;
|
||||
var currentTitle = document.createElement('h3');
|
||||
currentTitle.textContent = '当前编辑器版本';
|
||||
var diskTitle = document.createElement('h3');
|
||||
diskTitle.textContent = '磁盘版本';
|
||||
var currentBox = document.createElement('section');
|
||||
currentBox.append(currentTitle, current);
|
||||
var diskBox = document.createElement('section');
|
||||
diskBox.append(diskTitle, disk);
|
||||
var mergeTitle = document.createElement('h3');
|
||||
mergeTitle.textContent = '合并结果';
|
||||
var mergeText = document.createElement('textarea');
|
||||
mergeText.setAttribute('data-testid', 'mnote-conflict-merge-text');
|
||||
mergeText.value = mergeDefaultText;
|
||||
var mergeActions = document.createElement('div');
|
||||
mergeActions.className = 'mnote-conflict-actions';
|
||||
var useCurrent = document.createElement('button');
|
||||
useCurrent.type = 'button';
|
||||
useCurrent.textContent = '使用当前版本';
|
||||
useCurrent.setAttribute('data-testid', 'mnote-conflict-merge-use-current');
|
||||
var useDisk = document.createElement('button');
|
||||
useDisk.type = 'button';
|
||||
useDisk.textContent = '使用磁盘版本';
|
||||
useDisk.setAttribute('data-testid', 'mnote-conflict-merge-use-disk');
|
||||
var saveMerge = document.createElement('button');
|
||||
saveMerge.type = 'button';
|
||||
saveMerge.textContent = '写回合并结果';
|
||||
saveMerge.setAttribute('data-testid', 'mnote-conflict-merge-save');
|
||||
mergeActions.append(useCurrent, useDisk, saveMerge);
|
||||
var mergeBox = document.createElement('section');
|
||||
mergeBox.className = 'mnote-conflict-merge-box';
|
||||
mergeBox.append(mergeTitle, mergeText, mergeActions);
|
||||
panel.append(currentBox, diskBox, mergeBox);
|
||||
|
||||
useCurrent.addEventListener('click', function() {
|
||||
var nextText = typeof deps.onUseCurrent === 'function'
|
||||
? deps.onUseCurrent(context)
|
||||
: currentMergeText;
|
||||
mergeText.value = typeof nextText === 'string' ? nextText : currentMergeText;
|
||||
});
|
||||
useDisk.addEventListener('click', function() {
|
||||
var nextText = typeof deps.onUseDisk === 'function'
|
||||
? deps.onUseDisk(context)
|
||||
: diskMergeText;
|
||||
mergeText.value = typeof nextText === 'string' ? nextText : diskMergeText;
|
||||
});
|
||||
saveMerge.addEventListener('click', function() {
|
||||
if (typeof deps.onSaveMerge === 'function') {
|
||||
deps.onSaveMerge(mergeText.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.__mnoteDocumentConflictPanelRuntime = {
|
||||
clearSessionConflictSurface: clearSessionConflictSurface,
|
||||
createSessionConflictPanel: createSessionConflictPanel
|
||||
createSessionConflictPanel: createSessionConflictPanel,
|
||||
populateSessionConflictDiffPanel: populateSessionConflictDiffPanel
|
||||
};
|
||||
|
||||
@@ -1978,56 +1978,80 @@ pub(crate) fn render_editor_island_adapter_script() -> &'static str {
|
||||
? resourceSnapshotPlainText(latest)
|
||||
: aggregatePlainText(latest);
|
||||
diffPanel.replaceChildren();
|
||||
const current = document.createElement('pre');
|
||||
current.setAttribute('data-testid', 'mnote-conflict-current-text');
|
||||
current.textContent = sessionPlainText(session) || '(当前编辑器为空)';
|
||||
const disk = document.createElement('pre');
|
||||
disk.setAttribute('data-testid', 'mnote-conflict-disk-text');
|
||||
disk.textContent = latestText || '(磁盘版本为空)';
|
||||
const currentTitle = document.createElement('h3');
|
||||
currentTitle.textContent = '当前编辑器版本';
|
||||
const diskTitle = document.createElement('h3');
|
||||
diskTitle.textContent = '磁盘版本';
|
||||
const currentBox = document.createElement('section');
|
||||
currentBox.append(currentTitle, current);
|
||||
const diskBox = document.createElement('section');
|
||||
diskBox.append(diskTitle, disk);
|
||||
const mergeTitle = document.createElement('h3');
|
||||
mergeTitle.textContent = '合并结果';
|
||||
const mergeText = document.createElement('textarea');
|
||||
mergeText.setAttribute('data-testid', 'mnote-conflict-merge-text');
|
||||
mergeText.value = sessionPlainText(session) || latestText || '';
|
||||
const mergeActions = document.createElement('div');
|
||||
mergeActions.className = 'mnote-conflict-actions';
|
||||
const useCurrent = document.createElement('button');
|
||||
useCurrent.type = 'button';
|
||||
useCurrent.textContent = '使用当前版本';
|
||||
useCurrent.setAttribute('data-testid', 'mnote-conflict-merge-use-current');
|
||||
const useDisk = document.createElement('button');
|
||||
useDisk.type = 'button';
|
||||
useDisk.textContent = '使用磁盘版本';
|
||||
useDisk.setAttribute('data-testid', 'mnote-conflict-merge-use-disk');
|
||||
const saveMerge = document.createElement('button');
|
||||
saveMerge.type = 'button';
|
||||
saveMerge.textContent = '写回合并结果';
|
||||
saveMerge.setAttribute('data-testid', 'mnote-conflict-merge-save');
|
||||
mergeActions.append(useCurrent, useDisk, saveMerge);
|
||||
const mergeBox = document.createElement('section');
|
||||
mergeBox.className = 'mnote-conflict-merge-box';
|
||||
mergeBox.append(mergeTitle, mergeText, mergeActions);
|
||||
diffPanel.append(currentBox, diskBox, mergeBox);
|
||||
useCurrent.addEventListener('click', () => {
|
||||
mergeText.value = sessionPlainText(session) || '';
|
||||
});
|
||||
useDisk.addEventListener('click', () => {
|
||||
mergeText.value = latestText || '';
|
||||
});
|
||||
saveMerge.addEventListener('click', () => {
|
||||
writeMergedConflictResult(session, panel, mergeText.value).catch((error) => {
|
||||
setSessionStatus(session, 'external-change-conflict', error instanceof Error ? error.message : String(error));
|
||||
renderSessionConflictSurface(session, error instanceof Error ? error.message : String(error));
|
||||
var _dpRT_ = window.__mnoteDocumentConflictPanelRuntime;
|
||||
if (_dpRT_ && typeof _dpRT_.populateSessionConflictDiffPanel === 'function') {
|
||||
_dpRT_.populateSessionConflictDiffPanel(diffPanel, {
|
||||
currentText: sessionPlainText(session) || '(当前编辑器为空)',
|
||||
diskText: latestText || '(磁盘版本为空)',
|
||||
currentMergeText: sessionPlainText(session) || '',
|
||||
diskMergeText: latestText || '',
|
||||
mergeDefaultText: sessionPlainText(session) || latestText || '',
|
||||
}, {
|
||||
onUseCurrent: function() {
|
||||
return sessionPlainText(session) || '';
|
||||
},
|
||||
onUseDisk: function() {
|
||||
return latestText || '';
|
||||
},
|
||||
onSaveMerge: function(mergeText) {
|
||||
writeMergedConflictResult(session, panel, mergeText).catch((error) => {
|
||||
setSessionStatus(session, 'external-change-conflict', error instanceof Error ? error.message : String(error));
|
||||
renderSessionConflictSurface(session, error instanceof Error ? error.message : String(error));
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const current = document.createElement('pre');
|
||||
current.setAttribute('data-testid', 'mnote-conflict-current-text');
|
||||
current.textContent = sessionPlainText(session) || '(当前编辑器为空)';
|
||||
const disk = document.createElement('pre');
|
||||
disk.setAttribute('data-testid', 'mnote-conflict-disk-text');
|
||||
disk.textContent = latestText || '(磁盘版本为空)';
|
||||
const currentTitle = document.createElement('h3');
|
||||
currentTitle.textContent = '当前编辑器版本';
|
||||
const diskTitle = document.createElement('h3');
|
||||
diskTitle.textContent = '磁盘版本';
|
||||
const currentBox = document.createElement('section');
|
||||
currentBox.append(currentTitle, current);
|
||||
const diskBox = document.createElement('section');
|
||||
diskBox.append(diskTitle, disk);
|
||||
const mergeTitle = document.createElement('h3');
|
||||
mergeTitle.textContent = '合并结果';
|
||||
const mergeText = document.createElement('textarea');
|
||||
mergeText.setAttribute('data-testid', 'mnote-conflict-merge-text');
|
||||
mergeText.value = sessionPlainText(session) || latestText || '';
|
||||
const mergeActions = document.createElement('div');
|
||||
mergeActions.className = 'mnote-conflict-actions';
|
||||
const useCurrent = document.createElement('button');
|
||||
useCurrent.type = 'button';
|
||||
useCurrent.textContent = '使用当前版本';
|
||||
useCurrent.setAttribute('data-testid', 'mnote-conflict-merge-use-current');
|
||||
const useDisk = document.createElement('button');
|
||||
useDisk.type = 'button';
|
||||
useDisk.textContent = '使用磁盘版本';
|
||||
useDisk.setAttribute('data-testid', 'mnote-conflict-merge-use-disk');
|
||||
const saveMerge = document.createElement('button');
|
||||
saveMerge.type = 'button';
|
||||
saveMerge.textContent = '写回合并结果';
|
||||
saveMerge.setAttribute('data-testid', 'mnote-conflict-merge-save');
|
||||
mergeActions.append(useCurrent, useDisk, saveMerge);
|
||||
const mergeBox = document.createElement('section');
|
||||
mergeBox.className = 'mnote-conflict-merge-box';
|
||||
mergeBox.append(mergeTitle, mergeText, mergeActions);
|
||||
diffPanel.append(currentBox, diskBox, mergeBox);
|
||||
useCurrent.addEventListener('click', () => {
|
||||
mergeText.value = sessionPlainText(session) || '';
|
||||
});
|
||||
useDisk.addEventListener('click', () => {
|
||||
mergeText.value = latestText || '';
|
||||
});
|
||||
saveMerge.addEventListener('click', () => {
|
||||
writeMergedConflictResult(session, panel, mergeText.value).catch((error) => {
|
||||
setSessionStatus(session, 'external-change-conflict', error instanceof Error ? error.message : String(error));
|
||||
renderSessionConflictSurface(session, error instanceof Error ? error.message : String(error));
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
loading.textContent = error instanceof Error ? error.message : String(error);
|
||||
diffPanel.replaceChildren(loading);
|
||||
@@ -5620,6 +5644,21 @@ mod tests {
|
||||
assert!(DOCUMENT_CONFLICT_PANEL_RUNTIME_JS.contains("onAcceptDisk"));
|
||||
assert!(DOCUMENT_CONFLICT_PANEL_RUNTIME_JS.contains("onKeepCurrent"));
|
||||
assert!(DOCUMENT_CONFLICT_PANEL_RUNTIME_JS.contains("onOpenDiff"));
|
||||
assert!(DOCUMENT_CONFLICT_PANEL_RUNTIME_JS
|
||||
.contains("function populateSessionConflictDiffPanel"));
|
||||
assert!(DOCUMENT_CONFLICT_PANEL_RUNTIME_JS
|
||||
.contains("data-testid', 'mnote-conflict-current-text"));
|
||||
assert!(
|
||||
DOCUMENT_CONFLICT_PANEL_RUNTIME_JS.contains("data-testid', 'mnote-conflict-disk-text")
|
||||
);
|
||||
assert!(DOCUMENT_CONFLICT_PANEL_RUNTIME_JS
|
||||
.contains("data-testid', 'mnote-conflict-merge-use-current"));
|
||||
assert!(DOCUMENT_CONFLICT_PANEL_RUNTIME_JS
|
||||
.contains("data-testid', 'mnote-conflict-merge-use-disk"));
|
||||
assert!(DOCUMENT_CONFLICT_PANEL_RUNTIME_JS.contains("currentMergeText"));
|
||||
assert!(DOCUMENT_CONFLICT_PANEL_RUNTIME_JS.contains("onUseCurrent"));
|
||||
assert!(DOCUMENT_CONFLICT_PANEL_RUNTIME_JS.contains("onUseDisk"));
|
||||
assert!(DOCUMENT_CONFLICT_PANEL_RUNTIME_JS.contains("onSaveMerge"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user