@master/css 2.0.0-alpha.69 → 2.0.0-alpha.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/{configure.d.ts → apis/configure.d.ts} +1 -1
- package/esm/{configure.js → apis/configure.js} +2 -2
- package/esm/apis/configure.js.map +1 -0
- package/esm/{utils → apis}/extend.d.ts +0 -0
- package/esm/{utils → apis}/extend.js +3 -3
- package/esm/apis/extend.js.map +1 -0
- package/esm/{fill-color-scale.d.ts → apis/fill-color-scale.d.ts} +0 -0
- package/esm/{fill-color-scale.js → apis/fill-color-scale.js} +2 -2
- package/esm/apis/fill-color-scale.js.map +1 -0
- package/esm/apis/index.d.ts +7 -0
- package/esm/apis/index.js +8 -0
- package/esm/apis/index.js.map +1 -0
- package/esm/apis/init.d.ts +3 -0
- package/esm/{init.js → apis/init.js} +3 -3
- package/esm/apis/init.js.map +1 -0
- package/esm/{render-from-html.d.ts → apis/render-from-html.d.ts} +2 -2
- package/esm/{render-from-html.js → apis/render-from-html.js} +5 -5
- package/esm/apis/render-from-html.js.map +1 -0
- package/esm/{render-into-html.d.ts → apis/render-into-html.d.ts} +2 -2
- package/esm/{render-into-html.js → apis/render-into-html.js} +2 -2
- package/esm/apis/render-into-html.js.map +1 -0
- package/esm/{render.d.ts → apis/render.d.ts} +2 -2
- package/esm/{render.js → apis/render.js} +4 -4
- package/esm/apis/render.js.map +1 -0
- package/esm/config/breakpoints.js.map +1 -1
- package/esm/config/colors.js +1 -1
- package/esm/config/colors.js.map +1 -1
- package/esm/config/index.d.ts +10 -1
- package/esm/config/index.js +3 -1
- package/esm/config/index.js.map +1 -1
- package/esm/config/root-size.js.map +1 -1
- package/esm/config/rules.js.map +1 -1
- package/esm/config/scheme.d.ts +8 -0
- package/esm/config/scheme.js +9 -0
- package/esm/config/scheme.js.map +1 -0
- package/esm/config/values.js.map +1 -1
- package/esm/constants/start-symbol.js.map +1 -1
- package/esm/css.d.ts +16 -8
- package/esm/css.js +227 -180
- package/esm/css.js.map +1 -1
- package/esm/index.d.ts +2 -16
- package/esm/index.js +2 -16
- package/esm/index.js.map +1 -1
- package/esm/interfaces/config.d.ts +7 -0
- package/esm/polyfills/css-escape.js +1 -1
- package/esm/polyfills/css-escape.js.map +1 -1
- package/esm/rule.js +9 -10
- package/esm/rule.js.map +1 -1
- package/esm/rules/accent-color.js.map +1 -1
- package/esm/rules/align-content.js.map +1 -1
- package/esm/rules/align-items.js.map +1 -1
- package/esm/rules/align-self.js.map +1 -1
- package/esm/rules/animation-delay.js +1 -1
- package/esm/rules/animation-delay.js.map +1 -1
- package/esm/rules/animation-direction.js +1 -1
- package/esm/rules/animation-direction.js.map +1 -1
- package/esm/rules/animation-duration.js +1 -1
- package/esm/rules/animation-duration.js.map +1 -1
- package/esm/rules/animation-fill-mode.js +1 -1
- package/esm/rules/animation-fill-mode.js.map +1 -1
- package/esm/rules/animation-iteration-count.js +1 -1
- package/esm/rules/animation-iteration-count.js.map +1 -1
- package/esm/rules/animation-name.js +1 -1
- package/esm/rules/animation-name.js.map +1 -1
- package/esm/rules/animation-play-state.js +1 -1
- package/esm/rules/animation-play-state.js.map +1 -1
- package/esm/rules/animation-timing-function.js +1 -1
- package/esm/rules/animation-timing-function.js.map +1 -1
- package/esm/rules/animation.js.map +1 -1
- package/esm/rules/appearance.js.map +1 -1
- package/esm/rules/aspect-radio.js.map +1 -1
- package/esm/rules/backdrop-filter.js +0 -1
- package/esm/rules/backdrop-filter.js.map +1 -1
- package/esm/rules/background-attachment.js.map +1 -1
- package/esm/rules/background-blend-mode.js.map +1 -1
- package/esm/rules/background-clip.js.map +1 -1
- package/esm/rules/background-color.js.map +1 -1
- package/esm/rules/background-image.js.map +1 -1
- package/esm/rules/background-origin.js.map +1 -1
- package/esm/rules/background-position.js.map +1 -1
- package/esm/rules/background-repeat.js.map +1 -1
- package/esm/rules/background-size.js.map +1 -1
- package/esm/rules/background.js.map +1 -1
- package/esm/rules/border-collapse.js.map +1 -1
- package/esm/rules/border-color.js +1 -1
- package/esm/rules/border-color.js.map +1 -1
- package/esm/rules/border-image-outset.js.map +1 -1
- package/esm/rules/border-image-repeat.js.map +1 -1
- package/esm/rules/border-image-slice.js.map +1 -1
- package/esm/rules/border-image-source.js.map +1 -1
- package/esm/rules/border-image-width.js.map +1 -1
- package/esm/rules/border-image.js.map +1 -1
- package/esm/rules/border-radius.js +1 -1
- package/esm/rules/border-radius.js.map +1 -1
- package/esm/rules/border-spacing.js.map +1 -1
- package/esm/rules/border-style.js +1 -1
- package/esm/rules/border-style.js.map +1 -1
- package/esm/rules/border-width.js +1 -1
- package/esm/rules/border-width.js.map +1 -1
- package/esm/rules/border.js +1 -1
- package/esm/rules/border.js.map +1 -1
- package/esm/rules/box-decoration-break.js +0 -1
- package/esm/rules/box-decoration-break.js.map +1 -1
- package/esm/rules/box-shadow.js.map +1 -1
- package/esm/rules/box-sizing.js.map +1 -1
- package/esm/rules/break-after.js.map +1 -1
- package/esm/rules/break-before.js.map +1 -1
- package/esm/rules/break-inside.js.map +1 -1
- package/esm/rules/caret-color.js.map +1 -1
- package/esm/rules/clear.js.map +1 -1
- package/esm/rules/clip-path.js.map +1 -1
- package/esm/rules/color.js.map +1 -1
- package/esm/rules/column-span.js.map +1 -1
- package/esm/rules/columns.js.map +1 -1
- package/esm/rules/contain.js.map +1 -1
- package/esm/rules/content.js.map +1 -1
- package/esm/rules/counter-increment.js.map +1 -1
- package/esm/rules/cursor.js.map +1 -1
- package/esm/rules/cx.js.map +1 -1
- package/esm/rules/cy.js.map +1 -1
- package/esm/rules/direction.js.map +1 -1
- package/esm/rules/display.js.map +1 -1
- package/esm/rules/fill.js.map +1 -1
- package/esm/rules/filter.js.map +1 -1
- package/esm/rules/flex-basis.js.map +1 -1
- package/esm/rules/flex-direction.js.map +1 -1
- package/esm/rules/flex-grow.js.map +1 -1
- package/esm/rules/flex-shrink.js.map +1 -1
- package/esm/rules/flex-wrap.js.map +1 -1
- package/esm/rules/flex.js.map +1 -1
- package/esm/rules/float.js.map +1 -1
- package/esm/rules/font-family.js.map +1 -1
- package/esm/rules/font-size.js.map +1 -1
- package/esm/rules/font-smoothing.js +0 -1
- package/esm/rules/font-smoothing.js.map +1 -1
- package/esm/rules/font-style.js.map +1 -1
- package/esm/rules/font-variant-numeric.js.map +1 -1
- package/esm/rules/font-weight.js.map +1 -1
- package/esm/rules/font.js.map +1 -1
- package/esm/rules/gap.js.map +1 -1
- package/esm/rules/grid-area.js.map +1 -1
- package/esm/rules/grid-auto-columns.js.map +1 -1
- package/esm/rules/grid-auto-flow.js.map +1 -1
- package/esm/rules/grid-auto-rows.js.map +1 -1
- package/esm/rules/grid-column-end.js.map +1 -1
- package/esm/rules/grid-column-start.js.map +1 -1
- package/esm/rules/grid-column.js.map +1 -1
- package/esm/rules/grid-columns.js.map +1 -1
- package/esm/rules/grid-row-end.js.map +1 -1
- package/esm/rules/grid-row-start.js.map +1 -1
- package/esm/rules/grid-row.js.map +1 -1
- package/esm/rules/grid-rows.js.map +1 -1
- package/esm/rules/grid-template-areas.js.map +1 -1
- package/esm/rules/grid-template-columns.js.map +1 -1
- package/esm/rules/grid-template-rows.js.map +1 -1
- package/esm/rules/grid-template.js.map +1 -1
- package/esm/rules/grid.js.map +1 -1
- package/esm/rules/group.js.map +1 -1
- package/esm/rules/height.js.map +1 -1
- package/esm/rules/inset.js.map +1 -1
- package/esm/rules/isolation.js.map +1 -1
- package/esm/rules/justify-content.js.map +1 -1
- package/esm/rules/justify-items.js.map +1 -1
- package/esm/rules/justify-self.js.map +1 -1
- package/esm/rules/letter-spacing.js.map +1 -1
- package/esm/rules/line-clamp.js.map +1 -1
- package/esm/rules/line-height.js.map +1 -1
- package/esm/rules/lines.js.map +1 -1
- package/esm/rules/list-style-image.js.map +1 -1
- package/esm/rules/list-style-position.js.map +1 -1
- package/esm/rules/list-style-type.js.map +1 -1
- package/esm/rules/list-style.js.map +1 -1
- package/esm/rules/margin.js +1 -1
- package/esm/rules/margin.js.map +1 -1
- package/esm/rules/mask-image.js.map +1 -1
- package/esm/rules/max-height.js.map +1 -1
- package/esm/rules/max-width.js.map +1 -1
- package/esm/rules/min-height.js.map +1 -1
- package/esm/rules/min-width.js.map +1 -1
- package/esm/rules/mix-blend-mode.js.map +1 -1
- package/esm/rules/object-fit.js.map +1 -1
- package/esm/rules/object-position.js.map +1 -1
- package/esm/rules/opacity.js.map +1 -1
- package/esm/rules/order.js.map +1 -1
- package/esm/rules/outline-color.js.map +1 -1
- package/esm/rules/outline-offset.js.map +1 -1
- package/esm/rules/outline-style.js.map +1 -1
- package/esm/rules/outline-width.js.map +1 -1
- package/esm/rules/outline.js.map +1 -1
- package/esm/rules/overflow.js.map +1 -1
- package/esm/rules/overscroll-behavior.js.map +1 -1
- package/esm/rules/padding.js.map +1 -1
- package/esm/rules/place-content.js.map +1 -1
- package/esm/rules/place-items.js.map +1 -1
- package/esm/rules/place-self.js.map +1 -1
- package/esm/rules/placement.js.map +1 -1
- package/esm/rules/pointer-events.js.map +1 -1
- package/esm/rules/position.js.map +1 -1
- package/esm/rules/quotes.js.map +1 -1
- package/esm/rules/resize.js.map +1 -1
- package/esm/rules/rx.js.map +1 -1
- package/esm/rules/ry.js.map +1 -1
- package/esm/rules/scroll-behavior.js.map +1 -1
- package/esm/rules/scroll-margin.js.map +1 -1
- package/esm/rules/scroll-padding.js.map +1 -1
- package/esm/rules/scroll-snap-align.js.map +1 -1
- package/esm/rules/scroll-snap-stop.js.map +1 -1
- package/esm/rules/scroll-snap-type.js.map +1 -1
- package/esm/rules/shape-image-threshold.js.map +1 -1
- package/esm/rules/shape-margin.js.map +1 -1
- package/esm/rules/shape-outside.js.map +1 -1
- package/esm/rules/spacing.js.map +1 -1
- package/esm/rules/stroke-dasharray.js.map +1 -1
- package/esm/rules/stroke-dashoffset.js.map +1 -1
- package/esm/rules/stroke-width.js.map +1 -1
- package/esm/rules/stroke.js.map +1 -1
- package/esm/rules/table-layout.js.map +1 -1
- package/esm/rules/text-align.js.map +1 -1
- package/esm/rules/text-decoration-color.js.map +1 -1
- package/esm/rules/text-decoration-line.js.map +1 -1
- package/esm/rules/text-decoration-style.js.map +1 -1
- package/esm/rules/text-decoration-thickness.js.map +1 -1
- package/esm/rules/text-decoration.js.map +1 -1
- package/esm/rules/text-fill-color.js.map +1 -1
- package/esm/rules/text-indent.js.map +1 -1
- package/esm/rules/text-orientation.js.map +1 -1
- package/esm/rules/text-overflow.js.map +1 -1
- package/esm/rules/text-rendering.js.map +1 -1
- package/esm/rules/text-shadow.js.map +1 -1
- package/esm/rules/text-size.js.map +1 -1
- package/esm/rules/text-stroke-color.js.map +1 -1
- package/esm/rules/text-stroke-width.js.map +1 -1
- package/esm/rules/text-stroke.js.map +1 -1
- package/esm/rules/text-transform.js.map +1 -1
- package/esm/rules/text-underline-offset.js.map +1 -1
- package/esm/rules/touch-action.js.map +1 -1
- package/esm/rules/transform-box.js.map +1 -1
- package/esm/rules/transform-origin.js.map +1 -1
- package/esm/rules/transform-style.js.map +1 -1
- package/esm/rules/transform.js.map +1 -1
- package/esm/rules/transition-delay.js.map +1 -1
- package/esm/rules/transition-duration.js.map +1 -1
- package/esm/rules/transition-property.js.map +1 -1
- package/esm/rules/transition-timing-function.js.map +1 -1
- package/esm/rules/transition.js.map +1 -1
- package/esm/rules/user-drag.js +0 -1
- package/esm/rules/user-drag.js.map +1 -1
- package/esm/rules/user-select.js +0 -1
- package/esm/rules/user-select.js.map +1 -1
- package/esm/rules/variable.js.map +1 -1
- package/esm/rules/vertical-align.js.map +1 -1
- package/esm/rules/visibility.js.map +1 -1
- package/esm/rules/white-space.js.map +1 -1
- package/esm/rules/width.js.map +1 -1
- package/esm/rules/will-change.js.map +1 -1
- package/esm/rules/word-break.js.map +1 -1
- package/esm/rules/word-spacing.js.map +1 -1
- package/esm/rules/writing-mode.js.map +1 -1
- package/esm/rules/x.js.map +1 -1
- package/esm/rules/y.js.map +1 -1
- package/esm/rules/z-index.js.map +1 -1
- package/esm/utils/get-border-props.js.map +1 -1
- package/esm/utils/hex-to-rgb.js.map +1 -1
- package/esm/utils/is-symbol.js.map +1 -1
- package/esm/utils/normalize-css-calc-text.js.map +1 -1
- package/esm/utils/parse-value-unit.js.map +1 -1
- package/esm/utils/parse-value.js +1 -2
- package/esm/utils/parse-value.js.map +1 -1
- package/esm/utils/rgb-to-hex.js.map +1 -1
- package/index.js +1 -1
- package/index.js.map +4 -4
- package/package.json +1 -1
- package/esm/configure.js.map +0 -1
- package/esm/fill-color-scale.js.map +0 -1
- package/esm/init.d.ts +0 -3
- package/esm/init.js.map +0 -1
- package/esm/render-from-html.js.map +0 -1
- package/esm/render-into-html.js.map +0 -1
- package/esm/render.js.map +0 -1
- package/esm/utils/extend.js.map +0 -1
- package/esm/utils/test-css.d.ts +0 -3
- package/esm/utils/test-css.js +0 -16
- package/esm/utils/test-css.js.map +0 -1
package/esm/css.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import defaultConfig from './config';
|
|
2
|
-
import { init } from './init';
|
|
1
|
+
import { defaultConfig } from './config';
|
|
2
|
+
import { init } from './apis/init';
|
|
3
3
|
import { MasterCSSRule } from './rule';
|
|
4
4
|
const selectorSymbols = [',', '.', '#', '[', '!', '*', '>', '+', '~', ':', '@'];
|
|
5
5
|
const vendorPrefixSelectorRegExp = /^::-[a-z]+-/m;
|
|
@@ -18,7 +18,7 @@ const MutationObserver = isBrowser
|
|
|
18
18
|
: Object;
|
|
19
19
|
export default class MasterCSS extends MutationObserver {
|
|
20
20
|
config;
|
|
21
|
-
|
|
21
|
+
root;
|
|
22
22
|
static init = init;
|
|
23
23
|
static defaultConfig = defaultConfig;
|
|
24
24
|
static instances = [];
|
|
@@ -34,155 +34,8 @@ export default class MasterCSS extends MutationObserver {
|
|
|
34
34
|
style;
|
|
35
35
|
rules = [];
|
|
36
36
|
ruleOfClass = {};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.semantics = [];
|
|
40
|
-
this.classes = {};
|
|
41
|
-
this.colorsThemesMap = {};
|
|
42
|
-
this.relationThemesMap = {};
|
|
43
|
-
this.relations = {};
|
|
44
|
-
this.colorNames = [];
|
|
45
|
-
this.themeNames = [''];
|
|
46
|
-
this.selectors = {};
|
|
47
|
-
const { semantics, classes, selectors, themes, colors } = this.config;
|
|
48
|
-
function escapeString(str) {
|
|
49
|
-
return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
50
|
-
}
|
|
51
|
-
if (semantics) {
|
|
52
|
-
for (const semanticName in semantics) {
|
|
53
|
-
this.semantics.push([new RegExp('^' + escapeString(semanticName) + '(?=!|\\*|>|\\+|~|:|\\[|@|_|\\.|$)', 'm'), semanticName]);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (selectors) {
|
|
57
|
-
for (const [replacedSelectorText, newSelectorText] of Object.entries(selectors)) {
|
|
58
|
-
const regexp = new RegExp(escapeString(replacedSelectorText) + '(?![a-z-])');
|
|
59
|
-
for (const eachNewSelectorText of Array.isArray(newSelectorText) ? newSelectorText : [newSelectorText]) {
|
|
60
|
-
const vendor = eachNewSelectorText.match(vendorPrefixSelectorRegExp)?.[0] ?? '';
|
|
61
|
-
let selectorValues = this.selectors[vendor];
|
|
62
|
-
if (!selectorValues) {
|
|
63
|
-
selectorValues = this.selectors[vendor] = [];
|
|
64
|
-
}
|
|
65
|
-
let currentSelectValue = selectorValues.find(([_valueRegexp]) => _valueRegexp === regexp);
|
|
66
|
-
if (!currentSelectValue) {
|
|
67
|
-
currentSelectValue = [regexp, []];
|
|
68
|
-
selectorValues.push(currentSelectValue);
|
|
69
|
-
}
|
|
70
|
-
currentSelectValue[1].push(eachNewSelectorText);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
const semanticNames = [
|
|
75
|
-
...(classes ? Object.keys(classes) : []),
|
|
76
|
-
...((themes && !Array.isArray(themes))
|
|
77
|
-
? Object.entries(themes).flatMap(([_, { classes }]) => classes ? Object.keys(classes) : [])
|
|
78
|
-
: [])
|
|
79
|
-
];
|
|
80
|
-
const handleSemanticName = (semanticName) => {
|
|
81
|
-
if (semanticName in this.classes)
|
|
82
|
-
return;
|
|
83
|
-
const currentClass = this.classes[semanticName] = [];
|
|
84
|
-
const handleClassNames = (theme, className) => {
|
|
85
|
-
if (!className)
|
|
86
|
-
return;
|
|
87
|
-
const classNames = Array.isArray(className)
|
|
88
|
-
? className
|
|
89
|
-
: className
|
|
90
|
-
.replace(/(?:\n(?:\s*))+/g, ' ')
|
|
91
|
-
.trim()
|
|
92
|
-
.split(' ');
|
|
93
|
-
for (const eachClassName of classNames) {
|
|
94
|
-
const handle = (className) => {
|
|
95
|
-
if (className in this.relationThemesMap) {
|
|
96
|
-
if (theme in this.relationThemesMap[className]) {
|
|
97
|
-
this.relationThemesMap[className][theme].push(semanticName);
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
this.relationThemesMap[className][theme] = [semanticName];
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
this.relationThemesMap[className] = { [theme]: [semanticName] };
|
|
105
|
-
}
|
|
106
|
-
if (!currentClass.includes(className)) {
|
|
107
|
-
currentClass.push(className);
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
if (semanticNames.includes(eachClassName)) {
|
|
111
|
-
handleSemanticName(eachClassName);
|
|
112
|
-
for (const parentClassName of this.classes[eachClassName]) {
|
|
113
|
-
handle(parentClassName);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
handle(eachClassName);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
handleClassNames('', classes?.[semanticName]);
|
|
122
|
-
if (themes && !Array.isArray(themes)) {
|
|
123
|
-
for (const [eachTheme, { classes }] of Object.entries(themes)) {
|
|
124
|
-
handleClassNames(eachTheme, classes?.[semanticName]);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
for (const eachSemanticName of semanticNames) {
|
|
129
|
-
handleSemanticName(eachSemanticName);
|
|
130
|
-
}
|
|
131
|
-
for (const className in this.relationThemesMap) {
|
|
132
|
-
const currentRelation = this.relations[className] = [];
|
|
133
|
-
for (const semanticNames of Object.values(this.relationThemesMap[className])) {
|
|
134
|
-
for (const eachSemanticName of semanticNames) {
|
|
135
|
-
if (!currentRelation.includes(eachSemanticName)) {
|
|
136
|
-
currentRelation.push(eachSemanticName);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
const mergeColors = (theme, colors) => {
|
|
142
|
-
if (!colors)
|
|
143
|
-
return;
|
|
144
|
-
for (const colorName in colors) {
|
|
145
|
-
let levels = colors[colorName];
|
|
146
|
-
if (typeof levels === 'string') {
|
|
147
|
-
levels = { '': levels };
|
|
148
|
-
}
|
|
149
|
-
if (colorName in this.colorsThemesMap) {
|
|
150
|
-
const levelsThemes = this.colorsThemesMap[colorName];
|
|
151
|
-
for (const level in levels) {
|
|
152
|
-
const color = levels[level];
|
|
153
|
-
if (level in levelsThemes) {
|
|
154
|
-
levelsThemes[level][theme] = color;
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
levelsThemes[level] = { [theme]: color };
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
this.colorNames.push(colorName);
|
|
163
|
-
this.colorsThemesMap[colorName] = Object
|
|
164
|
-
.entries(levels)
|
|
165
|
-
.reduce((obj, [level, color]) => {
|
|
166
|
-
obj[level] = { [theme]: color };
|
|
167
|
-
return obj;
|
|
168
|
-
}, {});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
mergeColors('', colors);
|
|
173
|
-
if (themes) {
|
|
174
|
-
if (Array.isArray(themes)) {
|
|
175
|
-
this.themeNames.push(...themes);
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
for (const eachTheme in themes) {
|
|
179
|
-
const themeValue = themes[eachTheme];
|
|
180
|
-
mergeColors(eachTheme, themeValue.colors);
|
|
181
|
-
this.themeNames.push(eachTheme);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
37
|
+
countOfClass = {};
|
|
38
|
+
host;
|
|
186
39
|
semantics;
|
|
187
40
|
classes;
|
|
188
41
|
colorsThemesMap;
|
|
@@ -191,7 +44,8 @@ export default class MasterCSS extends MutationObserver {
|
|
|
191
44
|
relationThemesMap;
|
|
192
45
|
relations;
|
|
193
46
|
selectors;
|
|
194
|
-
|
|
47
|
+
schemeMQL;
|
|
48
|
+
constructor(config = defaultConfig, root) {
|
|
195
49
|
super((mutationRecords) => {
|
|
196
50
|
// console.time('css engine');
|
|
197
51
|
const correctionOfClassName = {};
|
|
@@ -326,10 +180,10 @@ export default class MasterCSS extends MutationObserver {
|
|
|
326
180
|
}
|
|
327
181
|
for (const className in correctionOfClassName) {
|
|
328
182
|
const correction = correctionOfClassName[className];
|
|
329
|
-
const count = (this.
|
|
183
|
+
const count = (this.countOfClass[className] || 0) + correction;
|
|
330
184
|
if (count === 0) {
|
|
331
185
|
// remove
|
|
332
|
-
delete this.
|
|
186
|
+
delete this.countOfClass[className];
|
|
333
187
|
/**
|
|
334
188
|
* class name 從 DOM tree 中被移除,
|
|
335
189
|
* 匹配並刪除對應的 rule
|
|
@@ -337,7 +191,7 @@ export default class MasterCSS extends MutationObserver {
|
|
|
337
191
|
this.delete(className);
|
|
338
192
|
}
|
|
339
193
|
else {
|
|
340
|
-
if (!(className in this.
|
|
194
|
+
if (!(className in this.countOfClass)) {
|
|
341
195
|
// add
|
|
342
196
|
/**
|
|
343
197
|
* 新 class name 被 connected 至 DOM tree,
|
|
@@ -345,27 +199,28 @@ export default class MasterCSS extends MutationObserver {
|
|
|
345
199
|
*/
|
|
346
200
|
this.findAndInsert(className);
|
|
347
201
|
}
|
|
348
|
-
this.
|
|
202
|
+
this.countOfClass[className] = count;
|
|
349
203
|
}
|
|
350
204
|
}
|
|
351
205
|
// console.timeEnd('css engine');
|
|
352
206
|
});
|
|
353
207
|
this.config = config;
|
|
354
|
-
this.
|
|
208
|
+
this.root = root;
|
|
355
209
|
this.cache();
|
|
356
|
-
if (
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
210
|
+
if (hasDocument && root) {
|
|
211
|
+
const isDocumentRoot = root === document;
|
|
212
|
+
this.host = isDocumentRoot ? document.documentElement : root.host;
|
|
213
|
+
// sync theme
|
|
214
|
+
this.scheme = this.storageScheme || config.scheme.preference;
|
|
215
|
+
const container = isDocumentRoot ? document.head : root;
|
|
216
|
+
const styleSheets = isDocumentRoot ? document.styleSheets : root.styleSheets;
|
|
361
217
|
// @ts-ignore
|
|
362
|
-
for (
|
|
218
|
+
for (const sheet of styleSheets) {
|
|
363
219
|
if (sheet.title === 'master') {
|
|
364
|
-
|
|
220
|
+
this.style = sheet.ownerNode;
|
|
365
221
|
}
|
|
366
222
|
}
|
|
367
|
-
if (
|
|
368
|
-
this.style = rootStyle;
|
|
223
|
+
if (this.style) {
|
|
369
224
|
for (let index = 0; index < this.style.sheet.cssRules.length; index++) {
|
|
370
225
|
const getRule = (cssRule) => {
|
|
371
226
|
if (cssRule.selectorText) {
|
|
@@ -421,31 +276,223 @@ export default class MasterCSS extends MutationObserver {
|
|
|
421
276
|
else {
|
|
422
277
|
this.style = STYLE.cloneNode();
|
|
423
278
|
/** 使用 prepend 而非 append 去降低 rules 類的優先層級,無法強制排在所有 <style> 之後 */
|
|
424
|
-
|
|
279
|
+
container.prepend(this.style);
|
|
425
280
|
}
|
|
426
281
|
}
|
|
427
282
|
MasterCSS.instances.push(this);
|
|
428
283
|
}
|
|
429
|
-
|
|
284
|
+
get storageScheme() {
|
|
285
|
+
const { storage } = this.config.scheme;
|
|
286
|
+
return localStorage.getItem(storage.key);
|
|
287
|
+
}
|
|
288
|
+
#scheme;
|
|
289
|
+
theme;
|
|
290
|
+
set scheme(scheme) {
|
|
291
|
+
if (scheme !== this.#scheme) {
|
|
292
|
+
this.#scheme = scheme;
|
|
293
|
+
let theme = '';
|
|
294
|
+
const { storage } = this.config.scheme;
|
|
295
|
+
if (scheme === 'system') {
|
|
296
|
+
// 按照系統的主題切換,目前只支援 light dark
|
|
297
|
+
this.schemeMQL = window.matchMedia('(prefers-color-scheme:dark)');
|
|
298
|
+
this.schemeMQL.addEventListener('change', this.onSchemeChange);
|
|
299
|
+
localStorage.removeItem(storage.key);
|
|
300
|
+
theme = this.schemeMQL.matches ? 'dark' : 'light';
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
this.removeSchemeListener();
|
|
304
|
+
theme = scheme;
|
|
305
|
+
if (this.storageScheme !== theme && storage.sync) {
|
|
306
|
+
localStorage.setItem(storage.key, theme);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (this.theme) {
|
|
310
|
+
this.host.classList.remove(this.theme);
|
|
311
|
+
}
|
|
312
|
+
if (this.host === document.documentElement) {
|
|
313
|
+
this.host.style.colorScheme = theme;
|
|
314
|
+
}
|
|
315
|
+
this.host.classList.add(theme);
|
|
316
|
+
this.theme = theme;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
removeSchemeListener() {
|
|
320
|
+
if (this.schemeMQL) {
|
|
321
|
+
this.schemeMQL.removeEventListener('change', this.onSchemeChange);
|
|
322
|
+
this.schemeMQL = null;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
onSchemeChange(mediaQueryList) {
|
|
326
|
+
this.scheme = mediaQueryList.matches ? 'dark' : 'light';
|
|
327
|
+
}
|
|
328
|
+
cache() {
|
|
329
|
+
this.semantics = [];
|
|
330
|
+
this.classes = {};
|
|
331
|
+
this.colorsThemesMap = {};
|
|
332
|
+
this.relationThemesMap = {};
|
|
333
|
+
this.relations = {};
|
|
334
|
+
this.colorNames = [];
|
|
335
|
+
this.themeNames = [''];
|
|
336
|
+
this.selectors = {};
|
|
337
|
+
const { semantics, classes, selectors, themes, colors } = this.config;
|
|
338
|
+
function escapeString(str) {
|
|
339
|
+
return str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
340
|
+
}
|
|
341
|
+
if (semantics) {
|
|
342
|
+
for (const semanticName in semantics) {
|
|
343
|
+
this.semantics.push([new RegExp('^' + escapeString(semanticName) + '(?=!|\\*|>|\\+|~|:|\\[|@|_|\\.|$)', 'm'), semanticName]);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (selectors) {
|
|
347
|
+
for (const [replacedSelectorText, newSelectorText] of Object.entries(selectors)) {
|
|
348
|
+
const regexp = new RegExp(escapeString(replacedSelectorText) + '(?![a-z-])');
|
|
349
|
+
for (const eachNewSelectorText of Array.isArray(newSelectorText) ? newSelectorText : [newSelectorText]) {
|
|
350
|
+
const vendor = eachNewSelectorText.match(vendorPrefixSelectorRegExp)?.[0] ?? '';
|
|
351
|
+
let selectorValues = this.selectors[vendor];
|
|
352
|
+
if (!selectorValues) {
|
|
353
|
+
selectorValues = this.selectors[vendor] = [];
|
|
354
|
+
}
|
|
355
|
+
let currentSelectValue = selectorValues.find(([_valueRegexp]) => _valueRegexp === regexp);
|
|
356
|
+
if (!currentSelectValue) {
|
|
357
|
+
currentSelectValue = [regexp, []];
|
|
358
|
+
selectorValues.push(currentSelectValue);
|
|
359
|
+
}
|
|
360
|
+
currentSelectValue[1].push(eachNewSelectorText);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const semanticNames = [
|
|
365
|
+
...(classes ? Object.keys(classes) : []),
|
|
366
|
+
...((themes && !Array.isArray(themes))
|
|
367
|
+
? Object.entries(themes).flatMap(([_, { classes }]) => classes ? Object.keys(classes) : [])
|
|
368
|
+
: [])
|
|
369
|
+
];
|
|
370
|
+
const handleSemanticName = (semanticName) => {
|
|
371
|
+
if (semanticName in this.classes)
|
|
372
|
+
return;
|
|
373
|
+
const currentClass = this.classes[semanticName] = [];
|
|
374
|
+
const handleClassNames = (theme, className) => {
|
|
375
|
+
if (!className)
|
|
376
|
+
return;
|
|
377
|
+
const classNames = Array.isArray(className)
|
|
378
|
+
? className
|
|
379
|
+
: className
|
|
380
|
+
.replace(/(?:\n(?:\s*))+/g, ' ')
|
|
381
|
+
.trim()
|
|
382
|
+
.split(' ');
|
|
383
|
+
for (const eachClassName of classNames) {
|
|
384
|
+
const handle = (className) => {
|
|
385
|
+
if (className in this.relationThemesMap) {
|
|
386
|
+
if (theme in this.relationThemesMap[className]) {
|
|
387
|
+
this.relationThemesMap[className][theme].push(semanticName);
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
this.relationThemesMap[className][theme] = [semanticName];
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
this.relationThemesMap[className] = { [theme]: [semanticName] };
|
|
395
|
+
}
|
|
396
|
+
if (!currentClass.includes(className)) {
|
|
397
|
+
currentClass.push(className);
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
if (semanticNames.includes(eachClassName)) {
|
|
401
|
+
handleSemanticName(eachClassName);
|
|
402
|
+
for (const parentClassName of this.classes[eachClassName]) {
|
|
403
|
+
handle(parentClassName);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
handle(eachClassName);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
handleClassNames('', classes?.[semanticName]);
|
|
412
|
+
if (themes && !Array.isArray(themes)) {
|
|
413
|
+
for (const [eachTheme, { classes }] of Object.entries(themes)) {
|
|
414
|
+
handleClassNames(eachTheme, classes?.[semanticName]);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
for (const eachSemanticName of semanticNames) {
|
|
419
|
+
handleSemanticName(eachSemanticName);
|
|
420
|
+
}
|
|
421
|
+
for (const className in this.relationThemesMap) {
|
|
422
|
+
const currentRelation = this.relations[className] = [];
|
|
423
|
+
for (const semanticNames of Object.values(this.relationThemesMap[className])) {
|
|
424
|
+
for (const eachSemanticName of semanticNames) {
|
|
425
|
+
if (!currentRelation.includes(eachSemanticName)) {
|
|
426
|
+
currentRelation.push(eachSemanticName);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
const mergeColors = (theme, colors) => {
|
|
432
|
+
if (!colors)
|
|
433
|
+
return;
|
|
434
|
+
for (const colorName in colors) {
|
|
435
|
+
let levels = colors[colorName];
|
|
436
|
+
if (typeof levels === 'string') {
|
|
437
|
+
levels = { '': levels };
|
|
438
|
+
}
|
|
439
|
+
if (colorName in this.colorsThemesMap) {
|
|
440
|
+
const levelsThemes = this.colorsThemesMap[colorName];
|
|
441
|
+
for (const level in levels) {
|
|
442
|
+
const color = levels[level];
|
|
443
|
+
if (level in levelsThemes) {
|
|
444
|
+
levelsThemes[level][theme] = color;
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
levelsThemes[level] = { [theme]: color };
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
this.colorNames.push(colorName);
|
|
453
|
+
this.colorsThemesMap[colorName] = Object
|
|
454
|
+
.entries(levels)
|
|
455
|
+
.reduce((obj, [level, color]) => {
|
|
456
|
+
obj[level] = { [theme]: color };
|
|
457
|
+
return obj;
|
|
458
|
+
}, {});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
mergeColors('', colors);
|
|
463
|
+
if (themes) {
|
|
464
|
+
if (Array.isArray(themes)) {
|
|
465
|
+
this.themeNames.push(...themes);
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
for (const eachTheme in themes) {
|
|
469
|
+
const themeValue = themes[eachTheme];
|
|
470
|
+
mergeColors(eachTheme, themeValue.colors);
|
|
471
|
+
this.themeNames.push(eachTheme);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
observe(options = { subtree: true, childList: true }) {
|
|
430
477
|
if (options.subtree) {
|
|
431
478
|
/**
|
|
432
479
|
* 待所有 DOM 結構完成解析後,開始繪製 MasterCSSRule 樣式
|
|
433
480
|
*/
|
|
434
|
-
|
|
481
|
+
this.host
|
|
435
482
|
.querySelectorAll('[class]')
|
|
436
483
|
.forEach((element) => {
|
|
437
484
|
element.classList.forEach((className) => {
|
|
438
|
-
if (className in this.
|
|
439
|
-
this.
|
|
485
|
+
if (className in this.countOfClass) {
|
|
486
|
+
this.countOfClass[className]++;
|
|
440
487
|
}
|
|
441
488
|
else {
|
|
442
|
-
this.
|
|
489
|
+
this.countOfClass[className] = 1;
|
|
443
490
|
this.findAndInsert(className);
|
|
444
491
|
}
|
|
445
492
|
});
|
|
446
493
|
});
|
|
447
494
|
}
|
|
448
|
-
super.observe(
|
|
495
|
+
super.observe(this.root, {
|
|
449
496
|
...options,
|
|
450
497
|
attributes: true,
|
|
451
498
|
attributeOldValue: true,
|
|
@@ -458,7 +505,7 @@ export default class MasterCSS extends MutationObserver {
|
|
|
458
505
|
// @ts-ignore
|
|
459
506
|
this.ruleOfClass = {};
|
|
460
507
|
// @ts-ignore
|
|
461
|
-
this.
|
|
508
|
+
this.countOfClass = {};
|
|
462
509
|
this.rules.length = 0;
|
|
463
510
|
const sheet = this.style.sheet;
|
|
464
511
|
if (sheet) {
|
|
@@ -510,7 +557,7 @@ export default class MasterCSS extends MutationObserver {
|
|
|
510
557
|
* 拿當前所有的 classNames 按照最新的 colors, breakpoints, config.Rules 匹配並生成新的 style
|
|
511
558
|
* 所以 refresh 過後 rules 可能會變多也可能會變少
|
|
512
559
|
*/
|
|
513
|
-
for (const name in this.
|
|
560
|
+
for (const name in this.countOfClass) {
|
|
514
561
|
this.findAndInsert(name);
|
|
515
562
|
}
|
|
516
563
|
}
|
|
@@ -519,6 +566,7 @@ export default class MasterCSS extends MutationObserver {
|
|
|
519
566
|
this.disconnect();
|
|
520
567
|
instances.splice(instances.indexOf(this), 1);
|
|
521
568
|
this.style.remove();
|
|
569
|
+
this.removeSchemeListener();
|
|
522
570
|
}
|
|
523
571
|
/**
|
|
524
572
|
* 1. where
|
|
@@ -549,7 +597,6 @@ export default class MasterCSS extends MutationObserver {
|
|
|
549
597
|
const endIndex = this.rules.length - 1;
|
|
550
598
|
const { media, order, prioritySelectorIndex, hasWhere, className } = rule;
|
|
551
599
|
const findPrioritySelectorInsertIndex = (rules, findStartIndex, findEndIndex, ignoreRule) => {
|
|
552
|
-
let targetRules;
|
|
553
600
|
let sIndex = 0;
|
|
554
601
|
let eIndex;
|
|
555
602
|
// 1. 找尋目標陣列
|
|
@@ -565,7 +612,7 @@ export default class MasterCSS extends MutationObserver {
|
|
|
565
612
|
if (eIndex === undefined || eIndex === -1) {
|
|
566
613
|
eIndex = rules.length;
|
|
567
614
|
}
|
|
568
|
-
targetRules = rules.slice(sIndex, eIndex);
|
|
615
|
+
const targetRules = rules.slice(sIndex, eIndex);
|
|
569
616
|
// 2. 由目標陣列找尋插入點
|
|
570
617
|
for (let i = 0; i < targetRules.length; i++) {
|
|
571
618
|
const currentRule = targetRules[i];
|
|
@@ -864,7 +911,7 @@ export default class MasterCSS extends MutationObserver {
|
|
|
864
911
|
const deleteRule = (name) => {
|
|
865
912
|
const rule = this.ruleOfClass[name];
|
|
866
913
|
if (!rule
|
|
867
|
-
|| name in this.relations && this.relations[name].some(eachClassName => eachClassName in this.
|
|
914
|
+
|| name in this.relations && this.relations[name].some(eachClassName => eachClassName in this.countOfClass))
|
|
868
915
|
return;
|
|
869
916
|
if (rule.natives.length) {
|
|
870
917
|
const firstNative = rule.natives[0];
|
|
@@ -883,7 +930,7 @@ export default class MasterCSS extends MutationObserver {
|
|
|
883
930
|
};
|
|
884
931
|
if (className in this.classes) {
|
|
885
932
|
for (const eachClassName of this.classes[className]) {
|
|
886
|
-
if (!(eachClassName in this.
|
|
933
|
+
if (!(eachClassName in this.countOfClass)) {
|
|
887
934
|
deleteRule(eachClassName);
|
|
888
935
|
}
|
|
889
936
|
}
|