Skip to content

Commit 5ae5fbb

Browse files
Sync docker clone row heights by folder id from main table
1 parent fed3a30 commit 5ae5fbb

3 files changed

Lines changed: 57 additions & 73 deletions

File tree

209 KB
Binary file not shown.

folderview.plus.plg

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@
66
<!ENTITY launch "Settings/FolderViewPlus">
77
<!ENTITY plugdir "/usr/local/emhttp/plugins/&name;">
88
<!ENTITY pluginURL "https://raw.githubusercontent.com/&github;/main/folderview.plus.plg">
9-
<!ENTITY version "2026.03.08.4">
10-
<!ENTITY md5 "5eb168d1dec551f9fa7ccd54276b291c">
9+
<!ENTITY version "2026.03.08.5">
10+
<!ENTITY md5 "292969f4dacb98f9268ce80256b6324f">
1111
]>
1212

1313
<PLUGIN name="&name;" author="&author;" version="&version;" launch="&launch;" pluginURL="&pluginURL;" icon="folder-open-o" support="https://github.com/alexphillips-dev/FolderView-Plus/issues" min="7.0.0">
1414
<CHANGES>
1515

16+
###2026.03.08.5
17+
- Rework Docker left-column centering sync to match by folder id content:
18+
- derive folder id from row class or hidden `folder-(id)` marker,
19+
- map source heights from real `#docker_list` rows,
20+
- apply height sync only to non-main clone rows and keep main rows at natural compact height.
21+
1622
###2026.03.08.4
1723
- Fix Docker folder left-column centering regression while keeping compact spacing:
1824
- use absolute vertical centering for folder label block on both row render paths,

src/folderview.plus/usr/local/emhttp/plugins/folderview.plus/scripts/docker.js

Lines changed: 49 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,21 @@ const escapeClassToken = (value) => {
6565
};
6666

6767
const getFolderIdFromRow = (row) => {
68-
if (!row || !row.classList) {
68+
if (!row) {
6969
return '';
7070
}
71-
for (const cls of row.classList) {
72-
if (typeof cls === 'string' && cls.startsWith('folder-id-')) {
73-
return cls.substring('folder-id-'.length);
71+
if (row.classList) {
72+
for (const cls of row.classList) {
73+
if (typeof cls === 'string' && cls.startsWith('folder-id-')) {
74+
return cls.substring('folder-id-'.length);
75+
}
76+
}
77+
}
78+
const label = row.querySelector && row.querySelector('td.ct-name.folder-name span.appname a');
79+
if (label && typeof label.textContent === 'string') {
80+
const text = label.textContent.trim();
81+
if (text.startsWith('folder-') && text.length > 7) {
82+
return text.substring(7);
7483
}
7584
}
7685
return '';
@@ -86,48 +95,30 @@ const getRenderedRowHeight = (row) => {
8695
return Math.max(Math.round(rectHeight), Math.round(offsetHeight), 0);
8796
};
8897

89-
const rowHasFolderPreview = (row) => {
90-
return !!(row && row.querySelector && row.querySelector('div.folder-preview'));
98+
const isMainDockerRow = (row) => {
99+
return !!(row && row.closest && row.closest('#docker_list'));
91100
};
92101

93-
const syncFolderRowsHeight = (rows) => {
94-
if (!rows || !rows.length) {
95-
return 0;
96-
}
97-
let baseHeight = 0;
98-
rows.forEach((row) => {
99-
if (rowHasFolderPreview(row)) {
100-
baseHeight = Math.max(baseHeight, getRenderedRowHeight(row));
101-
}
102-
});
103-
if (baseHeight <= 0) {
104-
rows.forEach((row) => {
105-
baseHeight = Math.max(baseHeight, getRenderedRowHeight(row));
106-
});
102+
const applyRowHeight = (row, height = 0) => {
103+
if (!row || row.tagName !== 'TR') {
104+
return;
107105
}
108-
if (baseHeight <= 0) {
109-
return 0;
106+
const targetHeight = Number.isFinite(height) && height > 0 ? Math.round(height) : 0;
107+
if (targetHeight > 0) {
108+
row.style.setProperty('height', `${targetHeight}px`, 'important');
109+
} else {
110+
row.style.removeProperty('height');
110111
}
111-
112-
rows.forEach((row) => {
113-
const shouldSyncHeight = !rowHasFolderPreview(row);
114-
if (shouldSyncHeight) {
115-
row.style.setProperty('height', `${baseHeight}px`, 'important');
116-
} else {
117-
row.style.removeProperty('height');
118-
}
119-
Array.from(row.children || []).forEach((td) => {
120-
if (td && td.tagName === 'TD') {
121-
if (shouldSyncHeight) {
122-
td.style.setProperty('height', `${baseHeight}px`, 'important');
123-
} else {
124-
td.style.removeProperty('height');
125-
}
126-
td.style.setProperty('vertical-align', 'middle', 'important');
112+
Array.from(row.children || []).forEach((td) => {
113+
if (td && td.tagName === 'TD') {
114+
if (targetHeight > 0) {
115+
td.style.setProperty('height', `${targetHeight}px`, 'important');
116+
} else {
117+
td.style.removeProperty('height');
127118
}
128-
});
119+
td.style.setProperty('vertical-align', 'middle', 'important');
120+
}
129121
});
130-
return baseHeight;
131122
};
132123

133124
const applyFolderCellCentering = (cell, rowHeight = 0) => {
@@ -180,53 +171,40 @@ const applyFolderCellCentering = (cell, rowHeight = 0) => {
180171
};
181172

182173
const forceAllFolderRowsVerticalCenter = () => {
183-
const rowsByFolderId = new Map();
184-
const handledRows = new Set();
185-
186-
document.querySelectorAll('tr[class*="folder-id-"]').forEach((row) => {
174+
const mainRowHeightByFolderId = new Map();
175+
document.querySelectorAll('#docker_list tr').forEach((row) => {
187176
const id = getFolderIdFromRow(row);
188177
if (!id) {
189178
return;
190179
}
191-
if (!rowsByFolderId.has(id)) {
192-
rowsByFolderId.set(id, []);
180+
const height = getRenderedRowHeight(row);
181+
if (height > 0) {
182+
mainRowHeightByFolderId.set(id, height);
193183
}
194-
rowsByFolderId.get(id).push(row);
195-
});
196-
197-
rowsByFolderId.forEach((rows) => {
198-
const syncedHeight = syncFolderRowsHeight(rows);
199-
rows.forEach((row) => {
200-
handledRows.add(row);
201-
const rowHeight = rowHasFolderPreview(row) ? 0 : syncedHeight;
202-
row.querySelectorAll('td.ct-name.folder-name').forEach((cell) => {
203-
applyFolderCellCentering(cell, rowHeight);
204-
});
205-
});
206184
});
207185

186+
const processedRows = new Set();
208187
document.querySelectorAll('td.ct-name.folder-name').forEach((cell) => {
209188
const parentRow = cell.parentElement;
210-
if (!handledRows.has(parentRow)) {
211-
applyFolderCellCentering(cell, rowHasFolderPreview(parentRow) ? 0 : getRenderedRowHeight(parentRow));
189+
if (!parentRow || processedRows.has(parentRow)) {
190+
return;
212191
}
192+
processedRows.add(parentRow);
193+
194+
const folderId = getFolderIdFromRow(parentRow);
195+
const mainHeight = folderId ? (mainRowHeightByFolderId.get(folderId) || 0) : 0;
196+
const targetHeight = !isMainDockerRow(parentRow) && mainHeight > 0 ? mainHeight : 0;
197+
applyRowHeight(parentRow, targetHeight);
198+
applyFolderCellCentering(cell, targetHeight);
213199
});
214200
};
215201

216202
const forceFolderRowVerticalCenter = (id) => {
217-
const escapedId = escapeClassToken(id);
218-
const rows = Array.from(document.querySelectorAll(`tr.folder-id-${escapedId}`));
219-
if (!rows.length) {
220-
forceAllFolderRowsVerticalCenter();
203+
const escapedId = escapeClassToken(id); // Keep id-specific call signature for existing call sites.
204+
if (!escapedId) {
221205
return;
222206
}
223-
const syncedHeight = syncFolderRowsHeight(rows);
224-
rows.forEach((row) => {
225-
const rowHeight = rowHasFolderPreview(row) ? 0 : syncedHeight;
226-
row.querySelectorAll('td.ct-name.folder-name').forEach((cell) => {
227-
applyFolderCellCentering(cell, rowHeight);
228-
});
229-
});
207+
forceAllFolderRowsVerticalCenter();
230208
};
231209

232210
let folderRowCenterObserver = null;

0 commit comments

Comments
 (0)