Update table-bindings.js

This commit is contained in:
2025-10-06 03:23:35 +08:00
committed by GitHub
parent ca67e9b295
commit b13f7eaff6

View File

@@ -15,6 +15,8 @@ import { fetchNccsModels, testNccsApiConnection } from '../core/api/NccsApi.js';
const isTouchDevice = () => window.matchMedia('(pointer: coarse)').matches;
const getAllTablesContainer = () => document.getElementById('all-tables-container');
let isResizing = false;
function toggleRowContextMenu(event) {
event.preventDefault();
@@ -23,63 +25,104 @@ function toggleRowContextMenu(event) {
const targetTd = event.target.closest('td.index-col');
if (!targetTd) return;
const menu = targetTd.querySelector('.amily2-context-menu');
if (!menu) return;
const tableWrapper = targetTd.closest('.amily2-table-wrapper');
if (!tableWrapper) return;
const isActive = menu.classList.contains('amily2-menu-active');
document.querySelectorAll('.amily2-context-menu.amily2-menu-active').forEach(activeMenu => {
activeMenu.classList.remove('amily2-menu-active');
const isActive = targetTd.classList.contains('amily2-menu-open');
document.querySelectorAll('.amily2-menu-open').forEach(openEl => {
if (openEl !== targetTd) {
openEl.classList.remove('amily2-menu-open');
const otherWrapper = openEl.closest('.amily2-table-wrapper');
if (otherWrapper) {
otherWrapper.style.overflowX = 'auto';
otherWrapper.style.zIndex = '';
otherWrapper.style.position = '';
}
}
});
if (!isActive) {
menu.classList.add('amily2-menu-active');
targetTd.classList.toggle('amily2-menu-open');
if (targetTd.classList.contains('amily2-menu-open')) {
tableWrapper.style.overflowX = 'visible';
tableWrapper.style.position = 'relative';
tableWrapper.style.zIndex = '10';
} else {
tableWrapper.style.overflowX = 'auto';
tableWrapper.style.position = '';
tableWrapper.style.zIndex = '';
}
const closeMenu = (e) => {
if (!menu.contains(e.target)) {
menu.classList.remove('amily2-menu-active');
if (!targetTd.contains(e.target)) {
targetTd.classList.remove('amily2-menu-open');
tableWrapper.style.overflowX = 'auto';
tableWrapper.style.position = '';
tableWrapper.style.zIndex = '';
document.removeEventListener('click', closeMenu, true);
}
};
if (targetTd.classList.contains('amily2-menu-open')) {
setTimeout(() => {
if (menu.classList.contains('amily2-menu-active')) {
document.addEventListener('click', closeMenu, true);
}
}, 0);
}
}
function toggleColumnContextMenu(event) {
if (isResizing || event.target.classList.contains('amily2-resizer')) {
return;
}
event.preventDefault();
event.stopPropagation();
const targetTh = event.target.closest('th');
if (!targetTh) return;
const isActive = targetTh.classList.contains('amily2-menu-open');
const tableWrapper = targetTh.closest('.amily2-table-wrapper');
if (!tableWrapper) return;
const isActive = targetTh.classList.contains('amily2-menu-open');
document.querySelectorAll('th.amily2-menu-open').forEach(openTh => {
if (openTh !== targetTh) {
openTh.classList.remove('amily2-menu-open');
const otherWrapper = openTh.closest('.amily2-table-wrapper');
if (otherWrapper) {
otherWrapper.style.overflowX = 'auto';
otherWrapper.style.zIndex = '';
otherWrapper.style.position = '';
}
}
});
if (!isActive) {
targetTh.classList.add('amily2-menu-open');
targetTh.classList.toggle('amily2-menu-open');
if (targetTh.classList.contains('amily2-menu-open')) {
tableWrapper.style.overflowX = 'visible';
tableWrapper.style.position = 'relative';
tableWrapper.style.zIndex = '10';
} else {
tableWrapper.style.overflowX = 'auto';
tableWrapper.style.position = '';
tableWrapper.style.zIndex = '';
}
const closeMenu = (e) => {
if (!targetTh.contains(e.target)) {
targetTh.classList.remove('amily2-menu-open');
tableWrapper.style.overflowX = 'auto';
tableWrapper.style.position = '';
tableWrapper.style.zIndex = '';
document.removeEventListener('click', closeMenu, true);
}
};
setTimeout(() => {
// If the menu was opened, set up the listener to close it
if (targetTh.classList.contains('amily2-menu-open')) {
setTimeout(() => {
document.addEventListener('click', closeMenu, true);
}
}, 0);
}
}
@@ -297,12 +340,34 @@ export function renderTables() {
header.appendChild(controls);
container.appendChild(header);
const tableWrapper = document.createElement('div');
tableWrapper.className = 'amily2-table-wrapper';
const tableElement = document.createElement('table');
tableElement.style.display = 'block';
tableElement.style.overflowX = 'auto';
tableElement.id = `amily2-table-${tableIndex}`;
tableElement.dataset.tableIndex = tableIndex;
const colgroup = document.createElement('colgroup');
const indexCol = document.createElement('col');
indexCol.style.width = '40px';
colgroup.appendChild(indexCol);
if (tableData.headers) {
tableData.headers.forEach((_, colIndex) => {
const col = document.createElement('col');
const colWidth = (tableData.columnWidths && tableData.columnWidths[colIndex]) ? tableData.columnWidths[colIndex] : 90;
col.style.width = `${colWidth}px`;
colgroup.appendChild(col);
});
}
tableElement.appendChild(colgroup);
let totalWidth = 0;
const cols = colgroup.querySelectorAll('col');
cols.forEach(col => {
totalWidth += parseInt(col.style.width, 10);
});
tableElement.style.width = `${totalWidth}px`;
const thead = tableElement.createTHead();
const headerRow = thead.insertRow();
@@ -315,7 +380,7 @@ export function renderTables() {
if (!tableData.rows || tableData.rows.length === 0) {
const headerMenu = document.createElement('div');
headerMenu.className = 'amily2-context-menu amily2-header-menu';
headerMenu.style.display = 'none';
headerMenu.style.display = 'none'; // 默认隐藏
const addRowButton = document.createElement('button');
addRowButton.innerHTML = '<i class="fas fa-plus-circle"></i> 创建第一行';
@@ -398,6 +463,57 @@ export function renderTables() {
});
th.appendChild(menu);
const resizer = document.createElement('div');
resizer.className = 'amily2-resizer';
th.appendChild(resizer);
const startResize = (startEvent) => {
startEvent.preventDefault();
startEvent.stopPropagation();
isResizing = true;
const table = startEvent.target.closest('table');
const th = startEvent.target.parentElement;
const col = table.querySelector(`colgroup > col:nth-child(${th.cellIndex + 1})`);
const isTouchEvent = startEvent.type.startsWith('touch');
const startX = isTouchEvent ? startEvent.touches[0].clientX : startEvent.clientX;
const startWidth = th.offsetWidth;
const onMove = (moveEvent) => {
const currentX = isTouchEvent ? moveEvent.touches[0].clientX : moveEvent.clientX;
const newWidth = startWidth + (currentX - startX);
if (newWidth > 50) {
col.style.width = `${newWidth}px`;
}
};
const onEnd = () => {
document.removeEventListener('mousemove', onMove);
document.removeEventListener('mouseup', onEnd);
document.removeEventListener('touchmove', onMove);
document.removeEventListener('touchend', onEnd);
const finalWidth = parseInt(col.style.width, 10);
TableManager.updateColumnWidth(tableIndex, colIndex, finalWidth);
setTimeout(() => { isResizing = false; }, 0);
};
if (isTouchEvent) {
document.addEventListener('touchmove', onMove, { passive: false });
document.addEventListener('touchend', onEnd);
} else {
document.addEventListener('mousemove', onMove);
document.addEventListener('mouseup', onEnd);
}
};
resizer.addEventListener('mousedown', startResize);
resizer.addEventListener('touchstart', startResize, { passive: false });
headerRow.appendChild(th);
});
@@ -476,7 +592,8 @@ export function renderTables() {
});
});
}
container.appendChild(tableElement);
tableWrapper.appendChild(tableElement);
container.appendChild(tableWrapper);
});
if (placeholder) {
@@ -674,6 +791,8 @@ function openRuleEditor(tableIndex) {
toastr.warning('请选择一个列。');
return;
}
// 允许输入0但0意味着“无限制”所以我们不添加规则。
if (isNaN(limitValue) || limitValue < 0) {
toastr.warning('请输入一个有效的字数限制大于等于0。');
return;
@@ -1223,6 +1342,7 @@ export function bindTableEvents() {
allTablesContainer.addEventListener('click', (event) => {
const th = event.target.closest('th');
if (th && th.classList.contains('index-col')) {
// 处理表头 # 号的点击(用于空表格添加首行)
toggleHeaderIndexContextMenu(event);
return;
}
@@ -1310,9 +1430,10 @@ export function bindTableEvents() {
const colIndex = parseInt(target.dataset.colIndex, 10);
const newValue = target.textContent;
const hScroll = tableElement.scrollLeft;
const scrollContainer = allTablesContainer.closest('.hly-scroll');
const vScroll = scrollContainer ? scrollContainer.scrollTop : 0;
// Correctly save scroll positions before re-rendering
const tableWrapper = tableElement.closest('.amily2-table-wrapper');
const hScroll = tableWrapper ? tableWrapper.scrollLeft : 0;
const vScroll = allTablesContainer.scrollTop;
TableManager.addHighlight(tableIndex, rowIndex, colIndex);
const dataToUpdate = { [colIndex]: newValue };
@@ -1320,13 +1441,12 @@ export function bindTableEvents() {
renderAll();
const newTableElement = document.getElementById(`amily2-table-${tableIndex}`);
if (newTableElement) {
newTableElement.scrollLeft = hScroll;
}
if (scrollContainer) {
scrollContainer.scrollTop = vScroll;
// Correctly restore scroll positions after re-rendering
const newTableWrapper = document.getElementById(`amily2-table-${tableIndex}`)?.closest('.amily2-table-wrapper');
if (newTableWrapper) {
newTableWrapper.scrollLeft = hScroll;
}
allTablesContainer.scrollTop = vScroll;
}, true);
}
@@ -1849,7 +1969,6 @@ function bindChatTableDisplaySetting() {
}
showInChatToggle.checked = settings.show_table_in_chat === true;
continuousRenderToggle.checked = settings.render_on_every_message === true;
const updateContinuousRenderState = () => {
if (showInChatToggle.checked) {
continuousRenderToggle.disabled = false;
@@ -1859,9 +1978,7 @@ function bindChatTableDisplaySetting() {
continuousRenderToggle.closest('.control-block-with-switch').style.opacity = '0.5';
}
};
updateContinuousRenderState();
showInChatToggle.addEventListener('change', () => {
settings.show_table_in_chat = showInChatToggle.checked;
saveSettingsDebounced();