File size: 2,943 Bytes
3401f26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import generate from 'css-tree/generator';

import { calculate, calculateForAST } from './core/index.js';
import { compare, equals, greaterThan, lessThan } from './util/compare.js';
import { min, max } from './util/filter.js';
import { sortAsc, sortDesc } from './util/sort.js';

class NotAllowedError extends Error {
    constructor() {
        super('Manipulating a Specificity instance is not allowed. Instead, create a new Specificity()');
    }
}

class Specificity {
    constructor(value, selector = null) {
        this.value = value;
        this.selector = selector;
    }

    get a() {
        return this.value.a;
    }

    set a(val) {
        throw new NotAllowedError();
    }

    get b() {
        return this.value.b;
    }

    set b(val) {
        throw new NotAllowedError();
    }

    get c() {
        return this.value.c;
    }

    set c(val) {
        throw new NotAllowedError();
    }

    selectorString() {
        // this.selector already is a String
        if (typeof this.selector === 'string' || this.selector instanceof String) {
            return this.selector;
        }

        // this.selector is a Selector as parsed by CSSTree
        if (this.selector instanceof Object) {
            if (this.selector.type === 'Selector') {
                return generate(this.selector);
            }
        }

        // this.selector is something else …
        return '';
    }

    toObject() {
        return this.value;
    }

    toArray() {
        return [this.value.a, this.value.b, this.value.c];
    }

    toString() {
        return `(${this.value.a},${this.value.b},${this.value.c})`;
    }

    toJSON() {
        return {
            selector: this.selectorString(),
            asObject: this.toObject(),
            asArray: this.toArray(),
            asString: this.toString(),
        };
    }

    isEqualTo(otherSpecificity) {
        return equals(this, otherSpecificity);
    }

    isGreaterThan(otherSpecificity) {
        return greaterThan(this, otherSpecificity);
    }

    isLessThan(otherSpecificity) {
        return lessThan(this, otherSpecificity);
    }

    static calculate(selector) {
        return calculate(selector);
    }

    static calculateForAST(selector) {
        return calculateForAST(selector);
    }

    static compare(s1, s2) {
        return compare(s1, s2);
    }

    static equals(s1, s2) {
        return equals(s1, s2);
    }

    static lessThan(s1, s2) {
        return lessThan(s1, s2);
    }

    static greaterThan(s1, s2) {
        return greaterThan(s1, s2);
    }

    static min(...specificities) {
        return min(...specificities);
    }

    static max(...specificities) {
        return max(...specificities);
    }

    static sortAsc(...specificities) {
        return sortAsc(...specificities);
    }

    static sortDesc(...specificities) {
        return sortDesc(...specificities);
    }
}

export default Specificity;