nehan
Version:
Html layout engine for paged-media written in Typescript
73 lines • 2.18 kB
JavaScript
import { Utils, Selector, } from "./public-api";
export class PseudoClassSelector extends Selector {
constructor(source) {
super();
this.src = source;
this.specificity.b = 1;
}
toString() {
return ":" + this.src;
}
testEven(element) {
return (element.index + 1) % 2 === 0;
}
testOdd(element) {
return this.testEven(element) === false;
}
getNthExpr(src) {
return src.replace(/\s/g, "").replace(/^nth-child\((.+)\)/, "$1");
}
testNthFuncExpr(index, expr) {
let match_a = expr.match(/\d+(?=n)/);
if (!match_a) {
console.error("invalid nth-child expr:%s", expr);
return false;
}
let a = Utils.atoi(match_a[0]);
let match_b = expr.replace(/\d+n/g, "").replace(/[+-]/g, "");
let b = match_b ? Utils.atoi(match_b[0]) : 0;
if (a === 0) {
return index === b;
}
if (index < b) {
return false;
}
return (index - b) % a === 0;
}
testNthExpr(index) {
let expr = this.getNthExpr(this.src);
if (/^\d+$/.test(expr)) {
let nth = Utils.atoi(expr);
return index + 1 === nth;
}
return this.testNthFuncExpr(index, expr);
}
testNthChild(element) {
return this.testNthExpr(element.indexOfElement);
}
testMatch(element) {
throw new Error("pseudo-class 'match' is not implemented yet");
}
test(element) {
if (this.src === "first-child") {
return element.isFirstElementChild();
}
if (this.src === "last-child") {
return element.isLastElementChild();
}
if (this.src === "odd") {
return this.testOdd(element);
}
if (this.src === "even") {
return this.testEven(element);
}
if (this.src.indexOf("nth-child(") >= 0) {
return this.testNthChild(element);
}
if (this.src.indexOf("match(") >= 0) {
return this.testMatch(element);
}
return false;
}
}
//# sourceMappingURL=pseudo-class-selector.js.map