for selector matching, I create some shortcut.
test("element id found", () => {
expect(new ElementData("no mean", new Map([["id", "target"]])).id()).toEqual("target");
});
test("element id not found", () => {
expect(new ElementData("no mean", new Map([["no mean", "no mean"]])).id()).toBeNull();
});
export class ElementData {
(snip)
id(): string | null {
return this.attributes.get("id") || null;
}
}
test("element class 1 found", () => {
expect(new ElementData("no mean", new Map([["class", "target1"]])).classes()).toEqual(
new Set(["target1"])
);
});
test("element class 2 found", () => {
expect(new ElementData("no mean", new Map([["class", "target1 target2"]])).classes()).toEqual(
new Set(["target1", "target2"])
);
});
test("element class 0 found", () => {
expect(new ElementData("no mean", new Map([])).classes()).toEqual(new Set([]));
});
export class ElementData {
(snip)
classes(): Set<string> {
const classes = this.attributes.get("class");
if (!classes) {
return new Set([]);
}
return new Set(classes.split(" "));
}
}
selector matching. using this simple selector.
test("matches simple selector", () => {
expect(
matchesSimpleSelector(
new ElementData("no mean", new Map([])),
new SimpleSelector(null, null, [])
)
).toBe(true);
});
test("matches simple selector different tag", () => {
expect(
matchesSimpleSelector(
new ElementData("other", new Map([])),
new SimpleSelector("some", null, [])
)
).toBe(false);
});
test("matches simple selector same tag", () => {
expect(
matchesSimpleSelector(
new ElementData("target", new Map([])),
new SimpleSelector("target", null, [])
)
).toBe(true);
});
test("matches simple selector different id", () => {
expect(
matchesSimpleSelector(
new ElementData("no mean1", new Map([["id", "other"]])),
new SimpleSelector(null, "some", [])
)
).toBe(false);
});
test("matches simple selector same id", () => {
expect(
matchesSimpleSelector(
new ElementData("no mean1", new Map([["id", "target"]])),
new SimpleSelector(null, "target", [])
)
).toBe(true);
});
test("matches simple selector different class", () => {
expect(
matchesSimpleSelector(
new ElementData("no mean1", new Map([["class", "other1 other2"]])),
new SimpleSelector(null, null, ["some1", "some2"])
)
).toBe(false);
});
test("matches simple selector same class", () => {
expect(
matchesSimpleSelector(
new ElementData("no mean1", new Map([["class", "target1 other2"]])),
new SimpleSelector(null, null, ["target1", "some2"])
)
).toBe(true);
});
test("matches simple selector same tag, other id", () => {
expect(
matchesSimpleSelector(
new ElementData("same", new Map([["id", "other"]])),
new SimpleSelector("same", "some", [])
)
).toBe(false);
});
test("matches simple selector same tag, same id, different class", () => {
expect(
matchesSimpleSelector(
new ElementData("same", new Map([["id", "same"], ["class", "other1 other2"]])),
new SimpleSelector("same", "same", ["some1", "some2"])
)
).toBe(false);
});
// returns true if there are no none-match
export function matchesSimpleSelector(elem: ElementData, selector: SimpleSelector): boolean {
const tagName = selector.tagName;
if (tagName && tagName !== elem.tagName) {
return false;
}
const id = selector.id;
if (id && id !== elem.id()) {
return false;
}
const classes = selector.classValue;
if (classes.length !== 0) {
let included = false;
for (let className of classes) {
if (elem.classes().has(className)) {
included = true;
break;
}
}
if (!included) {
return false;
}
}
return true;
}
test("matches no none-match", () => {
expect(
matches(
new ElementData("no mean", new Map([])),
new Selector.Simple(new SimpleSelector(null, null, []))
)
).toBe(true);
});
test("matches none-match", () => {
expect(
matches(
new ElementData("no mean", new Map([])),
new Selector.Simple(new SimpleSelector(null, "some", []))
)
).toBe(false);
});
test("matches match", () => {
expect(
matches(
new ElementData("no mean", new Map([["id", "target"]])),
new Selector.Simple(new SimpleSelector(null, "target", []))
)
).toBe(true);
});
export function matches(elem: ElementData, selector: Selector): boolean {
switch (selector.format) {
case Selector.Format.Simple:
return matchesSimpleSelector(elem, selector.selector);
}
}
references
- Let's build a browser engine! Part 1: Getting started
- mbrubeck/robinson
- sanemat/js-toy-engine
- sanemat/ts-toy-engine
series
- Let's build browser engine! in typescript vol0 Toy browser engine
- Let's build browser engine! in typescript vol1 Canvas with Color
- Let's build browser engine! in typescript vol2 Display Command
- Let's build browser engine! in typescript vol3 Layout Box, Dimensions
- Let's build browser engine! in typescript vol4 Layout Tree to Display List
- Let's build browser engine! in typescript vol5 DOM Shortcut
- Let's build browser engine! in typescript vol6 CSS Shortcut
- Let's build browser engine! in typescript vol7 Selector matching
Top comments (0)