Skip to content

Commit

Permalink
Invalidate state pseudo class (#149)
Browse files Browse the repository at this point in the history
  • Loading branch information
asamuzaK authored Nov 11, 2024
1 parent 9cfcd11 commit 2309249
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 6 deletions.
5 changes: 5 additions & 0 deletions src/js/constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,9 @@ export const KEY_MODIFIER = Object.freeze([
'Alt', 'AltGraph', 'CapsLock', 'Control', 'Fn', 'FnLock', 'Hyper', 'Meta',
'NumLock', 'ScrollLock', 'Shift', 'Super', 'Symbol', 'SymbolLock'
]);
export const KEY_PS_STATE = Object.freeze([
'enabled', 'disabled', 'valid', 'invalid', 'in-range', 'out-of-range',
'checked', 'indeterminate', 'read-only', 'read-write', 'open', 'closed',
'placeholder-shown'
]);
export const KEY_SHADOW_HOST = Object.freeze(['host', 'host-context']);
7 changes: 4 additions & 3 deletions src/js/finder.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,11 @@ export class Finder {
}
const { branches, info } = walkAST(cssAst);
const {
hasHasPseudoFunc, hasLogicalPseudoFunc, hasNthChildOfSelector
hasHasPseudoFunc, hasLogicalPseudoFunc, hasNthChildOfSelector,
hasStatePseudoClass
} = info;
let invalidate =
hasHasPseudoFunc || !!(hasLogicalPseudoFunc && hasNthChildOfSelector);
let invalidate = hasHasPseudoFunc || hasStatePseudoClass ||
!!(hasLogicalPseudoFunc && hasNthChildOfSelector);
let descendant = false;
let i = 0;
ast = [];
Expand Down
8 changes: 5 additions & 3 deletions src/js/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { getType } from './utility.js';
/* constants */
import {
ATTR_SELECTOR, BIT_01, BIT_02, BIT_04, BIT_08, BIT_16, BIT_32, BIT_FFFF,
CLASS_SELECTOR, DUO, HEX, HYPHEN, ID_SELECTOR, KEY_LOGICAL, KEY_SHADOW_HOST,
NTH, PS_CLASS_SELECTOR, PS_ELEMENT_SELECTOR, SELECTOR, SYNTAX_ERR,
TYPE_SELECTOR
CLASS_SELECTOR, DUO, HEX, HYPHEN, ID_SELECTOR, KEY_LOGICAL, KEY_PS_STATE,
KEY_SHADOW_HOST, NTH, PS_CLASS_SELECTOR, PS_ELEMENT_SELECTOR, SELECTOR,
SYNTAX_ERR, TYPE_SELECTOR
} from './constant.js';
const REG_EMPTY_PS_FUNC = /(?<=:(?:dir|has|host(?:-context)?|is|lang|not|nth-(?:last-)?(?:child|of-type)|where))\(\s+\)/g;
const REG_SHADOW_PS_ELEMENT = /^part|slotted$/;
Expand Down Expand Up @@ -192,6 +192,8 @@ export const walkAST = (ast = {}) => {
if (node.name === 'has') {
info.set('hasHasPseudoFunc', true);
}
} else if (KEY_PS_STATE.includes(node.name)) {
info.set('hasStatePseudoClass', true);
} else if (KEY_SHADOW_HOST.includes(node.name) &&
Array.isArray(node.children) && node.children.length) {
info.set('hasNestedSelector', true);
Expand Down
35 changes: 35 additions & 0 deletions test/parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7094,6 +7094,41 @@ describe('walk AST', () => {
}, 'result');
});

it('should get selectors and info', () => {
const ast = {
children: [
{
children: [
{
loc: null,
name: 'checked',
type: PS_CLASS_SELECTOR
}
],
loc: null,
type: SELECTOR
}
],
loc: null,
type: SELECTOR_LIST
};
const res = func(ast);
assert.deepEqual(res, {
branches: [
[
{
loc: null,
name: 'checked',
type: PS_CLASS_SELECTOR
}
]
],
info: {
hasStatePseudoClass: true
}
}, 'result');
});

it('should get selectors and info', () => {
const ast = {
children: [
Expand Down
18 changes: 18 additions & 0 deletions test/wpt.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6358,6 +6358,24 @@ describe('local wpt test cases', () => {
});
});

describe('to-upstream/html/semantics/selectors/pseudo-classes/checked-002.html', () => {
it('should get matched node(s)', () => {
const html = `
<select id="select" multiple>
<option id="option" selected>Your only option</option>
</select>
`;
document.body.innerHTML = html;
const selectEl = document.querySelector("#select");
const optionEl = document.querySelector("#option");
const query1 = selectEl.querySelector(":checked");
assert.deepEqual(query1, optionEl);
selectEl.lastElementChild.selected = false;
const query2 = selectEl.querySelector(":checked");
assert.isNull(query2);
});
});

describe('jsdom: to-port-to-wpts/query-selector-all.js', () => {
it('should get matched node(s)', () => {
const html = `
Expand Down

0 comments on commit 2309249

Please sign in to comment.