@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.
Files changed (283) hide show
  1. package/esm/{configure.d.ts → apis/configure.d.ts} +1 -1
  2. package/esm/{configure.js → apis/configure.js} +2 -2
  3. package/esm/apis/configure.js.map +1 -0
  4. package/esm/{utils → apis}/extend.d.ts +0 -0
  5. package/esm/{utils → apis}/extend.js +3 -3
  6. package/esm/apis/extend.js.map +1 -0
  7. package/esm/{fill-color-scale.d.ts → apis/fill-color-scale.d.ts} +0 -0
  8. package/esm/{fill-color-scale.js → apis/fill-color-scale.js} +2 -2
  9. package/esm/apis/fill-color-scale.js.map +1 -0
  10. package/esm/apis/index.d.ts +7 -0
  11. package/esm/apis/index.js +8 -0
  12. package/esm/apis/index.js.map +1 -0
  13. package/esm/apis/init.d.ts +3 -0
  14. package/esm/{init.js → apis/init.js} +3 -3
  15. package/esm/apis/init.js.map +1 -0
  16. package/esm/{render-from-html.d.ts → apis/render-from-html.d.ts} +2 -2
  17. package/esm/{render-from-html.js → apis/render-from-html.js} +5 -5
  18. package/esm/apis/render-from-html.js.map +1 -0
  19. package/esm/{render-into-html.d.ts → apis/render-into-html.d.ts} +2 -2
  20. package/esm/{render-into-html.js → apis/render-into-html.js} +2 -2
  21. package/esm/apis/render-into-html.js.map +1 -0
  22. package/esm/{render.d.ts → apis/render.d.ts} +2 -2
  23. package/esm/{render.js → apis/render.js} +4 -4
  24. package/esm/apis/render.js.map +1 -0
  25. package/esm/config/breakpoints.js.map +1 -1
  26. package/esm/config/colors.js +1 -1
  27. package/esm/config/colors.js.map +1 -1
  28. package/esm/config/index.d.ts +10 -1
  29. package/esm/config/index.js +3 -1
  30. package/esm/config/index.js.map +1 -1
  31. package/esm/config/root-size.js.map +1 -1
  32. package/esm/config/rules.js.map +1 -1
  33. package/esm/config/scheme.d.ts +8 -0
  34. package/esm/config/scheme.js +9 -0
  35. package/esm/config/scheme.js.map +1 -0
  36. package/esm/config/values.js.map +1 -1
  37. package/esm/constants/start-symbol.js.map +1 -1
  38. package/esm/css.d.ts +16 -8
  39. package/esm/css.js +227 -180
  40. package/esm/css.js.map +1 -1
  41. package/esm/index.d.ts +2 -16
  42. package/esm/index.js +2 -16
  43. package/esm/index.js.map +1 -1
  44. package/esm/interfaces/config.d.ts +7 -0
  45. package/esm/polyfills/css-escape.js +1 -1
  46. package/esm/polyfills/css-escape.js.map +1 -1
  47. package/esm/rule.js +9 -10
  48. package/esm/rule.js.map +1 -1
  49. package/esm/rules/accent-color.js.map +1 -1
  50. package/esm/rules/align-content.js.map +1 -1
  51. package/esm/rules/align-items.js.map +1 -1
  52. package/esm/rules/align-self.js.map +1 -1
  53. package/esm/rules/animation-delay.js +1 -1
  54. package/esm/rules/animation-delay.js.map +1 -1
  55. package/esm/rules/animation-direction.js +1 -1
  56. package/esm/rules/animation-direction.js.map +1 -1
  57. package/esm/rules/animation-duration.js +1 -1
  58. package/esm/rules/animation-duration.js.map +1 -1
  59. package/esm/rules/animation-fill-mode.js +1 -1
  60. package/esm/rules/animation-fill-mode.js.map +1 -1
  61. package/esm/rules/animation-iteration-count.js +1 -1
  62. package/esm/rules/animation-iteration-count.js.map +1 -1
  63. package/esm/rules/animation-name.js +1 -1
  64. package/esm/rules/animation-name.js.map +1 -1
  65. package/esm/rules/animation-play-state.js +1 -1
  66. package/esm/rules/animation-play-state.js.map +1 -1
  67. package/esm/rules/animation-timing-function.js +1 -1
  68. package/esm/rules/animation-timing-function.js.map +1 -1
  69. package/esm/rules/animation.js.map +1 -1
  70. package/esm/rules/appearance.js.map +1 -1
  71. package/esm/rules/aspect-radio.js.map +1 -1
  72. package/esm/rules/backdrop-filter.js +0 -1
  73. package/esm/rules/backdrop-filter.js.map +1 -1
  74. package/esm/rules/background-attachment.js.map +1 -1
  75. package/esm/rules/background-blend-mode.js.map +1 -1
  76. package/esm/rules/background-clip.js.map +1 -1
  77. package/esm/rules/background-color.js.map +1 -1
  78. package/esm/rules/background-image.js.map +1 -1
  79. package/esm/rules/background-origin.js.map +1 -1
  80. package/esm/rules/background-position.js.map +1 -1
  81. package/esm/rules/background-repeat.js.map +1 -1
  82. package/esm/rules/background-size.js.map +1 -1
  83. package/esm/rules/background.js.map +1 -1
  84. package/esm/rules/border-collapse.js.map +1 -1
  85. package/esm/rules/border-color.js +1 -1
  86. package/esm/rules/border-color.js.map +1 -1
  87. package/esm/rules/border-image-outset.js.map +1 -1
  88. package/esm/rules/border-image-repeat.js.map +1 -1
  89. package/esm/rules/border-image-slice.js.map +1 -1
  90. package/esm/rules/border-image-source.js.map +1 -1
  91. package/esm/rules/border-image-width.js.map +1 -1
  92. package/esm/rules/border-image.js.map +1 -1
  93. package/esm/rules/border-radius.js +1 -1
  94. package/esm/rules/border-radius.js.map +1 -1
  95. package/esm/rules/border-spacing.js.map +1 -1
  96. package/esm/rules/border-style.js +1 -1
  97. package/esm/rules/border-style.js.map +1 -1
  98. package/esm/rules/border-width.js +1 -1
  99. package/esm/rules/border-width.js.map +1 -1
  100. package/esm/rules/border.js +1 -1
  101. package/esm/rules/border.js.map +1 -1
  102. package/esm/rules/box-decoration-break.js +0 -1
  103. package/esm/rules/box-decoration-break.js.map +1 -1
  104. package/esm/rules/box-shadow.js.map +1 -1
  105. package/esm/rules/box-sizing.js.map +1 -1
  106. package/esm/rules/break-after.js.map +1 -1
  107. package/esm/rules/break-before.js.map +1 -1
  108. package/esm/rules/break-inside.js.map +1 -1
  109. package/esm/rules/caret-color.js.map +1 -1
  110. package/esm/rules/clear.js.map +1 -1
  111. package/esm/rules/clip-path.js.map +1 -1
  112. package/esm/rules/color.js.map +1 -1
  113. package/esm/rules/column-span.js.map +1 -1
  114. package/esm/rules/columns.js.map +1 -1
  115. package/esm/rules/contain.js.map +1 -1
  116. package/esm/rules/content.js.map +1 -1
  117. package/esm/rules/counter-increment.js.map +1 -1
  118. package/esm/rules/cursor.js.map +1 -1
  119. package/esm/rules/cx.js.map +1 -1
  120. package/esm/rules/cy.js.map +1 -1
  121. package/esm/rules/direction.js.map +1 -1
  122. package/esm/rules/display.js.map +1 -1
  123. package/esm/rules/fill.js.map +1 -1
  124. package/esm/rules/filter.js.map +1 -1
  125. package/esm/rules/flex-basis.js.map +1 -1
  126. package/esm/rules/flex-direction.js.map +1 -1
  127. package/esm/rules/flex-grow.js.map +1 -1
  128. package/esm/rules/flex-shrink.js.map +1 -1
  129. package/esm/rules/flex-wrap.js.map +1 -1
  130. package/esm/rules/flex.js.map +1 -1
  131. package/esm/rules/float.js.map +1 -1
  132. package/esm/rules/font-family.js.map +1 -1
  133. package/esm/rules/font-size.js.map +1 -1
  134. package/esm/rules/font-smoothing.js +0 -1
  135. package/esm/rules/font-smoothing.js.map +1 -1
  136. package/esm/rules/font-style.js.map +1 -1
  137. package/esm/rules/font-variant-numeric.js.map +1 -1
  138. package/esm/rules/font-weight.js.map +1 -1
  139. package/esm/rules/font.js.map +1 -1
  140. package/esm/rules/gap.js.map +1 -1
  141. package/esm/rules/grid-area.js.map +1 -1
  142. package/esm/rules/grid-auto-columns.js.map +1 -1
  143. package/esm/rules/grid-auto-flow.js.map +1 -1
  144. package/esm/rules/grid-auto-rows.js.map +1 -1
  145. package/esm/rules/grid-column-end.js.map +1 -1
  146. package/esm/rules/grid-column-start.js.map +1 -1
  147. package/esm/rules/grid-column.js.map +1 -1
  148. package/esm/rules/grid-columns.js.map +1 -1
  149. package/esm/rules/grid-row-end.js.map +1 -1
  150. package/esm/rules/grid-row-start.js.map +1 -1
  151. package/esm/rules/grid-row.js.map +1 -1
  152. package/esm/rules/grid-rows.js.map +1 -1
  153. package/esm/rules/grid-template-areas.js.map +1 -1
  154. package/esm/rules/grid-template-columns.js.map +1 -1
  155. package/esm/rules/grid-template-rows.js.map +1 -1
  156. package/esm/rules/grid-template.js.map +1 -1
  157. package/esm/rules/grid.js.map +1 -1
  158. package/esm/rules/group.js.map +1 -1
  159. package/esm/rules/height.js.map +1 -1
  160. package/esm/rules/inset.js.map +1 -1
  161. package/esm/rules/isolation.js.map +1 -1
  162. package/esm/rules/justify-content.js.map +1 -1
  163. package/esm/rules/justify-items.js.map +1 -1
  164. package/esm/rules/justify-self.js.map +1 -1
  165. package/esm/rules/letter-spacing.js.map +1 -1
  166. package/esm/rules/line-clamp.js.map +1 -1
  167. package/esm/rules/line-height.js.map +1 -1
  168. package/esm/rules/lines.js.map +1 -1
  169. package/esm/rules/list-style-image.js.map +1 -1
  170. package/esm/rules/list-style-position.js.map +1 -1
  171. package/esm/rules/list-style-type.js.map +1 -1
  172. package/esm/rules/list-style.js.map +1 -1
  173. package/esm/rules/margin.js +1 -1
  174. package/esm/rules/margin.js.map +1 -1
  175. package/esm/rules/mask-image.js.map +1 -1
  176. package/esm/rules/max-height.js.map +1 -1
  177. package/esm/rules/max-width.js.map +1 -1
  178. package/esm/rules/min-height.js.map +1 -1
  179. package/esm/rules/min-width.js.map +1 -1
  180. package/esm/rules/mix-blend-mode.js.map +1 -1
  181. package/esm/rules/object-fit.js.map +1 -1
  182. package/esm/rules/object-position.js.map +1 -1
  183. package/esm/rules/opacity.js.map +1 -1
  184. package/esm/rules/order.js.map +1 -1
  185. package/esm/rules/outline-color.js.map +1 -1
  186. package/esm/rules/outline-offset.js.map +1 -1
  187. package/esm/rules/outline-style.js.map +1 -1
  188. package/esm/rules/outline-width.js.map +1 -1
  189. package/esm/rules/outline.js.map +1 -1
  190. package/esm/rules/overflow.js.map +1 -1
  191. package/esm/rules/overscroll-behavior.js.map +1 -1
  192. package/esm/rules/padding.js.map +1 -1
  193. package/esm/rules/place-content.js.map +1 -1
  194. package/esm/rules/place-items.js.map +1 -1
  195. package/esm/rules/place-self.js.map +1 -1
  196. package/esm/rules/placement.js.map +1 -1
  197. package/esm/rules/pointer-events.js.map +1 -1
  198. package/esm/rules/position.js.map +1 -1
  199. package/esm/rules/quotes.js.map +1 -1
  200. package/esm/rules/resize.js.map +1 -1
  201. package/esm/rules/rx.js.map +1 -1
  202. package/esm/rules/ry.js.map +1 -1
  203. package/esm/rules/scroll-behavior.js.map +1 -1
  204. package/esm/rules/scroll-margin.js.map +1 -1
  205. package/esm/rules/scroll-padding.js.map +1 -1
  206. package/esm/rules/scroll-snap-align.js.map +1 -1
  207. package/esm/rules/scroll-snap-stop.js.map +1 -1
  208. package/esm/rules/scroll-snap-type.js.map +1 -1
  209. package/esm/rules/shape-image-threshold.js.map +1 -1
  210. package/esm/rules/shape-margin.js.map +1 -1
  211. package/esm/rules/shape-outside.js.map +1 -1
  212. package/esm/rules/spacing.js.map +1 -1
  213. package/esm/rules/stroke-dasharray.js.map +1 -1
  214. package/esm/rules/stroke-dashoffset.js.map +1 -1
  215. package/esm/rules/stroke-width.js.map +1 -1
  216. package/esm/rules/stroke.js.map +1 -1
  217. package/esm/rules/table-layout.js.map +1 -1
  218. package/esm/rules/text-align.js.map +1 -1
  219. package/esm/rules/text-decoration-color.js.map +1 -1
  220. package/esm/rules/text-decoration-line.js.map +1 -1
  221. package/esm/rules/text-decoration-style.js.map +1 -1
  222. package/esm/rules/text-decoration-thickness.js.map +1 -1
  223. package/esm/rules/text-decoration.js.map +1 -1
  224. package/esm/rules/text-fill-color.js.map +1 -1
  225. package/esm/rules/text-indent.js.map +1 -1
  226. package/esm/rules/text-orientation.js.map +1 -1
  227. package/esm/rules/text-overflow.js.map +1 -1
  228. package/esm/rules/text-rendering.js.map +1 -1
  229. package/esm/rules/text-shadow.js.map +1 -1
  230. package/esm/rules/text-size.js.map +1 -1
  231. package/esm/rules/text-stroke-color.js.map +1 -1
  232. package/esm/rules/text-stroke-width.js.map +1 -1
  233. package/esm/rules/text-stroke.js.map +1 -1
  234. package/esm/rules/text-transform.js.map +1 -1
  235. package/esm/rules/text-underline-offset.js.map +1 -1
  236. package/esm/rules/touch-action.js.map +1 -1
  237. package/esm/rules/transform-box.js.map +1 -1
  238. package/esm/rules/transform-origin.js.map +1 -1
  239. package/esm/rules/transform-style.js.map +1 -1
  240. package/esm/rules/transform.js.map +1 -1
  241. package/esm/rules/transition-delay.js.map +1 -1
  242. package/esm/rules/transition-duration.js.map +1 -1
  243. package/esm/rules/transition-property.js.map +1 -1
  244. package/esm/rules/transition-timing-function.js.map +1 -1
  245. package/esm/rules/transition.js.map +1 -1
  246. package/esm/rules/user-drag.js +0 -1
  247. package/esm/rules/user-drag.js.map +1 -1
  248. package/esm/rules/user-select.js +0 -1
  249. package/esm/rules/user-select.js.map +1 -1
  250. package/esm/rules/variable.js.map +1 -1
  251. package/esm/rules/vertical-align.js.map +1 -1
  252. package/esm/rules/visibility.js.map +1 -1
  253. package/esm/rules/white-space.js.map +1 -1
  254. package/esm/rules/width.js.map +1 -1
  255. package/esm/rules/will-change.js.map +1 -1
  256. package/esm/rules/word-break.js.map +1 -1
  257. package/esm/rules/word-spacing.js.map +1 -1
  258. package/esm/rules/writing-mode.js.map +1 -1
  259. package/esm/rules/x.js.map +1 -1
  260. package/esm/rules/y.js.map +1 -1
  261. package/esm/rules/z-index.js.map +1 -1
  262. package/esm/utils/get-border-props.js.map +1 -1
  263. package/esm/utils/hex-to-rgb.js.map +1 -1
  264. package/esm/utils/is-symbol.js.map +1 -1
  265. package/esm/utils/normalize-css-calc-text.js.map +1 -1
  266. package/esm/utils/parse-value-unit.js.map +1 -1
  267. package/esm/utils/parse-value.js +1 -2
  268. package/esm/utils/parse-value.js.map +1 -1
  269. package/esm/utils/rgb-to-hex.js.map +1 -1
  270. package/index.js +1 -1
  271. package/index.js.map +4 -4
  272. package/package.json +1 -1
  273. package/esm/configure.js.map +0 -1
  274. package/esm/fill-color-scale.js.map +0 -1
  275. package/esm/init.d.ts +0 -3
  276. package/esm/init.js.map +0 -1
  277. package/esm/render-from-html.js.map +0 -1
  278. package/esm/render-into-html.js.map +0 -1
  279. package/esm/render.js.map +0 -1
  280. package/esm/utils/extend.js.map +0 -1
  281. package/esm/utils/test-css.d.ts +0 -3
  282. package/esm/utils/test-css.js +0 -16
  283. 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
- container;
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
- countOfName = {};
38
- cache() {
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
- constructor(config = defaultConfig, container) {
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.countOfName[className] || 0) + correction;
183
+ const count = (this.countOfClass[className] || 0) + correction;
330
184
  if (count === 0) {
331
185
  // remove
332
- delete this.countOfName[className];
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.countOfName)) {
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.countOfName[className] = count;
202
+ this.countOfClass[className] = count;
349
203
  }
350
204
  }
351
205
  // console.timeEnd('css engine');
352
206
  });
353
207
  this.config = config;
354
- this.container = container;
208
+ this.root = root;
355
209
  this.cache();
356
- if (!hasDocument) {
357
- return;
358
- }
359
- if (container) {
360
- let rootStyle;
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 (let sheet of (container.shadowRoot?.styleSheets || document.styleSheets)) {
218
+ for (const sheet of styleSheets) {
363
219
  if (sheet.title === 'master') {
364
- rootStyle = sheet.ownerNode;
220
+ this.style = sheet.ownerNode;
365
221
  }
366
222
  }
367
- if (rootStyle) {
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
- this.container?.prepend(this.style);
279
+ container.prepend(this.style);
425
280
  }
426
281
  }
427
282
  MasterCSS.instances.push(this);
428
283
  }
429
- observe(target, options = { subtree: true, childList: true }) {
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
- target
481
+ this.host
435
482
  .querySelectorAll('[class]')
436
483
  .forEach((element) => {
437
484
  element.classList.forEach((className) => {
438
- if (className in this.countOfName) {
439
- this.countOfName[className]++;
485
+ if (className in this.countOfClass) {
486
+ this.countOfClass[className]++;
440
487
  }
441
488
  else {
442
- this.countOfName[className] = 1;
489
+ this.countOfClass[className] = 1;
443
490
  this.findAndInsert(className);
444
491
  }
445
492
  });
446
493
  });
447
494
  }
448
- super.observe(target, {
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.countOfName = {};
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.countOfName) {
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.countOfName))
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.countOfName)) {
933
+ if (!(eachClassName in this.countOfClass)) {
887
934
  deleteRule(eachClassName);
888
935
  }
889
936
  }