Skip to content

Commit

Permalink
Just use querySelector in elementByTag
Browse files Browse the repository at this point in the history
[Just as fast](https://jsbench.github.io/#639aa913f9d03e86f75df4665f04da66) and less code.

Also asserts that tagNames passed to `*ByTag` functions are actually just tagNames.
  • Loading branch information
jridgewell committed Feb 21, 2019
1 parent efa27d0 commit 0bc8331
Showing 1 changed file with 21 additions and 8 deletions.
29 changes: 21 additions & 8 deletions src/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ export function ancestorElements(child, predicate) {
* @return {!Array<!Element>}
*/
export function ancestorElementsByTag(child, tagName) {
assertOnlyTagName(tagName);
tagName = tagName.toUpperCase();
return ancestorElements(child, el => {
return el.tagName == tagName;
Expand Down Expand Up @@ -383,6 +384,8 @@ export function childNodes(parent, callback) {
* @return {?Element}
*/
export function childElementByAttr(parent, attr) {
// Yah, it's supposed to be an attr and not a tag name. But same code.
assertOnlyTagName(attr);
return scopedQuerySelector/*OK*/(parent, `> [${attr}]`);
}

Expand All @@ -394,6 +397,8 @@ export function childElementByAttr(parent, attr) {
* @return {?Element}
*/
export function lastChildElementByAttr(parent, attr) {
// Yah, it's supposed to be an attr and not a tag name. But same code.
assertOnlyTagName(attr);
return lastChildElement(parent, el => {
return el.hasAttribute(attr);
});
Expand All @@ -407,6 +412,8 @@ export function lastChildElementByAttr(parent, attr) {
* @return {!NodeList<!Element>}
*/
export function childElementsByAttr(parent, attr) {
// Yah, it's supposed to be an attr and not a tag name. But same code.
assertOnlyTagName(attr);
return scopedQuerySelectorAll/*OK*/(parent, `> [${attr}]`);
}

Expand All @@ -418,6 +425,7 @@ export function childElementsByAttr(parent, attr) {
* @return {?Element}
*/
export function childElementByTag(parent, tagName) {
assertOnlyTagName(tagName);
return scopedQuerySelector/*OK*/(parent, `> ${tagName}`);
}

Expand All @@ -429,6 +437,7 @@ export function childElementByTag(parent, tagName) {
* @return {!NodeList<!Element>}
*/
export function childElementsByTag(parent, tagName) {
assertOnlyTagName(tagName);
return scopedQuerySelectorAll/*OK*/(parent, `> ${tagName}`);
}

Expand Down Expand Up @@ -457,14 +466,18 @@ export function matches(el, selector) {
* @return {?Element}
*/
export function elementByTag(element, tagName) {
let elements;
// getElementsByTagName() is not supported on ShadowRoot.
if (typeof element.getElementsByTagName === 'function') {
elements = element.getElementsByTagName(tagName);
} else {
elements = element./*OK*/querySelectorAll(tagName);
}
return (elements && elements[0]) || null;
assertOnlyTagName(tagName);
return element./*OK*/querySelector(tagName);
}

/**
* Asserts that tagName is just an alphanumeric word, and does not contain
* advanced CSS selector features like attributes, psuedo-classes, class names,
* nor ids.
* @param {string} tagName
*/
function assertOnlyTagName(tagName) {
devAssert(!/[^\w-]/.test(tagName));
}

/**
Expand Down

0 comments on commit 0bc8331

Please sign in to comment.