|
3 | 3 | // found in the LICENSE file. |
4 | 4 |
|
5 | 5 | import * as Protocol from '../../generated/protocol.js'; |
| 6 | +import {renderElementIntoDOM} from '../../testing/DOMHelpers.js'; |
6 | 7 | import {createTarget} from '../../testing/EnvironmentHelpers.js'; |
7 | 8 | import {describeWithMockConnection, setMockConnectionResponseHandler} from '../../testing/MockConnection.js'; |
8 | 9 | import {getMatchedStyles, ruleMatch} from '../../testing/StyleHelpers.js'; |
@@ -696,6 +697,91 @@ describe('CSSMatchedStyles', () => { |
696 | 697 | assert.strictEqual(matchedStyles.resolveProperty('color', styles[0])?.value, 'y'); |
697 | 698 | assert.isNull(matchedStyles.resolveProperty('background-color', styles[0])); |
698 | 699 | }); |
| 700 | + |
| 701 | + it('evaluates variables with attr() calls in the same way as blink', async () => { |
| 702 | + const attributes = [ |
| 703 | + {name: 'data-test-nonexistent', value: 'attr(data-nonexistent)'}, |
| 704 | + {name: 'data-test-nonexistent-raw-string', value: 'attr(data-nonexistent raw-string)'}, |
| 705 | + {name: 'data-test-empty', value: ''}, |
| 706 | + {name: 'data-test-self-loop', value: 'attr(data-test-self-loop)'}, |
| 707 | + {name: 'data-test-loop-1', value: 'attr(data-test-loop-2 type(<length>), 1px)'}, |
| 708 | + {name: 'data-test-loop-2', value: 'var(--test-loop-1, 2px)'}, |
| 709 | + {name: 'data-test-loop-indirect-2', value: 'attr(data-test-loop-1 type(<length>), 6px)'}, |
| 710 | + {name: 'data-test-number', value: '70'}, |
| 711 | + {name: 'data-test-length', value: 'attr(data-test-number in)'}, |
| 712 | + {name: 'data-test-bad-unit', value: 'attr(data-test-number parsecs, 2px)'}, |
| 713 | + {name: 'data-test-bad-type', value: 'attr(data-test-number type(<nomber>), 2)'}, |
| 714 | + {name: 'data-cant-parse', value: 'attr('}, |
| 715 | + ]; |
| 716 | + const variables = [ |
| 717 | + {name: '--test-missing', value: 'attr(data-nonexistent)'}, |
| 718 | + {name: '--test-missing-fallback', value: 'attr(data-nonexistent, 2px)'}, |
| 719 | + {name: '--test-missing-var-indirect', value: 'var(--test-missing, 2px)'}, |
| 720 | + {name: '--test-missing-attr-indirect-raw', value: 'attr(data-test-nonexistent, 2px)'}, |
| 721 | + {name: '--test-missing-attr-indirect', value: 'attr(data-test-nonexistent type(*), 2px)'}, |
| 722 | + {name: '--test-missing-raw-string', value: 'attr(data-nonexistent raw-string)'}, |
| 723 | + {name: '--test-missing-raw-string-fallback', value: 'attr(data-nonexistent raw-string, 2px)'}, |
| 724 | + {name: '--test-missing-raw-string-var-indirect', value: 'var(--test-missing-raw-string, 2px)'}, |
| 725 | + {name: '--test-missing-raw-string-attr-indirect', value: 'attr(data-test-nonexistent-raw-string, 2px)'}, |
| 726 | + {name: '--test-empty-any', value: 'attr(data-test-empty type(*))'}, |
| 727 | + {name: '--test-empty-number', value: 'attr(data-test-empty type(<number>))'}, |
| 728 | + {name: '--test-empty-any-fallback', value: 'attr(data-test-empty type(*), 2px)'}, |
| 729 | + {name: '--test-empty-number-fallback', value: 'attr(data-test-empty type(<number>), 2px)'}, |
| 730 | + {name: '--test-self-loop', value: 'attr(data-test-self-loop type(*))'}, |
| 731 | + {name: '--test-self-loop-raw', value: 'attr(data-test-self-loop)'}, |
| 732 | + {name: '--test-self-loop-fallback', value: 'attr(data-test-self-loop type(*), 2px)'}, |
| 733 | + {name: '--test-self-loop-fallback-2', value: 'var(--test-self-loop-fallback, 4px)'}, |
| 734 | + {name: '--test-self-loop-fallback-self', value: 'attr(data-test-self-loop type(*), attr(data-test-self-loop))'}, |
| 735 | + {name: '--test-loop-1', value: 'var(--test-loop-2, 3px)'}, |
| 736 | + {name: '--test-loop-2', value: 'attr(data-test-loop-1 type(<length>), 4px)'}, |
| 737 | + {name: '--test-loop-indirect-1', value: 'attr(data-test-loop-1 type(<length>), 5px)'}, |
| 738 | + {name: '--test-loop-indirect-2', value: 'attr(data-test-loop-indirect-2 type(<length>), 7px)'}, |
| 739 | + {name: '--test-number', value: 'attr(data-test-number type(<number>))'}, |
| 740 | + {name: '--test-number-to-length', value: 'attr(data-test-number in)'}, |
| 741 | + { |
| 742 | + name: '--test-number-as-length', |
| 743 | + value: 'attr(data-test-number type(<length>), var(--test-self-loop-fallback-2))' |
| 744 | + }, |
| 745 | + {name: '--test-length', value: 'attr(data-test-length type(<length>))'}, |
| 746 | + // TODO(b/393087009): Re-enable once fallback is fixed. |
| 747 | + // {name: '--test-bad-unit-indirect', value: 'attr(data-test-bad-unit type(*), 4px)'}, |
| 748 | + // {name: '--test-bad-type-indirect', value: 'attr(data-test-bad-type type(*), 4)'}, |
| 749 | + // {name: '--test-cant-parse', value: 'attr(data-cant-parse type(*), red)'}, |
| 750 | + ]; |
| 751 | + // Create an element |
| 752 | + const element = document.createElement('div'); |
| 753 | + for (const {name, value} of attributes) { |
| 754 | + element.setAttribute(name, value); |
| 755 | + } |
| 756 | + for (const {name, value} of variables) { |
| 757 | + element.style.setProperty(name, value); |
| 758 | + } |
| 759 | + |
| 760 | + renderElementIntoDOM(element); |
| 761 | + const computedProperties = element.computedStyleMap(); |
| 762 | + |
| 763 | + const node = sinon.createStubInstance(SDK.DOMModel.DOMNode); |
| 764 | + node.id = 1 as Protocol.DOM.NodeId; |
| 765 | + node.nodeType.returns(Node.ELEMENT_NODE); |
| 766 | + // Create a sinon stub to return the requested attribute |
| 767 | + node.getAttribute.callsFake((name: string) => attributes.find(attr => attr.name === name)?.value); |
| 768 | + |
| 769 | + const matchedStyles = await getMatchedStyles({ |
| 770 | + matchedPayload: [ruleMatch('div', variables)], |
| 771 | + node, |
| 772 | + }); |
| 773 | + |
| 774 | + for (const {name} of variables) { |
| 775 | + const frontendComputedValue = |
| 776 | + matchedStyles.computeCSSVariable(matchedStyles.nodeStyles()[0], name)?.value ?? null; |
| 777 | + const backendComputedValue = computedProperties.get(name) ?? null; |
| 778 | + if (backendComputedValue === null) { |
| 779 | + assert.isNull(frontendComputedValue, `evaluating variable ${name}`); |
| 780 | + } else { |
| 781 | + assert.strictEqual(frontendComputedValue, backendComputedValue.toString(), `evaluating variable ${name}`); |
| 782 | + } |
| 783 | + } |
| 784 | + }); |
699 | 785 | }); |
700 | 786 |
|
701 | 787 | describeWithMockConnection('NodeCascade', () => { |
|
0 commit comments