lib/core/utils/get-selector.js
function generateSelector(elm, options, doc) {
	/*eslint no-loop-func:0*/
	if (!axe._selectorData) {
		throw new Error('Expect axe._selectorData to be set up');
	}
	const { toRoot = false } = options;
	let selector;
	let similar;

	/**
	 * Try to find a unique selector by filtering out all the clashing
	 * nodes by adding ancestor selectors iteratively.
	 * This loop is much faster than recursing and using querySelectorAll
	 */
	do {
		let features = getElmId(elm);
		if (!features) {
			features = getThreeLeastCommonFeatures(elm, axe._selectorData);
			features += getNthChildString(elm, features);
		}
		if (selector) {
			selector = features + ' > ' + selector;
		} else {
			selector = features;
		}
		if (!similar) {
			similar = Array.from(doc.querySelectorAll(selector));
		} else {
			similar = similar.filter(item => {
				return axe.utils.matchesSelector(item, selector);
			});
		}
		elm = elm.parentElement;
	} while ((similar.length > 1 || toRoot) && elm && elm.nodeType !== 11);

	if (similar.length === 1) {
		return selector;
	} else if (selector.indexOf(' > ') !== -1) {
		// For the odd case that document doesn't have a unique selector
		return ':root' + selector.substring(selector.indexOf(' > '));
	}
	return ':root';
}
function generateSelector(elm, options, doc) {
	/*eslint no-loop-func:0*/
	if (!axe._selectorData) {
		throw new Error('Expect axe._selectorData to be set up');
	}
	const { toRoot = false } = options;
	let selector;
	let similar;

	/**
	 * Try to find a unique selector by filtering out all the clashing
	 * nodes by adding ancestor selectors iteratively.
	 * This loop is much faster than recursing and using querySelectorAll
	 */
	do {
		let features = getElmId(elm);
		if (!features) {
			features = getThreeLeastCommonFeatures(elm, axe._selectorData);
			features += getNthChildString(elm, features);
		}
		if (selector) {
			selector = features + ' > ' + selector;
		} else {
			selector = features;
		}
		if (!similar) {
			similar = Array.from(doc.querySelectorAll(selector));
		} else {
			similar = similar.filter(item => {
				return axe.utils.matchesSelector(item, selector);
			});
		}
		elm = elm.parentElement;
	} while ((similar.length > 1 || toRoot) && elm && elm.nodeType !== 11);

	if (similar.length === 1) {
		return selector;
	} else if (selector.indexOf(' > ') !== -1) {
		// For the odd case that document doesn't have a unique selector
		return ':root' + selector.substring(selector.indexOf(' > '));
	}
	return ':root';
}
function generateSelector ( elm , options , doc ) { /*eslint no-loop-func:0*/ if ( ! axe . _selectorData ) { throw new Error ( 'Expect axe._selectorData to be set up' ) ; } const { toRoot = false } = options ; let selector ; let similar ; /**
	 * Try to find a unique selector by filtering out all the clashing
	 * nodes by adding ancestor selectors iteratively.
	 * This loop is much faster than recursing and using querySelectorAll
	 */ do { let features = getElmId ( elm ) ; if ( ! features ) { features = getThreeLeastCommonFeatures ( elm , axe . _selectorData ) ; features += getNthChildString ( elm , features ) ; } if ( selector ) { selector = features + ' > ' + selector ; } else { selector = features ; } if ( ! similar ) { similar = Array . from ( doc . querySelectorAll ( selector ) ) ; } else { similar = similar . filter ( item => { return axe . utils . matchesSelector ( item , selector ) ; } ) ; } elm = elm . parentElement ; } while ( ( similar . length > 1 || toRoot ) && elm && elm . nodeType !== 11 ) ; if ( similar . length === 1 ) { return selector ; } else if ( selector . indexOf ( ' > ' ) !== - 1 ) { // For the odd case that document doesn't have a unique selector return ':root' + selector . substring ( selector . indexOf ( ' > ' ) ) ; } return ':root' ; }
generates a single selector for an element
@param {Element} elm			The element for which to generate a selector
@param {Object} options	 Options for how to generate the selector
@param {RootNode} doc		 The root node of the document or document fragment
@returns {String}				 The selector
generates a single selector for an element