|
1395 | 1395 | } |
1396 | 1396 | }; |
1397 | 1397 | D.search.oninput = e => { |
1398 | | - const q = e.target.value.toLowerCase(); |
1399 | | - document.querySelectorAll('.tree-item').forEach(item => { |
1400 | | - const n = item.querySelector('.file-name').textContent.toLowerCase(); |
1401 | | - item.style.display = n.includes(q) ? '' : 'none'; |
| 1398 | + const q = e.target.value.trim().toLowerCase(); |
| 1399 | + const allItems = Array.from(document.querySelectorAll('.tree-item')); |
| 1400 | + // Helper: get full path for a tree-item |
| 1401 | + const getPath = item => { |
| 1402 | + let path = ''; |
| 1403 | + let cur = item; |
| 1404 | + while (cur && cur.classList.contains('tree-item')) { |
| 1405 | + const name = cur.querySelector('.file-name')?.textContent || ''; |
| 1406 | + path = name + (path ? '/' + path : ''); |
| 1407 | + cur = cur.parentElement?.closest('.tree-item'); |
| 1408 | + } |
| 1409 | + return path.toLowerCase(); |
| 1410 | + }; |
| 1411 | + // First, hide all |
| 1412 | + allItems.forEach(item => { item.style.display = 'none'; }); |
| 1413 | + // If search is empty, show all |
| 1414 | + if (!q) { |
| 1415 | + allItems.forEach(item => { item.style.display = ''; }); |
| 1416 | + // Collapse all folders |
| 1417 | + document.querySelectorAll('.tree-children').forEach(tc => tc.classList.remove('open')); |
| 1418 | + document.querySelectorAll('.expand-btn').forEach(btn => btn.classList.remove('expanded')); |
| 1419 | + document.querySelectorAll('.expand-btn .material-symbols-outlined').forEach(span => span.textContent = 'chevron_right'); |
| 1420 | + return; |
| 1421 | + } |
| 1422 | + // Find all items that match (by name or path) |
| 1423 | + const matches = allItems.filter(item => { |
| 1424 | + const name = item.querySelector('.file-name')?.textContent.toLowerCase() || ''; |
| 1425 | + const path = getPath(item); |
| 1426 | + return name.includes(q) || path.includes(q); |
| 1427 | + }); |
| 1428 | + // Show all matches and their ancestors |
| 1429 | + const showSet = new Set(); |
| 1430 | + matches.forEach(item => { |
| 1431 | + let cur = item; |
| 1432 | + while (cur && cur.classList.contains('tree-item')) { |
| 1433 | + showSet.add(cur); |
| 1434 | + cur = cur.parentElement?.closest('.tree-item'); |
| 1435 | + } |
| 1436 | + }); |
| 1437 | + allItems.forEach(item => { |
| 1438 | + if (showSet.has(item)) { |
| 1439 | + item.style.display = ''; |
| 1440 | + } else { |
| 1441 | + item.style.display = 'none'; |
| 1442 | + } |
| 1443 | + }); |
| 1444 | + // Expand all folders that are ancestors of matches |
| 1445 | + document.querySelectorAll('.tree-children').forEach(tc => { |
| 1446 | + const parent = tc.parentElement; |
| 1447 | + if (parent && showSet.has(parent)) { |
| 1448 | + tc.classList.add('open'); |
| 1449 | + const btn = parent.querySelector('.expand-btn'); |
| 1450 | + if (btn) { |
| 1451 | + btn.classList.add('expanded'); |
| 1452 | + const span = btn.querySelector('.material-symbols-outlined'); |
| 1453 | + if (span) span.textContent = 'expand_more'; |
| 1454 | + } |
| 1455 | + } else { |
| 1456 | + tc.classList.remove('open'); |
| 1457 | + const btn = parent?.querySelector('.expand-btn'); |
| 1458 | + if (btn) { |
| 1459 | + btn.classList.remove('expanded'); |
| 1460 | + const span = btn.querySelector('.material-symbols-outlined'); |
| 1461 | + if (span) span.textContent = 'chevron_right'; |
| 1462 | + } |
| 1463 | + } |
1402 | 1464 | }); |
1403 | 1465 | }; |
1404 | 1466 | const togFold = o => { |
|
0 commit comments