|
4 | 4 | findIndex, |
5 | 5 | firstMatch, |
6 | 6 | get, |
| 7 | + hashCode, |
7 | 8 | inArray, |
8 | 9 | isArray, |
9 | 10 | isClient, |
@@ -50,6 +51,12 @@ export class Query { |
50 | 51 | */ |
51 | 52 | static behaviors = new Map(); |
52 | 53 |
|
| 54 | + /* |
| 55 | + Cache for naturalDisplay() results per element |
| 56 | + Key: element, Value: { rulesHash, displayValue } |
| 57 | + */ |
| 58 | + static elementDisplayCache = new WeakMap(); |
| 59 | + |
53 | 60 | constructor(selector, { root = document, pierceShadow = false, prevObject = null } = {}) { |
54 | 61 | let elements = []; |
55 | 62 |
|
@@ -1451,9 +1458,36 @@ export class Query { |
1451 | 1458 |
|
1452 | 1459 | naturalDisplay() { |
1453 | 1460 | const displays = this.map((el) => { |
| 1461 | + console.log('hi'); |
| 1462 | + // Create cache key from current stylesheet state + inline styles |
| 1463 | + const stylesheetData = Array.from(document.styleSheets).map(sheet => { |
| 1464 | + try { |
| 1465 | + return { href: sheet.href, title: sheet.title, disabled: sheet.disabled }; |
| 1466 | + } |
| 1467 | + catch (e) { |
| 1468 | + // Cross-origin stylesheet - can't access properties safely |
| 1469 | + return { crossOrigin: true, index: Array.from(document.styleSheets).indexOf(sheet) }; |
| 1470 | + } |
| 1471 | + }); |
| 1472 | + |
| 1473 | + // Include inline display style in cache key since it overrides everything |
| 1474 | + const inlineDisplay = el.style.display; |
| 1475 | + const cacheKey = { stylesheetData, inlineDisplay }; |
| 1476 | + const rulesHash = hashCode(cacheKey); |
| 1477 | + |
| 1478 | + // Check cache for this element |
| 1479 | + const cached = Query.elementDisplayCache.get(el); |
| 1480 | + if (cached && cached.rulesHash === rulesHash) { |
| 1481 | + return cached.displayValue; |
| 1482 | + } |
| 1483 | + |
1454 | 1484 | // If already visible, return current display |
1455 | 1485 | const current = getComputedStyle(el).display; |
1456 | | - if (current !== 'none') { return current; } |
| 1486 | + if (current !== 'none') { |
| 1487 | + // Cache visible elements too |
| 1488 | + Query.elementDisplayCache.set(el, { rulesHash, displayValue: current }); |
| 1489 | + return current; |
| 1490 | + } |
1457 | 1491 |
|
1458 | 1492 | const matchingRules = []; |
1459 | 1493 |
|
@@ -1505,60 +1539,69 @@ export class Query { |
1505 | 1539 | // Sort by specificity, then source order |
1506 | 1540 | matchingRules.sort((a, b) => b.specificity - a.specificity || b.sourceOrder - a.sourceOrder); |
1507 | 1541 |
|
| 1542 | + let displayValue; |
| 1543 | + |
1508 | 1544 | // If we have matching rules, return the highest precedence value |
1509 | 1545 | if (matchingRules.length > 0) { |
1510 | | - return matchingRules[0].display; |
1511 | | - } |
1512 | | - |
1513 | | - // No CSS rules found - use element's natural display value |
1514 | | - const naturalDisplay = { |
1515 | | - inline: [ |
1516 | | - 'a', |
1517 | | - 'abbr', |
1518 | | - 'b', |
1519 | | - 'bdi', |
1520 | | - 'bdo', |
1521 | | - 'br', |
1522 | | - 'cite', |
1523 | | - 'code', |
1524 | | - 'dfn', |
1525 | | - 'em', |
1526 | | - 'i', |
1527 | | - 'kbd', |
1528 | | - 'mark', |
1529 | | - 'q', |
1530 | | - 'ruby', |
1531 | | - 'samp', |
1532 | | - 'small', |
1533 | | - 'span', |
1534 | | - 'strong', |
1535 | | - 'sub', |
1536 | | - 'sup', |
1537 | | - 'time', |
1538 | | - 'u', |
1539 | | - 'var', |
1540 | | - 'wbr', |
1541 | | - ], |
1542 | | - 'inline-block': ['button', 'img', 'input', 'meter', 'object', 'progress', 'select', 'textarea'], |
1543 | | - 'table': ['table'], |
1544 | | - 'table-row': ['tr'], |
1545 | | - 'table-cell': ['td', 'th'], |
1546 | | - 'table-header-group': ['thead'], |
1547 | | - 'table-row-group': ['tbody'], |
1548 | | - 'table-footer-group': ['tfoot'], |
1549 | | - 'table-caption': ['caption'], |
1550 | | - 'table-column': ['col'], |
1551 | | - 'table-column-group': ['colgroup'], |
1552 | | - 'list-item': ['li'], |
1553 | | - }; |
| 1546 | + displayValue = matchingRules[0].display; |
| 1547 | + } |
| 1548 | + else { |
| 1549 | + // No CSS rules found - use element's natural display value |
| 1550 | + const naturalDisplay = { |
| 1551 | + inline: [ |
| 1552 | + 'a', |
| 1553 | + 'abbr', |
| 1554 | + 'b', |
| 1555 | + 'bdi', |
| 1556 | + 'bdo', |
| 1557 | + 'br', |
| 1558 | + 'cite', |
| 1559 | + 'code', |
| 1560 | + 'dfn', |
| 1561 | + 'em', |
| 1562 | + 'i', |
| 1563 | + 'kbd', |
| 1564 | + 'mark', |
| 1565 | + 'q', |
| 1566 | + 'ruby', |
| 1567 | + 'samp', |
| 1568 | + 'small', |
| 1569 | + 'span', |
| 1570 | + 'strong', |
| 1571 | + 'sub', |
| 1572 | + 'sup', |
| 1573 | + 'time', |
| 1574 | + 'u', |
| 1575 | + 'var', |
| 1576 | + 'wbr', |
| 1577 | + ], |
| 1578 | + 'inline-block': ['button', 'img', 'input', 'meter', 'object', 'progress', 'select', 'textarea'], |
| 1579 | + 'table': ['table'], |
| 1580 | + 'table-row': ['tr'], |
| 1581 | + 'table-cell': ['td', 'th'], |
| 1582 | + 'table-header-group': ['thead'], |
| 1583 | + 'table-row-group': ['tbody'], |
| 1584 | + 'table-footer-group': ['tfoot'], |
| 1585 | + 'table-caption': ['caption'], |
| 1586 | + 'table-column': ['col'], |
| 1587 | + 'table-column-group': ['colgroup'], |
| 1588 | + 'list-item': ['li'], |
| 1589 | + }; |
1554 | 1590 |
|
1555 | | - const tagName = el.tagName.toLowerCase(); |
1556 | | - for (const [display, tags] of Object.entries(naturalDisplay)) { |
1557 | | - if (tags.includes(tagName)) { |
1558 | | - return display; |
| 1591 | + const tagName = el.tagName.toLowerCase(); |
| 1592 | + for (const [display, tags] of Object.entries(naturalDisplay)) { |
| 1593 | + if (tags.includes(tagName)) { |
| 1594 | + displayValue = display; |
| 1595 | + break; |
| 1596 | + } |
1559 | 1597 | } |
| 1598 | + displayValue = displayValue || 'block'; // Default for most elements |
1560 | 1599 | } |
1561 | | - return 'block'; // Default for most elements |
| 1600 | + |
| 1601 | + // Cache the result |
| 1602 | + Query.elementDisplayCache.set(el, { rulesHash, displayValue }); |
| 1603 | + |
| 1604 | + return displayValue; |
1562 | 1605 | }); |
1563 | 1606 | return displays.length > 1 ? displays : displays[0]; |
1564 | 1607 | } |
|
0 commit comments