Skip to content

Commit

Permalink
fix: attribute case insensitivity parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
romainmenke committed Nov 20, 2022
1 parent c3db2ff commit fd5f0bf
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
28 changes: 28 additions & 0 deletions src/__tests__/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,38 @@ test('insensitive attribute selector 2', '[href=TEsT i ]', (t, tree) => {
test('insensitive attribute selector 3', '[href=test i]', (t, tree) => {
t.deepEqual(tree.nodes[0].nodes[0].value, 'test');
t.deepEqual(tree.nodes[0].nodes[0].insensitive, true);

tree.nodes[0].nodes[0].insensitive = false;

t.deepEqual(tree.toString(), '[href=test ]');
});
test('capitalized insensitive attribute selector 3', '[href=test I]', (t, tree) => {
t.deepEqual(tree.nodes[0].nodes[0].value, 'test');
t.deepEqual(tree.nodes[0].nodes[0].insensitive, true);

tree.nodes[0].nodes[0].insensitive = false;

t.deepEqual(tree.toString(), '[href=test ]');
});

test('insensitive attribute selector 4', '[href="test"i]', (t, tree) => {
t.deepEqual(tree.nodes[0].nodes[0].value, 'test');
t.deepEqual(tree.nodes[0].nodes[0].insensitive, true);
});

test('capitalized insensitive attribute selector 4', '[href="test"I]', (t, tree) => {
t.deepEqual(tree.nodes[0].nodes[0].value, 'test');
t.deepEqual(tree.nodes[0].nodes[0].insensitive, true);
});

test('insensitive attribute selector 5', '[href="test" i ]', (t, tree) => {
t.deepEqual(tree.nodes[0].nodes[0].value, 'test');
t.deepEqual(tree.nodes[0].nodes[0].insensitive, true);
});

test('insensitive attribute selector 6', '[href=test i ]', (t, tree) => {
t.deepEqual(tree.nodes[0].nodes[0].value, 'test');
t.deepEqual(tree.nodes[0].nodes[0].insensitive, true);
});

test('extraneous non-combinating whitespace', ' [href] , [class] ', (t, tree) => {
Expand Down
6 changes: 3 additions & 3 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ export default class Parser {
node.raws.attribute += content;
}
lastAdded = 'attribute';
} else if ((!node.value && node.value !== "") || (lastAdded === "value" && !spaceAfterMeaningfulToken)) {
} else if ((!node.value && node.value !== "") || (lastAdded === "value" && !(spaceAfterMeaningfulToken || node.quoteMark))) {
let unescaped = unesc(content);
let oldRawValue = getProp(node, 'raws', 'value') || '';
let oldValue = node.value || '';
Expand Down Expand Up @@ -464,8 +464,8 @@ export default class Parser {
}

/**
*
* @param {*} nodes
*
* @param {*} nodes
*/
convertWhitespaceNodesToSpace (nodes, requiredSpace = false) {
let space = "";
Expand Down
25 changes: 25 additions & 0 deletions src/selectors/attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,31 @@ export default class Attribute extends Namespace {
return this._value;
}

get insensitive () {
return this._insensitive;
}

/**
* Set the case insensitive flag.
* If the case insensitive flag changes, the raw (escaped) value at `attr.raws.insensitiveFlag`
* of the attribute is updated accordingly.
*
* @param {true | false} insensitive true if the attribute should match case-insensitively.
*/
set insensitive (insensitive) {
if (!insensitive) {
this._insensitive = false;

// "i" and "I" can be used in "this.raws.insensitiveFlag" to store the original notation.
// When setting `attr.insensitive = false` both should be erased to ensure correct serialization.
if (this.raws && (this.raws.insensitiveFlag === 'I' || this.raws.insensitiveFlag === 'i')) {
this.raws.insensitiveFlag = undefined;
}
}

this._insensitive = insensitive;
}

/**
* Before 3.0, the value had to be set to an escaped value including any wrapped
* quote marks. In 3.0, the semantics of `Attribute.value` changed so that the value
Expand Down

0 comments on commit fd5f0bf

Please sign in to comment.