refactor: Handle TS2.7 stricter tuples checks (#5366)

This commit is contained in:
Alexander Vakrilov
2018-02-01 13:04:55 +02:00
committed by GitHub
parent c66a3fb3a7
commit c0a7a45ab9
3 changed files with 49 additions and 51 deletions

View File

@@ -342,7 +342,7 @@ export function parseAngle(value: string, start: number = 0): Parsed<Angle> {
const angleResult = parseUnit(value, start);
if (angleResult) {
const { start, end, value } = angleResult;
return (angleUnitsToRadMap[value.unit] || (() => null))(start, end, value.value);
return (angleUnitsToRadMap[value.unit] || ((_,__,___) => null))(start, end, value.value);
}
return null;
}
@@ -693,7 +693,8 @@ export interface AttributeSelector {
export type SimpleSelector = UniversalSelector | TypeSelector | ClassSelector | IdSelector | PseudoClassSelector | AttributeSelector;
export type SimpleSelectorSequence = SimpleSelector[];
export type Selector = [SimpleSelectorSequence, Combinator];
export type SelectorCombinatorPair = [SimpleSelectorSequence, Combinator];
export type Selector = SelectorCombinatorPair[];
const universalSelectorRegEx = /\*/gy;
export function parseUniversalSelector(text: string, start: number = 0): Parsed<UniversalSelector> {
@@ -781,6 +782,7 @@ export function parseSelector(text: string, start: number = 0): Parsed<Selector>
let value = <Selector>[];
let combinator: Parsed<Combinator>;
let expectSimpleSelector = true; // Must have at least one
let pair = <SelectorCombinatorPair>[];
do {
const simpleSelectorSequence = parseSimpleSelectorSequence(text, end);
if (!simpleSelectorSequence) {
@@ -792,16 +794,17 @@ export function parseSelector(text: string, start: number = 0): Parsed<Selector>
}
end = simpleSelectorSequence.end;
if (combinator) {
value.push(combinator.value);
pair[1] = combinator.value;
}
value.push(simpleSelectorSequence.value);
pair = [simpleSelectorSequence.value, undefined]
value.push(pair)
combinator = parseCombinator(text, end);
if (combinator) {
end = combinator.end;
}
expectSimpleSelector = combinator && combinator.value !== " "; // Simple selector must follow non trailing white space combinator
} while(combinator);
value.push(undefined);
return { start, end, value };
}

View File

@@ -432,13 +432,13 @@ function createSimpleSelectorSequenceFromAst(ast: parser.SimpleSelectorSequence)
function createSelectorFromAst(ast: parser.Selector): SimpleSelector | SimpleSelectorSequence | Selector {
if (ast.length === 0) {
return new InvalidSelector(new Error("Empty selector."));
} else if (ast.length <= 2) {
return createSimpleSelectorSequenceFromAst(ast[0]);
} else if (ast.length === 1) {
return createSimpleSelectorSequenceFromAst(ast[0][0]);
} else {
let simpleSelectorSequences = [];
for (var i = 0; i < ast.length; i += 2) {
const simpleSelectorSequence = createSimpleSelectorSequenceFromAst(<parser.SimpleSelectorSequence>ast[i]);
const combinator = <parser.Combinator>ast[i + 1];
for (var i = 0; i < ast.length; i ++) {
const simpleSelectorSequence = createSimpleSelectorSequenceFromAst(<parser.SimpleSelectorSequence>ast[i][0]);
const combinator = <parser.Combinator>ast[i][1];
if (combinator) {
simpleSelectorSequence.combinator = combinator;
}

View File

@@ -143,68 +143,63 @@ describe("css", () => {
describe("selectors", () => {
test(parseSelector, ` listview#products.mark gridlayout:selected[row="2"] a> b > c >d>e *[src] `, {
start: 0, end: 79, value: [
[
[[
{ type: "", identifier: "listview" },
{ type: "#", identifier: "products" },
{ type: ".", identifier: "mark" }
],
" ",
[
], " "],
[[
{ type: "", identifier: "gridlayout" },
{ type: ":", identifier: "selected" },
{ type: "[]", property: "row", test: "=", value: "2" }
],
" ",
[{ type: "", identifier: "a"}],
">",
[{ type: "", identifier: "b"}],
">",
[{ type: "", identifier: "c"}],
">",
[{ type: "", identifier: "d"}],
">",
[{ type: "", identifier: "e"}],
" ",
[
], " "],
[[{ type: "", identifier: "a"}], ">"],
[[{ type: "", identifier: "b"}], ">"],
[[{ type: "", identifier: "c"}], ">"],
[[{ type: "", identifier: "d"}], ">"],
[[{ type: "", identifier: "e"}], " "],
[[
{ type: "*" },
{ type: "[]", property: "src" }
],
undefined
], undefined]
],
});
test(parseSelector, "*", { start: 0, end: 1, value: [[{ type: "*" }], undefined ]});
test(parseSelector, "button", { start: 0, end: 6, value: [[{ type: "", identifier: "button" }], undefined]});
test(parseSelector, ".login", { start: 0, end: 6, value: [[{ type: ".", identifier: "login" }], undefined]});
test(parseSelector, "#login", { start: 0, end: 6, value: [[{ type: "#", identifier: "login" }], undefined]});
test(parseSelector, ":hover", { start: 0, end: 6, value: [[{ type: ":", identifier: "hover" }], undefined]});
test(parseSelector, "[src]", { start: 0, end: 5, value: [[{ type: "[]", property: "src" }], undefined]});
test(parseSelector, `[src = "res://"]`, { start: 0, end: 16, value: [[{ type: "[]", property: "src", test: "=", value: `res://`}], undefined]});
test(parseSelector, "*", { start: 0, end: 1, value: [[[{ type: "*" }], undefined ]] });
test(parseSelector, "button", { start: 0, end: 6, value: [[[{ type: "", identifier: "button" }], undefined]]});
test(parseSelector, ".login", { start: 0, end: 6, value: [[[{ type: ".", identifier: "login" }], undefined]]});
test(parseSelector, "#login", { start: 0, end: 6, value: [[[{ type: "#", identifier: "login" }], undefined]]});
test(parseSelector, ":hover", { start: 0, end: 6, value: [[[{ type: ":", identifier: "hover" }], undefined]]});
test(parseSelector, "[src]", { start: 0, end: 5, value: [[[{ type: "[]", property: "src" }], undefined]]});
test(parseSelector, `[src = "res://"]`, { start: 0, end: 16, value: [[[{ type: "[]", property: "src", test: "=", value: `res://`}], undefined]]});
(<AttributeSelectorTest[]>["=", "^=", "$=", "*=", "=", "~=", "|="]).forEach(attributeTest => {
test(parseSelector, `[src ${attributeTest} "val"]`, { start: 0, end: 12 + attributeTest.length, value: [[{ type: "[]", property: "src", test: attributeTest, value: "val"}], undefined]});
test(parseSelector, `[src ${attributeTest} "val"]`, { start: 0, end: 12 + attributeTest.length, value: [[[{ type: "[]", property: "src", test: attributeTest, value: "val"}], undefined]]});
});
test(parseSelector, "listview > .image", { start: 0, end: 17, value: [[{ type: "", identifier: "listview"}], ">", [{ type: ".", identifier: "image"}], undefined]});
test(parseSelector, "listview .image", { start: 0, end: 16, value: [[{ type: "", identifier: "listview"}], " ", [{ type: ".", identifier: "image"}], undefined]});
test(parseSelector, "button:hover", { start: 0, end: 12, value: [[{ type: "", identifier: "button" }, { type: ":", identifier: "hover"}], undefined]});
test(parseSelector, "listview > .image", { start: 0, end: 17, value: [
[[{ type: "", identifier: "listview"}], ">"],
[[{ type: ".", identifier: "image"}], undefined]
]});
test(parseSelector, "listview .image", { start: 0, end: 16, value: [
[[{ type: "", identifier: "listview"}], " "],
[[{ type: ".", identifier: "image"}], undefined]
]});
test(parseSelector, "button:hover", { start: 0, end: 12, value: [[[{ type: "", identifier: "button" }, { type: ":", identifier: "hover"}], undefined]]});
test(parseSelector, "listview>:selected image.product", { start: 0, end: 32, value: [
[{ type: "", identifier: "listview" }],
">",
[{ type: ":", identifier: "selected" }],
" ",
[
[[{ type: "", identifier: "listview" }], ">"],
[[{ type: ":", identifier: "selected" }], " "],
[[
{ type: "", identifier: "image" },
{ type: ".", identifier: "product" }
],
undefined
], undefined]
]});
test(parseSelector, "button[testAttr]", { start: 0, end: 16, value: [
[
[[
{ type: "", identifier: "button" },
{ type: "[]", property: "testAttr" },
],
undefined
undefined]
]});
test(parseSelector, "button#login[user][pass]:focused:hovered", { start: 0, end: 40, value: [
[
[[
{ type: "", identifier: "button" },
{ type: "#", identifier: "login" },
{ type: "[]", property: "user" },
@@ -212,7 +207,7 @@ describe("css", () => {
{ type: ":", identifier: "focused" },
{ type: ":", identifier: "hovered" }
],
undefined
undefined]
]});
});