fix(selectors): use Maps instead of objects
This commit is contained in:
parent
b4265e0685
commit
d321b0ebf5
|
@ -135,12 +135,12 @@ export class SelectorMatcher {
|
||||||
return notMatcher;
|
return notMatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _elementMap: {[k: string]: SelectorContext[]} = {};
|
private _elementMap = new Map<string, SelectorContext[]>();
|
||||||
private _elementPartialMap: {[k: string]: SelectorMatcher} = {};
|
private _elementPartialMap = new Map<string, SelectorMatcher>();
|
||||||
private _classMap: {[k: string]: SelectorContext[]} = {};
|
private _classMap = new Map<string, SelectorContext[]>();
|
||||||
private _classPartialMap: {[k: string]: SelectorMatcher} = {};
|
private _classPartialMap = new Map<string, SelectorMatcher>();
|
||||||
private _attrValueMap: {[k: string]: {[k: string]: SelectorContext[]}} = {};
|
private _attrValueMap = new Map<string, Map<string, SelectorContext[]>>();
|
||||||
private _attrValuePartialMap: {[k: string]: {[k: string]: SelectorMatcher}} = {};
|
private _attrValuePartialMap = new Map<string, Map<string, SelectorMatcher>>();
|
||||||
private _listContexts: SelectorListContext[] = [];
|
private _listContexts: SelectorListContext[] = [];
|
||||||
|
|
||||||
addSelectables(cssSelectors: CssSelector[], callbackCtxt?: any) {
|
addSelectables(cssSelectors: CssSelector[], callbackCtxt?: any) {
|
||||||
|
@ -195,18 +195,18 @@ export class SelectorMatcher {
|
||||||
const value = attrs[i + 1];
|
const value = attrs[i + 1];
|
||||||
if (isTerminal) {
|
if (isTerminal) {
|
||||||
const terminalMap = matcher._attrValueMap;
|
const terminalMap = matcher._attrValueMap;
|
||||||
let terminalValuesMap = terminalMap[name];
|
let terminalValuesMap = terminalMap.get(name);
|
||||||
if (!terminalValuesMap) {
|
if (!terminalValuesMap) {
|
||||||
terminalValuesMap = {};
|
terminalValuesMap = new Map<string, SelectorContext[]>();
|
||||||
terminalMap[name] = terminalValuesMap;
|
terminalMap.set(name, terminalValuesMap);
|
||||||
}
|
}
|
||||||
this._addTerminal(terminalValuesMap, value, selectable);
|
this._addTerminal(terminalValuesMap, value, selectable);
|
||||||
} else {
|
} else {
|
||||||
let partialMap = matcher._attrValuePartialMap;
|
let partialMap = matcher._attrValuePartialMap;
|
||||||
let partialValuesMap = partialMap[name];
|
let partialValuesMap = partialMap.get(name);
|
||||||
if (!partialValuesMap) {
|
if (!partialValuesMap) {
|
||||||
partialValuesMap = {};
|
partialValuesMap = new Map<string, SelectorMatcher>();
|
||||||
partialMap[name] = partialValuesMap;
|
partialMap.set(name, partialValuesMap);
|
||||||
}
|
}
|
||||||
matcher = this._addPartial(partialValuesMap, value);
|
matcher = this._addPartial(partialValuesMap, value);
|
||||||
}
|
}
|
||||||
|
@ -215,20 +215,20 @@ export class SelectorMatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addTerminal(
|
private _addTerminal(
|
||||||
map: {[k: string]: SelectorContext[]}, name: string, selectable: SelectorContext) {
|
map: Map<string, SelectorContext[]>, name: string, selectable: SelectorContext) {
|
||||||
let terminalList = map[name];
|
let terminalList = map.get(name);
|
||||||
if (!terminalList) {
|
if (!terminalList) {
|
||||||
terminalList = [];
|
terminalList = [];
|
||||||
map[name] = terminalList;
|
map.set(name, terminalList);
|
||||||
}
|
}
|
||||||
terminalList.push(selectable);
|
terminalList.push(selectable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addPartial(map: {[k: string]: SelectorMatcher}, name: string): SelectorMatcher {
|
private _addPartial(map: Map<string, SelectorMatcher>, name: string): SelectorMatcher {
|
||||||
let matcher = map[name];
|
let matcher = map.get(name);
|
||||||
if (!matcher) {
|
if (!matcher) {
|
||||||
matcher = new SelectorMatcher();
|
matcher = new SelectorMatcher();
|
||||||
map[name] = matcher;
|
map.set(name, matcher);
|
||||||
}
|
}
|
||||||
return matcher;
|
return matcher;
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ export class SelectorMatcher {
|
||||||
const name = attrs[i];
|
const name = attrs[i];
|
||||||
const value = attrs[i + 1];
|
const value = attrs[i + 1];
|
||||||
|
|
||||||
const terminalValuesMap = this._attrValueMap[name];
|
const terminalValuesMap = this._attrValueMap.get(name);
|
||||||
if (value) {
|
if (value) {
|
||||||
result =
|
result =
|
||||||
this._matchTerminal(terminalValuesMap, '', cssSelector, matchedCallback) || result;
|
this._matchTerminal(terminalValuesMap, '', cssSelector, matchedCallback) || result;
|
||||||
|
@ -278,7 +278,7 @@ export class SelectorMatcher {
|
||||||
result =
|
result =
|
||||||
this._matchTerminal(terminalValuesMap, value, cssSelector, matchedCallback) || result;
|
this._matchTerminal(terminalValuesMap, value, cssSelector, matchedCallback) || result;
|
||||||
|
|
||||||
const partialValuesMap = this._attrValuePartialMap[name];
|
const partialValuesMap = this._attrValuePartialMap.get(name);
|
||||||
if (value) {
|
if (value) {
|
||||||
result = this._matchPartial(partialValuesMap, '', cssSelector, matchedCallback) || result;
|
result = this._matchPartial(partialValuesMap, '', cssSelector, matchedCallback) || result;
|
||||||
}
|
}
|
||||||
|
@ -291,14 +291,14 @@ export class SelectorMatcher {
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_matchTerminal(
|
_matchTerminal(
|
||||||
map: {[k: string]: SelectorContext[]}, name: string, cssSelector: CssSelector,
|
map: Map<string, SelectorContext[]>, name: string, cssSelector: CssSelector,
|
||||||
matchedCallback: (c: CssSelector, a: any) => void): boolean {
|
matchedCallback: (c: CssSelector, a: any) => void): boolean {
|
||||||
if (!map || typeof name !== 'string') {
|
if (!map || typeof name !== 'string') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let selectables = map[name];
|
let selectables = map.get(name);
|
||||||
const starSelectables = map['*'];
|
const starSelectables = map.get('*');
|
||||||
if (starSelectables) {
|
if (starSelectables) {
|
||||||
selectables = selectables.concat(starSelectables);
|
selectables = selectables.concat(starSelectables);
|
||||||
}
|
}
|
||||||
|
@ -316,13 +316,13 @@ export class SelectorMatcher {
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_matchPartial(
|
_matchPartial(
|
||||||
map: {[k: string]: SelectorMatcher}, name: string, cssSelector: CssSelector,
|
map: Map<string, SelectorMatcher>, name: string, cssSelector: CssSelector,
|
||||||
matchedCallback: (c: CssSelector, a: any) => void): boolean {
|
matchedCallback: (c: CssSelector, a: any) => void): boolean {
|
||||||
if (!map || typeof name !== 'string') {
|
if (!map || typeof name !== 'string') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nestedSelector = map[name];
|
const nestedSelector = map.get(name);
|
||||||
if (!nestedSelector) {
|
if (!nestedSelector) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,12 @@ export function main() {
|
||||||
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
|
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not throw for class name "constructor"', () => {
|
||||||
|
expect(matcher.match(CssSelector.parse('.constructor')[0], selectableCollector))
|
||||||
|
.toEqual(false);
|
||||||
|
expect(matched).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
it('should select by attr name case sensitive independent of the value', () => {
|
it('should select by attr name case sensitive independent of the value', () => {
|
||||||
matcher.addSelectables(s1 = CssSelector.parse('[someAttr]'), 1);
|
matcher.addSelectables(s1 = CssSelector.parse('[someAttr]'), 1);
|
||||||
matcher.addSelectables(s2 = CssSelector.parse('[someAttr][someAttr2]'), 2);
|
matcher.addSelectables(s2 = CssSelector.parse('[someAttr][someAttr2]'), 2);
|
||||||
|
|
Loading…
Reference in New Issue