user1141649 user1141649 - 3 months ago 6
CSS Question

how to calculate css rules priority in Javascript?

I have created this code to calculate css rules priority

var selectorText = "body";
A = selectorText.match(/#/gm); // id
A = !A ? 0 : A.length;
B1 = selectorText.match(/\\./gm); // class
B1 = !B1 ? 0 : B1.length;
B2 = selectorText.match(/[[]/gm); // attribute selector
B2 = !B2 ? 0 : B2.length;
B3 = selectorText.match(/[\\w\\d_\\s^]:(?!:)/gm); // pseudo třída
B3 = !B3 ? 0 : B3.length;
B = B1 + B2 + B3;
C1 = selectorText.match(/::/gm); // pseudo element
C1 = !C1 ? 0 : C1.length;
C2 = selectorText.match(/\\w+[$\\s#\\.:\\[]/gm); // element
C2 = !C2 ? 0 : C2.length;
C = C1 + C2;
A *= 10000;
B *= 100;
alert(C)


There must not be more than 100 matches (A, B or C) in a selector.
For some reason the result of C is 0 (but I use "body" selector). Can you suggest how to correct the last match? Also do you see any mistakes in the code?

Note:

The original question stated just "body" selector, but I think about any selector or multiple selectors like this: "div#menu ul li, div#id, div.class" the selector can contain pseudo-classes, pseudo-elements, attribute selectors. In the case of C2 regex, I am trying to find count of elements which here in the last string is 5 elements total (then C2 should be 5).

Answer

selectorText does not contain ::, C1 = selectorText.match(/::/gm); should return null; C1 = !C1 ? 0 : C1.length; returns 0; C2 = selectorText.match(/\\w+[$\s#\\.:\\[]/gm); returns null, C2 = !C2 ? 0 : C2.length; returns 0; C = C1 + C2; is equal to 0; that is 0 + 0 = 0


The original question stated just "body" selector, but I think about any selector or multiple selectors like this: "div#menu ul li, div#id, div.class" the selector can contain pseudo-classes, pseudo-elements, attribute selectors. In the case of C2 regex, I am trying to find count of elements which here in the last string is 5 elements total (then C2 should be 5)

You can use .split() with RegExp /,|\s/ to split multiple selectors at , character; .map(), .filter(Boolean) to remove empty string, .match() with RegExp /^[a-z]+(?=[.#:\s]|$)/i to match element.

var selectorText = "div#menu ul li, div#id, div.class";
C2 = selectorText.split(/,|\s/).filter(Boolean)
     .map(el => el.trim().match(/^[a-z]+(?=[.#:\s]|$)/i)[0]);
console.log(C2);