DEV Community

Murahashi [Matt] Kenichi
Murahashi [Matt] Kenichi

Posted on • Updated on

Let's build browser engine! in typescript vol8 Specificity

Calculating a selector’s specificity

I'm not sure I don't count C.

// Examples:
//
// *               /* a=0 b=0 c=0 */
// LI              /* a=0 b=0 c=1 */
// UL LI           /* a=0 b=0 c=2 */
// UL OL+LI        /* a=0 b=0 c=3 */
// H1 + *[REL=up]  /* a=0 b=1 c=1 */
// UL OL LI.red    /* a=0 b=1 c=3 */
// LI.red.level    /* a=0 b=2 c=1 */
// #x34y           /* a=1 b=0 c=0 */
// #s12:not(FOO)   /* a=1 b=0 c=1 */
// .foo :is(.bar, #baz)
//                 /* a=1 b=1 c=0 */

test("specificity li", () => {
  expect(new SimpleSelector("li", null, []).specificity()).toEqual([0, 0, 1]);
});

test("specificity li.red.level", () => {
  expect(new SimpleSelector("li", null, ["red", "level"]).specificity()).toEqual([0, 2, 1]);
});

test("specificity #x34y", () => {
  expect(new SimpleSelector(null, "x34y", []).specificity()).toEqual([1, 0, 0]);
});
Enter fullscreen mode Exit fullscreen mode
export type Specificity = [number, number, number];

export class SimpleSelector {
  (snip)

  specificity(): Specificity {
    // http://www.w3.org/TR/selectors/#specificity
    const a = this.id === null ? 0 : 1;
    const b = this.classValue.length;
    // NOTE: I don't support chained selectors now.
    const c = this.tagName === null ? 0 : 1;
    return [a, b, c];
  }
}
Enter fullscreen mode Exit fullscreen mode

:thinking_face:

references

series

Top comments (0)