case insensitive flag

0 views
Skip to first unread message

Andrew Poulos

unread,
Mar 2, 2021, 1:48:09 AM3/2/21
to
I had some code that looked like this

document.querySelectorAll('a[href^="goto"]')

that failed because users were setting the href to cases different from
the expected case. I was thinking that this was going to be a PIA to
resolve till a search revealed that in modern browsers there's a flag to
make an attribute selector case-insensitive.

So for those don't know here's the simple resolution:

document.querySelectorAll('a[href^="goto" i]')

Andrew Poulos

Thomas 'PointedEars' Lahn

unread,
Mar 4, 2021, 8:02:14 AM3/4/21
to
Andrew Poulos wrote:

> I had some code that looked like this
>
> document.querySelectorAll('a[href^="goto"]')
>
> that failed because users were setting the href to cases different from
> the expected case.

The attribute name, or the attribute value?

> I was thinking that this was going to be a PIA to
> resolve till a search revealed that in modern browsers there's a flag to
> make an attribute selector case-insensitive.
>
> So for those don't know here's the simple resolution:
>
> document.querySelectorAll('a[href^="goto" i]')

This is a relatively new feature:

<https://www.w3.org/TR/selectors-4/#attribute-case>
<https://caniuse.com/css-case-insensitive>

I would be wary to rely on it on the Internet at this point (the intranet
might be a different case); I would use XPath instead (or as a fallback),
which is better supported:

<https://dom.spec.whatwg.org/#xpathexpression>
(DOM Level 3 XPath is “retired”: <https://www.w3.org/TR/DOM-Level-3-XPath/>)

<https://caniuse.com/document-evaluate-xpath>

With WHATWG DOM and XPath 1.0 (assuming that you mean the attribute value):

const xpathCaseInsensitive = function (name, v) {
return `translate(${name}, '${v.toUpperCase()}', '${v.toLowerCase()}')`;
};

const s = 'goto';
let snapshots = document.evaluate(
`//a[starts-with(${xpathCaseInsensitive('@href', s)}, '${s}')]`,
document.body,
null,
XPathResult.XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
);

/* alternatively (more backwards-compatible):
*
* var snapshots = new Array(snapshots.snapshotLength).keys()
* .map((el, i) => snapshots.snapshotItem(i));
*/
snapshots = [...new Array(snapshots.snapshotLength)].map(
(el, i) => snapshots.snapshotItem(i)
);

If at some point in the future XPath 2.0 will be supported sufficiently,
you can write simpler

let snapshots = document.evaluate(
"//a[starts-with(lower-case(@href), 'goto')]",
document.body,
null,
XPathResult.XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
);

snapshots = Array.from(
new Array(snapshots.snapshotLength),
(el, i) => snapshots.snapshotItem(i)
);

I think this should be posted to <news:comp.lang.javascript> (as well).
Adjust follow-ups if necessary.

--
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

Andrew Poulos

unread,
Mar 4, 2021, 6:54:34 PM3/4/21
to
On 5/03/2021 12:02 am, Thomas 'PointedEars' Lahn wrote:
> Andrew Poulos wrote:
>
>> I had some code that looked like this
>>
>> document.querySelectorAll('a[href^="goto"]')
>>
>> that failed because users were setting the href to cases different from
>> the expected case.
>
> The attribute name, or the attribute value?
>
>> I was thinking that this was going to be a PIA to
>> resolve till a search revealed that in modern browsers there's a flag to
>> make an attribute selector case-insensitive.
>>
>> So for those don't know here's the simple resolution:
>>
>> document.querySelectorAll('a[href^="goto" i]')
>
> This is a relatively new feature:
>
> <https://www.w3.org/TR/selectors-4/#attribute-case>
> <https://caniuse.com/css-case-insensitive>

This page indicates that it works in most places (except for IE)
<https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors>
Thanks for the code.

Andrew Poulos

Thomas 'PointedEars' Lahn

unread,
Mar 4, 2021, 7:43:06 PM3/4/21
to
Andrew Poulos wrote:

> On 5/03/2021 12:02 am, Thomas 'PointedEars' Lahn wrote:
>> Andrew Poulos wrote:
>>> document.querySelectorAll('a[href^="goto"]')
>>>
>>> that failed because users were setting the href to cases different from
>>> the expected case.
>>
>> The attribute name, or the attribute value?

Well?

>>> document.querySelectorAll('a[href^="goto" i]')
>> This is a relatively new feature:
>>
>> <https://www.w3.org/TR/selectors-4/#attribute-case>
>> <https://caniuse.com/css-case-insensitive>
>
> This page indicates that it works in most places (except for IE)
> <https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors>

When in doubt, probably trust caniuse.com more than MDN.

>> […]
> Thanks for the code.

You’re welcome. I learned a thing or two about the new Array-related
features and XPath while writing it; so that you for the question :)

F’up2 comp.lang.javascript

Thomas 'PointedEars' Lahn

unread,
Mar 4, 2021, 8:23:10 PM3/4/21
to
Andrew Poulos wrote:

> On 5/03/2021 12:02 am, Thomas 'PointedEars' Lahn wrote:
>> Andrew Poulos wrote:
>>> document.querySelectorAll('a[href^="goto"]')
>>>
>>> that failed because users were setting the href to cases different from
>>> the expected case.
>>
>> The attribute name, or the attribute value?

Well?

>>> document.querySelectorAll('a[href^="goto" i]')
>> This is a relatively new feature:
>>
>> <https://www.w3.org/TR/selectors-4/#attribute-case>
>> <https://caniuse.com/css-case-insensitive>
>
> This page indicates that it works in most places (except for IE)
> <https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors>

When in doubt, probably trust caniuse.com more than MDN.

>> […]
> Thanks for the code.

You’re welcome. I learned a thing or two about the new Array-related
features and XPath while writing it; so thank you for the question :)

F’up2 comp.lang.javascript

Andrew Poulos

unread,
Mar 4, 2021, 10:39:17 PM3/4/21
to
On 5/03/2021 12:23 pm, Thomas 'PointedEars' Lahn wrote:
> Andrew Poulos wrote:
>
>> On 5/03/2021 12:02 am, Thomas 'PointedEars' Lahn wrote:
>>> Andrew Poulos wrote:
>>>> document.querySelectorAll('a[href^="goto"]')
>>>>
>>>> that failed because users were setting the href to cases different from
>>>> the expected case.
>>>
>>> The attribute name, or the attribute value?
>
> Well?

The value which, in my case, starts "goto".

>>>> document.querySelectorAll('a[href^="goto" i]')
>>> This is a relatively new feature:
>>>
>>> <https://www.w3.org/TR/selectors-4/#attribute-case>
>>> <https://caniuse.com/css-case-insensitive>
>>
>> This page indicates that it works in most places (except for IE)
>> <https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors>
>
> When in doubt, probably trust caniuse.com more than MDN.

Of the online resources I usually refer to MDN first. Good to know that
in some things, other sites are more "trustworthy".

>>> […]
>> Thanks for the code.
>
> You’re welcome. I learned a thing or two about the new Array-related
> features and XPath while writing it; so thank you for the question :)

Well I'm all chuffed.

Andrew Poulos

Thomas 'PointedEars' Lahn

unread,
Mar 5, 2021, 1:45:21 PM3/5/21
to
Andrew Poulos wrote:

> On 5/03/2021 12:23 pm, Thomas 'PointedEars' Lahn wrote:
>> Andrew Poulos wrote:
>>> On 5/03/2021 12:02 am, Thomas 'PointedEars' Lahn wrote:
>>>> Andrew Poulos wrote:
>>>>> document.querySelectorAll('a[href^="goto"]')
>>>>>
>>>>> that failed because users were setting the href to cases different
>>>>> from the expected case.
>>>> The attribute name, or the attribute value?
>> Well?
>
> The value which, in my case, starts "goto".

OK.

>>>>> document.querySelectorAll('a[href^="goto" i]')
>>>> This is a relatively new feature:
>>>>
>>>> <https://www.w3.org/TR/selectors-4/#attribute-case>
>>>> <https://caniuse.com/css-case-insensitive>
>>> This page indicates that it works in most places (except for IE)
>>> <https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors>
>> When in doubt, probably trust caniuse.com more than MDN.
>
> Of the online resources I usually refer to MDN first. Good to know that
> in some things, other sites are more "trustworthy".

I recommended caniuse.com over MDN *in this case* because both MDN and
caniuse.com are community-supported projects, but the focus of caniuse.com
is documenting compatibility while MDN provides documentation in general.

Now I can also see that caniuse.com features a last-modified date on the top
of the site, and you can see that it was last modified on 2021-02-27, while
the MDN page that you referred to was last modified on 2021-02-19.

>>>> […]
>>> Thanks for the code.
>>
>> You’re welcome. I learned a thing or two about the new Array-related
>> features and XPath while writing it; so thank you for the question :)
>
> Well I'm all chuffed.

:)
Reply all
Reply to author
Forward
0 new messages