You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
6.3 KiB
149 lines
6.3 KiB
"use strict"; |
|
|
|
Object.defineProperty(exports, "__esModule", { |
|
value: true |
|
}); |
|
exports.queryByLabelText = exports.queryAllByLabelText = exports.getByLabelText = exports.getAllByLabelText = exports.findByLabelText = exports.findAllByLabelText = void 0; |
|
|
|
var _config = require("../config"); |
|
|
|
var _helpers = require("../helpers"); |
|
|
|
var _labelHelpers = require("../label-helpers"); |
|
|
|
var _allUtils = require("./all-utils"); |
|
|
|
function queryAllLabels(container) { |
|
return Array.from(container.querySelectorAll('label,input')).map(node => { |
|
return { |
|
node, |
|
textToMatch: (0, _labelHelpers.getLabelContent)(node) |
|
}; |
|
}).filter(({ |
|
textToMatch |
|
}) => textToMatch !== null); |
|
} |
|
|
|
const queryAllLabelsByText = (container, text, { |
|
exact = true, |
|
trim, |
|
collapseWhitespace, |
|
normalizer |
|
} = {}) => { |
|
const matcher = exact ? _allUtils.matches : _allUtils.fuzzyMatches; |
|
const matchNormalizer = (0, _allUtils.makeNormalizer)({ |
|
collapseWhitespace, |
|
trim, |
|
normalizer |
|
}); |
|
const textToMatchByLabels = queryAllLabels(container); |
|
return textToMatchByLabels.filter(({ |
|
node, |
|
textToMatch |
|
}) => matcher(textToMatch, node, text, matchNormalizer)).map(({ |
|
node |
|
}) => node); |
|
}; |
|
|
|
const queryAllByLabelText = (container, text, { |
|
selector = '*', |
|
exact = true, |
|
collapseWhitespace, |
|
trim, |
|
normalizer |
|
} = {}) => { |
|
(0, _helpers.checkContainerType)(container); |
|
const matcher = exact ? _allUtils.matches : _allUtils.fuzzyMatches; |
|
const matchNormalizer = (0, _allUtils.makeNormalizer)({ |
|
collapseWhitespace, |
|
trim, |
|
normalizer |
|
}); |
|
const matchingLabelledElements = Array.from(container.querySelectorAll('*')).filter(element => { |
|
return (0, _labelHelpers.getRealLabels)(element).length || element.hasAttribute('aria-labelledby'); |
|
}).reduce((labelledElements, labelledElement) => { |
|
const labelList = (0, _labelHelpers.getLabels)(container, labelledElement, { |
|
selector |
|
}); |
|
labelList.filter(label => Boolean(label.formControl)).forEach(label => { |
|
if (matcher(label.content, label.formControl, text, matchNormalizer) && label.formControl) labelledElements.push(label.formControl); |
|
}); |
|
const labelsValue = labelList.filter(label => Boolean(label.content)).map(label => label.content); |
|
if (matcher(labelsValue.join(' '), labelledElement, text, matchNormalizer)) labelledElements.push(labelledElement); |
|
|
|
if (labelsValue.length > 1) { |
|
labelsValue.forEach((labelValue, index) => { |
|
if (matcher(labelValue, labelledElement, text, matchNormalizer)) labelledElements.push(labelledElement); |
|
const labelsFiltered = [...labelsValue]; |
|
labelsFiltered.splice(index, 1); |
|
|
|
if (labelsFiltered.length > 1) { |
|
if (matcher(labelsFiltered.join(' '), labelledElement, text, matchNormalizer)) labelledElements.push(labelledElement); |
|
} |
|
}); |
|
} |
|
|
|
return labelledElements; |
|
}, []).concat((0, _allUtils.queryAllByAttribute)('aria-label', container, text, { |
|
exact, |
|
normalizer: matchNormalizer |
|
})); |
|
return Array.from(new Set(matchingLabelledElements)).filter(element => element.matches(selector)); |
|
}; // the getAll* query would normally look like this: |
|
// const getAllByLabelText = makeGetAllQuery( |
|
// queryAllByLabelText, |
|
// (c, text) => `Unable to find a label with the text of: ${text}`, |
|
// ) |
|
// however, we can give a more helpful error message than the generic one, |
|
// so we're writing this one out by hand. |
|
|
|
|
|
const getAllByLabelText = (container, text, ...rest) => { |
|
const els = queryAllByLabelText(container, text, ...rest); |
|
|
|
if (!els.length) { |
|
const labels = queryAllLabelsByText(container, text, ...rest); |
|
|
|
if (labels.length) { |
|
const tagNames = labels.map(label => getTagNameOfElementAssociatedWithLabelViaFor(container, label)).filter(tagName => !!tagName); |
|
|
|
if (tagNames.length) { |
|
throw (0, _config.getConfig)().getElementError(tagNames.map(tagName => `Found a label with the text of: ${text}, however the element associated with this label (<${tagName} />) is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a <${tagName} />, you can use aria-label or aria-labelledby instead.`).join('\n\n'), container); |
|
} else { |
|
throw (0, _config.getConfig)().getElementError(`Found a label with the text of: ${text}, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.`, container); |
|
} |
|
} else { |
|
throw (0, _config.getConfig)().getElementError(`Unable to find a label with the text of: ${text}`, container); |
|
} |
|
} |
|
|
|
return els; |
|
}; |
|
|
|
function getTagNameOfElementAssociatedWithLabelViaFor(container, label) { |
|
const htmlFor = label.getAttribute('for'); |
|
|
|
if (!htmlFor) { |
|
return null; |
|
} |
|
|
|
const element = container.querySelector(`[id="${htmlFor}"]`); |
|
return element ? element.tagName.toLowerCase() : null; |
|
} // the reason mentioned above is the same reason we're not using buildQueries |
|
|
|
|
|
const getMultipleError = (c, text) => `Found multiple elements with the text of: ${text}`; |
|
|
|
const queryByLabelText = (0, _allUtils.wrapSingleQueryWithSuggestion)((0, _allUtils.makeSingleQuery)(queryAllByLabelText, getMultipleError), queryAllByLabelText.name, 'query'); |
|
exports.queryByLabelText = queryByLabelText; |
|
const getByLabelText = (0, _allUtils.makeSingleQuery)(getAllByLabelText, getMultipleError); |
|
const findAllByLabelText = (0, _allUtils.makeFindQuery)((0, _allUtils.wrapAllByQueryWithSuggestion)(getAllByLabelText, getAllByLabelText.name, 'findAll')); |
|
exports.findAllByLabelText = findAllByLabelText; |
|
const findByLabelText = (0, _allUtils.makeFindQuery)((0, _allUtils.wrapSingleQueryWithSuggestion)(getByLabelText, getAllByLabelText.name, 'find')); |
|
exports.findByLabelText = findByLabelText; |
|
const getAllByLabelTextWithSuggestions = (0, _allUtils.wrapAllByQueryWithSuggestion)(getAllByLabelText, getAllByLabelText.name, 'getAll'); |
|
exports.getAllByLabelText = getAllByLabelTextWithSuggestions; |
|
const getByLabelTextWithSuggestions = (0, _allUtils.wrapSingleQueryWithSuggestion)(getByLabelText, getAllByLabelText.name, 'get'); |
|
exports.getByLabelText = getByLabelTextWithSuggestions; |
|
const queryAllByLabelTextWithSuggestions = (0, _allUtils.wrapAllByQueryWithSuggestion)(queryAllByLabelText, queryAllByLabelText.name, 'queryAll'); |
|
exports.queryAllByLabelText = queryAllByLabelTextWithSuggestions; |