├── .gitignore
├── README.md
├── moo-css-react
├── .babelrc
├── .prettierrc.js
├── README.md
├── __test__
│ ├── index.css
│ ├── index.html
│ ├── index.js
│ ├── index.jsx
│ ├── test2.json
│ ├── virtualDom-2.json
│ ├── virtualDom-3.json
│ └── virtualDom.json
├── dist
│ ├── handleJsx.js
│ ├── handleVue.js
│ ├── index.js
│ ├── json2html.js
│ └── utils
│ │ └── handleImage.js
├── jest.config.js
├── package.json
├── src
│ ├── handleJsx.ts
│ ├── handleVue.ts
│ ├── index.ts
│ ├── json2html.ts
│ └── types
│ │ └── moo.d.ts
└── tsconfig.json
├── moo-css-sketch
├── package.json
└── tsconfig.json
├── moo-css-transformer
├── .babelrc
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .prettierrc.js
├── README.md
├── build
│ └── getMooDatas.js
├── config.js
├── index.js
├── jest.config.js
├── package.json
├── src
│ ├── c2m.js
│ ├── const.js
│ ├── m2c.js
│ ├── scaner.js
│ └── utils.js
├── test
│ ├── c2m.test.js
│ └── m2c.test.js
├── types
│ └── index.d.ts
└── webpack.config.js
├── moo-css-weapp
├── package.json
└── tsconfig.json
├── moo-css-web
├── .eslintignore
├── .gitignore
├── .prettierrc.js
├── dist
│ ├── index.js
│ ├── json2html.js
│ ├── src
│ │ ├── index.js
│ │ └── json2html.js
│ └── utils
│ │ └── handleImage.js
├── package.json
└── tsconfig.json
└── vscode
└── moo-css-plugin.dev.vsix
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | *.swp
3 | .DS_Store
4 | npm-debug.log
5 | lerna-debug.log
6 | npm-debug.log*
7 | lib/
8 | es/
9 | dist/
10 | build/
11 | coverage/
12 | node_modules/
13 | examples/test
14 | .eslintcache
15 | *.lock
16 |
17 | temp/
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Moo-CSS plugins
2 |
3 | Style automatic development.
4 |
5 |
6 |
7 |
8 |
9 | ## 1.[moo-css-transformer](./moo-css-transformer)
10 |
11 | MooCSS transform tool.mini name style <-> css style. Version: `0.1.0`
12 |
13 | Install:
14 |
15 | ``` sh
16 | npm i --save moo-css-transformer
17 | ```
18 |
19 |
20 |
21 | for example:
22 | ```
23 | f-tc <-> text-align: center
24 | ```
25 |
26 | ## 2.[moo-css-base](https://github.com/MichealWayne/Moo-CSS/tree/master/moo-css-base)
27 |
28 | Moo-CSS base Layer demo, for less/sass/stylus.
29 |
30 | Install:
31 |
32 | ``` sh
33 | npm i --save moo-css-base
34 | ```
35 |
36 |
37 |
38 | ## 3.[moo-css-sketch](./moo-css-sketch)
39 |
40 | analysis sketch file and get Moo-CSS's style sheet.
41 |
42 | ## 3.[moo-css-web](./moo-css-web)
43 |
44 | vritual dom data -> web files(HTML, CSS).
45 |
46 | ## 4.[moo-css-weapp](./moo-css-weapp)
47 |
48 | vritual dom data -> weapp files(wxml, wxss).
49 |
50 | ## 5.[moo-css-server](./moo-css-server)
51 |
52 | platform to handle sketch file.
53 |
54 | ## 6.[vscode](./vscode)
55 |
56 | ## 7.[moo-css-react](./moo-css-react)
57 |
58 | moo-css AST -> React component
59 |
60 | moo-css-base's vscode plugin.
--------------------------------------------------------------------------------
/moo-css-react/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/env",
5 | {
6 | "loose": true
7 | }
8 | ]
9 | ]
10 | }
--------------------------------------------------------------------------------
/moo-css-react/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | printWidth: 100,
3 | tabWidth: 2,
4 | useTabs: false,
5 | singleQuote: true,
6 | semi: true,
7 | trailingComma: 'es5',
8 | bracketSpacing: true,
9 | arrowParens: 'avoid',
10 | };
11 |
--------------------------------------------------------------------------------
/moo-css-react/README.md:
--------------------------------------------------------------------------------
1 | # moo-css-react
2 |
--------------------------------------------------------------------------------
/moo-css-react/__test__/index.css:
--------------------------------------------------------------------------------
1 |
2 | .g-pa {
3 | position:absolute
4 | }
5 | .g-t0 {
6 | top:0px
7 | }
8 | .g-l0 {
9 | left:0px
10 | }
11 | .u-w0 {
12 | width:0px
13 | }
14 | .u-h0 {
15 | height:0px
16 | }
17 | .u-bdw0 {
18 | border-width:0
19 | }
20 | .s-bgc_t {
21 | background-color:transparent
22 | }
23 | .u-w686 {
24 | width:686px
25 | }
26 | .u-h324 {
27 | height:324px
28 | }
29 | .f-ov_h {
30 | overflow:hidden
31 | }
32 | .s-bgc_ffffff {
33 | background-color:rgba(255,255,255,1)
34 | }
35 | .f-bdr16 {
36 | border-radius:16px
37 | }
38 | .u-w718 {
39 | width:718px
40 | }
41 | .u-h145 {
42 | height:145px
43 | }
44 | .z-o40 {
45 | opacity:0.4000000059604645
46 | }
47 | .g-t187 {
48 | top:187px
49 | }
50 | .g-l32 {
51 | left:32px
52 | }
53 | .u-w385 {
54 | width:385px
55 | }
56 | .u-h50 {
57 | height:50px
58 | }
59 | .s-cr_313131 {
60 | color:rgba(49,49,49,1)
61 | }
62 | .g-fs36 {
63 | font-size:36px
64 | }
65 | .f-ff_PM {
66 | font-family:PingFangSC-Medium,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif
67 | }
68 | .f-tl {
69 | text-align:left
70 | }
71 | .g-lh_n {
72 | line-height:normal
73 | }
74 | .g-t207 {
75 | top:207px
76 | }
77 | .g-l518 {
78 | left:518px
79 | }
80 | .u-w136 {
81 | width:136px
82 | }
83 | .u-h56 {
84 | height:56px
85 | }
86 | .s-bgc_fe5d4e {
87 | background-color:rgba(254,93,78,1)
88 | }
89 | .f-bdr8 {
90 | border-radius:8px
91 | }
92 | .g-t218 {
93 | top:218px
94 | }
95 | .g-l538 {
96 | left:538px
97 | }
98 | .u-w96 {
99 | width:96px
100 | }
101 | .u-h33 {
102 | height:33px
103 | }
104 | .s-cr_ffffff {
105 | color:rgba(255,255,255,1)
106 | }
107 | .g-fs24 {
108 | font-size:24px
109 | }
110 | .f-ff_PR {
111 | font-family:PingFangSC-Regular,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif
112 | }
113 | .g-pr {
114 | position:relative
115 | }
116 | .g-t24 {
117 | top:24px
118 | }
119 | .u-w209 {
120 | width:209px
121 | }
122 | .s-cr_364a7f {
123 | color:rgba(54,74,127,1)
124 | }
125 | .g-t39 {
126 | top:39px
127 | }
128 | .g-l641 {
129 | left:641px
130 | }
131 | .u-w13 {
132 | width:13px
133 | }
134 | .u-h22 {
135 | height:22px
136 | }
137 | .g-t81 {
138 | top:81px
139 | }
140 | .u-w78 {
141 | width:78px
142 | }
143 | .u-h37 {
144 | height:37px
145 | }
146 | .g-fs26 {
147 | font-size:26px
148 | }
149 | .g-l130 {
150 | left:130px
151 | }
152 | .u-w26 {
153 | width:26px
154 | }
155 | .s-cr_fe5d4e {
156 | color:rgba(254,93,78,1)
157 | }
158 | .g-l176 {
159 | left:176px
160 | }
161 | .u-w58 {
162 | width:58px
163 | }
164 | .g-l254 {
165 | left:254px
166 | }
167 | .u-w156 {
168 | width:156px
169 | }
170 | .g-l410 {
171 | left:410px
172 | }
173 | .u-w104 {
174 | width:104px
175 | }
176 | .g-t243 {
177 | top:243px
178 | }
179 | .u-w129 {
180 | width:129px
181 | }
182 | .u-h41 {
183 | height:41px
184 | }
185 | .g-fs34 {
186 | font-size:34px
187 | }
188 | .f-ff_DM {
189 | font-family:DIN-Medium,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif
190 | }
191 | .g-t249 {
192 | top:249px
193 | }
194 | .g-l178 {
195 | left:178px
196 | }
197 | .u-w120 {
198 | width:120px
199 | }
200 | .s-cr_999999 {
201 | color:rgba(153,153,153,1)
202 | }
--------------------------------------------------------------------------------
/moo-css-react/__test__/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const testdata = require('./test2.json');
4 | const test = require('../dist/');
5 |
6 | let datas = test.default({
7 | data: testdata,
8 | vueBool: true
9 | });
10 | console.log(datas);
11 | fs.writeFileSync(path.join(__dirname, './index.jsx'), datas.jsx)
12 | fs.writeFileSync(path.join(__dirname, './index.css'), datas.css);
--------------------------------------------------------------------------------
/moo-css-react/__test__/index.jsx:
--------------------------------------------------------------------------------
1 |
2 | import * as Vue from 'vue'
3 | import Component from 'vue-class-component'
4 | import './index.css'
5 |
6 | @Component({
7 | props: {}
8 | })
9 | export default class MyComponent extends Vue {
10 | render () {
11 |
12 | return (
13 |
14 |
17 | 易方达沪深300RTF联接
18 |
19 | 立即购买
20 |
25 |
36 | )
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/moo-css-react/__test__/test2.json:
--------------------------------------------------------------------------------
1 | {
2 | "tagName": "body",
3 | "props": {
4 | "style": {
5 | "position": "absolute",
6 | "top": "0px",
7 | "left": "0px",
8 | "width": "0px",
9 | "height": "0px",
10 | "borderWidth": 0,
11 | "backgroundColor": "transparent"
12 | },
13 | "children": [
14 | {
15 | "tagName": "div",
16 | "props": {
17 | "style": {
18 | "position": "absolute",
19 | "top": "0px",
20 | "left": "0px",
21 | "width": "686px",
22 | "height": "324px",
23 | "borderWidth": 0,
24 | "backgroundColor": "transparent"
25 | },
26 | "children": [
27 | {
28 | "tagName": "div",
29 | "props": {
30 | "style": {
31 | "position": "absolute",
32 | "top": "0px",
33 | "left": "0px",
34 | "width": "686px",
35 | "height": "324px",
36 | "overflow": "hidden",
37 | "boxShadow": "0px 0px 10px 4px rgba(221,221,221,0.16)",
38 | "backgroundColor": "rgba(255,255,255,1)",
39 | "borderRadius": "16px"
40 | },
41 | "children": [
42 | {
43 | "tagName": "div",
44 | "props": {
45 | "style": {
46 | "position": "absolute",
47 | "top": "0px",
48 | "left": "0px",
49 | "width": "718px",
50 | "height": "145px",
51 | "opacity": 0.4000000059604645,
52 | "backgroundImage": "linear-gradient(213deg, rgba(219,225,243,1) 0%,rgba(181,192,234,1) 63.444924464826016%,rgba(139,155,215,1) 100%)",
53 | "borderRadius": "16px"
54 | },
55 | "children": []
56 | },
57 | "id": "48F856A8-DDCF-45ED-9E15-32CBC9BFE734",
58 | "name": "矩形",
59 | "rect": {
60 | "x": 0.25,
61 | "y": 0,
62 | "width": 718.0810706886241,
63 | "height": 145
64 | }
65 | }
66 | ]
67 | },
68 | "id": "1B3CA453-E627-47B8-AD7A-039074FF1736",
69 | "name": "蒙版",
70 | "rect": {
71 | "x": 0,
72 | "y": 0,
73 | "width": 686,
74 | "height": 324
75 | }
76 | }
77 | ]
78 | },
79 | "id": "9F3F16A6-7FAD-43DB-94CF-05ADACE33783",
80 | "name": "矩形",
81 | "rect": {
82 | "x": 0,
83 | "y": 0,
84 | "width": 686,
85 | "height": 324,
86 | "mX": 343,
87 | "mY": 162,
88 | "x1": 686,
89 | "y1": 324
90 | }
91 | },
92 | {
93 | "tagName": "p",
94 | "props": {
95 | "style": {
96 | "position": "absolute",
97 | "top": "187px",
98 | "left": "32px",
99 | "width": "385px",
100 | "height": "50px",
101 | "color": "rgba(49,49,49,1)",
102 | "fontSize": "36px",
103 | "fontFamily": "PingFangSC-Medium,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif",
104 | "textAlign": "left",
105 | "lineHeight": "normal",
106 | "whiteSpace": "nowrap"
107 | },
108 | "text": "易方达沪深300RTF联接"
109 | },
110 | "id": "2514F8C1-0511-4821-9A30-83931477359A",
111 | "name": "易方达沪深300RTF联接",
112 | "rect": {
113 | "x": 32,
114 | "y": 186.5,
115 | "width": 385,
116 | "height": 50,
117 | "mX": 224.5,
118 | "mY": 211.5,
119 | "x1": 417,
120 | "y1": 236.5
121 | }
122 | },
123 | {
124 | "tagName": "div",
125 | "props": {
126 | "style": {
127 | "position": "absolute",
128 | "top": "207px",
129 | "left": "518px",
130 | "width": "136px",
131 | "height": "56px",
132 | "backgroundColor": "rgba(254,93,78,1)",
133 | "borderRadius": "8px"
134 | },
135 | "children": []
136 | },
137 | "id": "18F57906-745F-4CDB-ABBE-BB98D0992F78",
138 | "name": "矩形",
139 | "rect": {
140 | "x": 517.5,
141 | "y": 206.5,
142 | "width": 136,
143 | "height": 56,
144 | "mX": 585.5,
145 | "mY": 234.5,
146 | "x1": 653.5,
147 | "y1": 262.5
148 | }
149 | },
150 | {
151 | "tagName": "p",
152 | "props": {
153 | "style": {
154 | "position": "absolute",
155 | "top": "218px",
156 | "left": "538px",
157 | "width": "96px",
158 | "height": "33px",
159 | "color": "rgba(255,255,255,1)",
160 | "fontSize": "24px",
161 | "fontFamily": "PingFangSC-Regular,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif",
162 | "textAlign": "left",
163 | "lineHeight": "normal",
164 | "whiteSpace": "nowrap"
165 | },
166 | "text": "立即购买"
167 | },
168 | "id": "F808A800-86FB-4404-A042-08FB20ABDC2E",
169 | "name": "立即购买",
170 | "rect": {
171 | "x": 537.5,
172 | "y": 217.5,
173 | "width": 96,
174 | "height": 33,
175 | "mX": 585.5,
176 | "mY": 234,
177 | "x1": 633.5,
178 | "y1": 250.5
179 | }
180 | },
181 | {
182 | "id": "-0A61-47F1-521BE4FDF",
183 | "name": "l-4沪深300指数l-5icon_list_forward",
184 | "direct": "y",
185 | "props": {
186 | "style": {
187 | "position": "relative"
188 | },
189 | "children": [
190 | {
191 | "id": "-1404C1E6F-0A61-47F1",
192 | "name": "l-1沪深300指数",
193 | "direct": "x",
194 | "props": {
195 | "style": {
196 | "position": "relative"
197 | },
198 | "children": [
199 | {
200 | "tagName": "p",
201 | "props": {
202 | "style": {
203 | "position": "absolute",
204 | "top": "24px",
205 | "left": "32px",
206 | "width": "209px",
207 | "height": "50px",
208 | "color": "rgba(54,74,127,1)",
209 | "fontSize": "36px",
210 | "fontFamily": "PingFangSC-Medium,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif",
211 | "textAlign": "left",
212 | "lineHeight": "normal",
213 | "whiteSpace": "nowrap"
214 | },
215 | "text": "沪深300指数"
216 | },
217 | "id": "404C1E6F-0A61-47F1-B7C3-709C624B93BE",
218 | "name": "沪深300指数",
219 | "rect": {
220 | "x": 32,
221 | "y": 24,
222 | "width": 209,
223 | "height": 50,
224 | "mX": 136.5,
225 | "mY": 49,
226 | "x1": 241,
227 | "y1": 74
228 | },
229 | "leaf": true
230 | }
231 | ]
232 | },
233 | "tagName": "div",
234 | "rect": {
235 | "x": 32,
236 | "y": 24,
237 | "x1": 241,
238 | "y1": 74,
239 | "mX": 136.5,
240 | "mY": 49,
241 | "width": 209,
242 | "height": 50
243 | },
244 | "leafWrapper": true
245 | },
246 | {
247 | "id": "-221BE4FDF-C8CE-4465",
248 | "name": "l-2icon_list_forward",
249 | "direct": "x",
250 | "props": {
251 | "style": {
252 | "position": "relative"
253 | },
254 | "children": [
255 | {
256 | "tagName": "div",
257 | "props": {
258 | "style": {
259 | "position": "absolute",
260 | "top": "39px",
261 | "left": "641px",
262 | "width": "13px",
263 | "height": "22px",
264 | "borderWidth": 0,
265 | "backgroundColor": "transparent"
266 | },
267 | "children": null
268 | },
269 | "id": "21BE4FDF-C8CE-4465-B0F3-1CF481CE974D",
270 | "name": "icon_list_forward",
271 | "rect": {
272 | "x": 641,
273 | "y": 39,
274 | "width": 13,
275 | "height": 22,
276 | "mX": 647.5,
277 | "mY": 50,
278 | "x1": 654,
279 | "y1": 61
280 | },
281 | "leaf": true
282 | }
283 | ]
284 | },
285 | "tagName": "div",
286 | "rect": {
287 | "x": 641,
288 | "y": 39,
289 | "x1": 654,
290 | "y1": 61,
291 | "mX": 647.5,
292 | "mY": 50,
293 | "width": 13,
294 | "height": 22
295 | },
296 | "leafWrapper": true
297 | }
298 | ]
299 | },
300 | "tagName": "div",
301 | "rect": {
302 | "x": 32,
303 | "y": 24,
304 | "x1": 654,
305 | "y1": 74,
306 | "mX": 343,
307 | "mY": 49,
308 | "width": 622,
309 | "height": 50
310 | }
311 | },
312 | {
313 | "id": "A6E216F-DDDD-4FDAE5E7F1E8-7C3C-448F",
314 | "name": "l-3性价比投资环境良好高88分值得买入",
315 | "direct": "y",
316 | "props": {
317 | "style": {
318 | "position": "relative"
319 | },
320 | "children": [
321 | {
322 | "id": "-105895885-C3CA-442D",
323 | "name": "l-1性价比",
324 | "direct": "x",
325 | "props": {
326 | "style": {
327 | "position": "relative"
328 | },
329 | "children": [
330 | {
331 | "tagName": "p",
332 | "props": {
333 | "style": {
334 | "position": "absolute",
335 | "top": "81px",
336 | "left": "32px",
337 | "width": "78px",
338 | "height": "37px",
339 | "color": "rgba(54,74,127,1)",
340 | "fontSize": "26px",
341 | "fontFamily": "PingFangSC-Regular,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif",
342 | "textAlign": "left",
343 | "lineHeight": "normal",
344 | "whiteSpace": "nowrap"
345 | },
346 | "text": "性价比"
347 | },
348 | "id": "05895885-C3CA-442D-8CBA-AC64AF18BB11",
349 | "name": "性价比",
350 | "rect": {
351 | "x": 32,
352 | "y": 81.25,
353 | "width": 78,
354 | "height": 37,
355 | "mX": 71,
356 | "mY": 99.75,
357 | "x1": 110,
358 | "y1": 118.25
359 | },
360 | "leaf": true
361 | }
362 | ]
363 | },
364 | "tagName": "div",
365 | "rect": {
366 | "x": 32,
367 | "y": 81.25,
368 | "x1": 110,
369 | "y1": 118.25,
370 | "mX": 71,
371 | "mY": 99.75,
372 | "width": 78,
373 | "height": 37
374 | },
375 | "leafWrapper": true
376 | },
377 | {
378 | "id": "-33F4E49CB-5702-4B94",
379 | "name": "l-3高",
380 | "direct": "x",
381 | "props": {
382 | "style": {
383 | "position": "relative"
384 | },
385 | "children": [
386 | {
387 | "tagName": "p",
388 | "props": {
389 | "style": {
390 | "position": "absolute",
391 | "top": "81px",
392 | "left": "130px",
393 | "width": "26px",
394 | "height": "37px",
395 | "color": "rgba(254,93,78,1)",
396 | "fontSize": "26px",
397 | "fontFamily": "PingFangSC-Medium,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif",
398 | "textAlign": "left",
399 | "lineHeight": "normal",
400 | "whiteSpace": "nowrap"
401 | },
402 | "text": "高"
403 | },
404 | "id": "3F4E49CB-5702-4B94-878B-84A2AEB3F673",
405 | "name": "高",
406 | "rect": {
407 | "x": 130,
408 | "y": 81.25,
409 | "width": 26,
410 | "height": 37,
411 | "mX": 143,
412 | "mY": 99.75,
413 | "x1": 156,
414 | "y1": 118.25
415 | },
416 | "leaf": true
417 | }
418 | ]
419 | },
420 | "tagName": "div",
421 | "rect": {
422 | "x": 130,
423 | "y": 81.25,
424 | "x1": 156,
425 | "y1": 118.25,
426 | "mX": 143,
427 | "mY": 99.75,
428 | "width": 26,
429 | "height": 37
430 | },
431 | "leafWrapper": true
432 | },
433 | {
434 | "id": "-40A6E216F-DDDD-4FDA",
435 | "name": "l-488分",
436 | "direct": "x",
437 | "props": {
438 | "style": {
439 | "position": "relative"
440 | },
441 | "children": [
442 | {
443 | "tagName": "p",
444 | "props": {
445 | "style": {
446 | "position": "absolute",
447 | "top": "81px",
448 | "left": "176px",
449 | "width": "58px",
450 | "height": "37px",
451 | "color": "rgba(54,74,127,1)",
452 | "fontSize": "26px",
453 | "fontFamily": "PingFangSC-Regular,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif",
454 | "textAlign": "left",
455 | "lineHeight": "normal",
456 | "whiteSpace": "nowrap"
457 | },
458 | "text": "88分"
459 | },
460 | "id": "0A6E216F-DDDD-4FDA-8913-8F2B3BBAF023",
461 | "name": "88分",
462 | "rect": {
463 | "x": 176,
464 | "y": 81.25,
465 | "width": 58,
466 | "height": 37,
467 | "mX": 205,
468 | "mY": 99.75,
469 | "x1": 234,
470 | "y1": 118.25
471 | },
472 | "leaf": true
473 | }
474 | ]
475 | },
476 | "tagName": "div",
477 | "rect": {
478 | "x": 176,
479 | "y": 81.25,
480 | "x1": 234,
481 | "y1": 118.25,
482 | "mX": 205,
483 | "mY": 99.75,
484 | "width": 58,
485 | "height": 37
486 | },
487 | "leafWrapper": true
488 | },
489 | {
490 | "id": "-26E02EBA5-6260-4C46",
491 | "name": "l-2投资环境良好",
492 | "direct": "x",
493 | "props": {
494 | "style": {
495 | "position": "relative"
496 | },
497 | "children": [
498 | {
499 | "tagName": "p",
500 | "props": {
501 | "style": {
502 | "position": "absolute",
503 | "top": "81px",
504 | "left": "254px",
505 | "width": "156px",
506 | "height": "37px",
507 | "color": "rgba(54,74,127,1)",
508 | "fontSize": "26px",
509 | "fontFamily": "PingFangSC-Regular,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif",
510 | "textAlign": "left",
511 | "lineHeight": "normal",
512 | "whiteSpace": "nowrap"
513 | },
514 | "text": "投资环境良好"
515 | },
516 | "id": "6E02EBA5-6260-4C46-B07F-CA0C83DBF307",
517 | "name": "投资环境良好",
518 | "rect": {
519 | "x": 254,
520 | "y": 81.25,
521 | "width": 156,
522 | "height": 37,
523 | "mX": 332,
524 | "mY": 99.75,
525 | "x1": 410,
526 | "y1": 118.25
527 | },
528 | "leaf": true
529 | }
530 | ]
531 | },
532 | "tagName": "div",
533 | "rect": {
534 | "x": 254,
535 | "y": 81.25,
536 | "x1": 410,
537 | "y1": 118.25,
538 | "mX": 332,
539 | "mY": 99.75,
540 | "width": 156,
541 | "height": 37
542 | },
543 | "leafWrapper": true
544 | },
545 | {
546 | "id": "-5E5E7F1E8-7C3C-448F",
547 | "name": "l-5值得买入",
548 | "direct": "x",
549 | "props": {
550 | "style": {
551 | "position": "relative"
552 | },
553 | "children": [
554 | {
555 | "tagName": "p",
556 | "props": {
557 | "style": {
558 | "position": "absolute",
559 | "top": "81px",
560 | "left": "410px",
561 | "width": "104px",
562 | "height": "37px",
563 | "color": "rgba(54,74,127,1)",
564 | "fontSize": "26px",
565 | "fontFamily": "PingFangSC-Regular,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif",
566 | "textAlign": "left",
567 | "lineHeight": "normal",
568 | "whiteSpace": "nowrap"
569 | },
570 | "text": "值得买入"
571 | },
572 | "id": "E5E7F1E8-7C3C-448F-BFA0-828C1614CEBD",
573 | "name": "值得买入",
574 | "rect": {
575 | "x": 410,
576 | "y": 81.25,
577 | "width": 104,
578 | "height": 37,
579 | "mX": 462,
580 | "mY": 99.75,
581 | "x1": 514,
582 | "y1": 118.25
583 | },
584 | "leaf": true
585 | }
586 | ]
587 | },
588 | "tagName": "div",
589 | "rect": {
590 | "x": 410,
591 | "y": 81.25,
592 | "x1": 514,
593 | "y1": 118.25,
594 | "mX": 462,
595 | "mY": 99.75,
596 | "width": 104,
597 | "height": 37
598 | },
599 | "leafWrapper": true
600 | }
601 | ]
602 | },
603 | "tagName": "div",
604 | "rect": {
605 | "x": 32,
606 | "y": 81.25,
607 | "x1": 514,
608 | "y1": 118.25,
609 | "mX": 273,
610 | "mY": 99.75,
611 | "width": 482,
612 | "height": 37
613 | }
614 | },
615 | {
616 | "id": "-3371-4935-284AE8842",
617 | "name": "l-1+34.12%l-2近一年涨幅",
618 | "direct": "y",
619 | "props": {
620 | "style": {
621 | "position": "relative"
622 | },
623 | "children": [
624 | {
625 | "id": "-190FD50B4-3371-4935",
626 | "name": "l-1+34.12%",
627 | "direct": "x",
628 | "props": {
629 | "style": {
630 | "position": "relative"
631 | },
632 | "children": [
633 | {
634 | "tagName": "p",
635 | "props": {
636 | "style": {
637 | "position": "absolute",
638 | "top": "243px",
639 | "left": "32px",
640 | "width": "129px",
641 | "height": "41px",
642 | "color": "rgba(254,93,78,1)",
643 | "fontSize": "34px",
644 | "fontFamily": "DIN-Medium,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif",
645 | "textAlign": "left",
646 | "lineHeight": "normal",
647 | "whiteSpace": "nowrap"
648 | },
649 | "text": "+34.12%"
650 | },
651 | "id": "90FD50B4-3371-4935-93B4-4D57A48FB558",
652 | "name": "+34.12%",
653 | "rect": {
654 | "x": 32,
655 | "y": 242.5,
656 | "width": 129,
657 | "height": 41,
658 | "mX": 96.5,
659 | "mY": 263,
660 | "x1": 161,
661 | "y1": 283.5
662 | },
663 | "leaf": true
664 | }
665 | ]
666 | },
667 | "tagName": "div",
668 | "rect": {
669 | "x": 32,
670 | "y": 242.5,
671 | "x1": 161,
672 | "y1": 283.5,
673 | "mX": 96.5,
674 | "mY": 263,
675 | "width": 129,
676 | "height": 41
677 | },
678 | "leafWrapper": true
679 | },
680 | {
681 | "id": "-284AE8842-3800-43B6",
682 | "name": "l-2近一年涨幅",
683 | "direct": "x",
684 | "props": {
685 | "style": {
686 | "position": "relative"
687 | },
688 | "children": [
689 | {
690 | "tagName": "p",
691 | "props": {
692 | "style": {
693 | "position": "absolute",
694 | "top": "249px",
695 | "left": "178px",
696 | "width": "120px",
697 | "height": "33px",
698 | "color": "rgba(153,153,153,1)",
699 | "fontSize": "24px",
700 | "fontFamily": "PingFangSC-Regular,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif",
701 | "textAlign": "left",
702 | "lineHeight": "normal",
703 | "whiteSpace": "nowrap"
704 | },
705 | "text": "近一年涨幅"
706 | },
707 | "id": "84AE8842-3800-43B6-B852-FAD8E51E8BF0",
708 | "name": "近一年涨幅",
709 | "rect": {
710 | "x": 178,
711 | "y": 248.5,
712 | "width": 120,
713 | "height": 33,
714 | "mX": 238,
715 | "mY": 265,
716 | "x1": 298,
717 | "y1": 281.5
718 | },
719 | "leaf": true
720 | }
721 | ]
722 | },
723 | "tagName": "div",
724 | "rect": {
725 | "x": 178,
726 | "y": 248.5,
727 | "x1": 298,
728 | "y1": 281.5,
729 | "mX": 238,
730 | "mY": 265,
731 | "width": 120,
732 | "height": 33
733 | },
734 | "leafWrapper": true
735 | }
736 | ]
737 | },
738 | "tagName": "div",
739 | "rect": {
740 | "x": 32,
741 | "y": 242.5,
742 | "x1": 298,
743 | "y1": 283.5,
744 | "mX": 165,
745 | "mY": 263,
746 | "width": 266,
747 | "height": 41
748 | }
749 | }
750 | ]
751 | },
752 | "id": "12537FE2-C67F-4F0A-8776-8986DCCF2BD6",
753 | "name": "页面 1",
754 | "rect": {
755 | "x": 0,
756 | "y": 0,
757 | "width": 0,
758 | "height": 0
759 | }
760 | }
--------------------------------------------------------------------------------
/moo-css-react/__test__/virtualDom.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 | {
4 | "tagName": "body",
5 | "sketchInfo": {
6 | "type": "page"
7 | },
8 | "props": {
9 | "style": "position:absolute;top:0px;left:0px;width:0px;height:0px;",
10 | "children": [
11 | {
12 | "tagName": "div",
13 | "sketchInfo": {
14 | "type": "artboard"
15 | },
16 | "props": {
17 | "style": "position:absolute;top:152px;left:257px;width:750px;height:1334px;",
18 | "children": [
19 | {
20 | "tagName": "div",
21 | "sketchInfo": {
22 | "type": "symbolInstance"
23 | },
24 | "props": {
25 | "style": "position:absolute;top:0px;left:0px;width:750px;height:128px;",
26 | "children": []
27 | }
28 | },
29 | {
30 | "tagName": "img",
31 | "sketchInfo": {
32 | "type": "bitmap"
33 | },
34 | "props": {
35 | "style": "position:absolute;top:169px;left:121px;width:76px;height:93px;",
36 | "src": "images/9346ca49147854673f7e1ce3dfab9a09f848152b.png",
37 | "children": []
38 | }
39 | },
40 | {
41 | "tagName": "p",
42 | "sketchInfo": {
43 | "type": "text"
44 | },
45 | "props": {
46 | "style": "position:absolute;top:369px;left:118px;width:64px;height:32px;color:rgba(84,84,84,1);font-size:32px;font-family:SourceHanSansCN-Medium,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif;text-align:left;line-height:;",
47 | "children": [
48 | "周报"
49 | ]
50 | }
51 | },
52 | {
53 | "tagName": "p",
54 | "sketchInfo": {
55 | "type": "text"
56 | },
57 | "props": {
58 | "style": "position:absolute;top:353px;left:316px;width:100px;height:50px;color:rgba(84,84,84,1);font-size:50px;font-family:SourceHanSansCN-Medium,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif;text-align:left;line-height:;",
59 | "children": [
60 | "周报"
61 | ]
62 | }
63 | },
64 | {
65 | "tagName": "p",
66 | "sketchInfo": {
67 | "type": "text"
68 | },
69 | "props": {
70 | "style": "position:absolute;top:341px;left:524px;width:128px;height:64px;color:rgba(84,84,84,1);font-size:64px;font-family:SourceHanSansCN-Medium,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif;text-align:left;line-height:;",
71 | "children": [
72 | "周报"
73 | ]
74 | }
75 | },
76 | {
77 | "tagName": "div",
78 | "sketchInfo": {
79 | "type": "oval"
80 | },
81 | "props": {
82 | "style": "position:absolute;top:474px;left:108px;width:102px;height:102px;border-color:rgba(151,151,151,1);border-width:1px;border-style:dash;",
83 | "children": []
84 | }
85 | },
86 | {
87 | "tagName": "div",
88 | "sketchInfo": {
89 | "type": "oval"
90 | },
91 | "props": {
92 | "style": "position:absolute;top:807px;left:108px;width:102px;height:102px;border-color:rgba(151,151,151,1);border-width:1px;border-style:dash;",
93 | "children": []
94 | }
95 | },
96 | {
97 | "tagName": "div",
98 | "sketchInfo": {
99 | "type": "oval"
100 | },
101 | "props": {
102 | "style": "position:absolute;top:1105px;left:108px;width:102px;height:102px;border-color:rgba(151,151,151,1);border-width:1px;border-style:dash;",
103 | "children": []
104 | }
105 | },
106 | {
107 | "tagName": "div",
108 | "sketchInfo": {
109 | "type": "oval"
110 | },
111 | "props": {
112 | "style": "position:absolute;top:645px;left:108px;width:102px;height:102px;border-color:rgba(255,160,160,1);border-width:5px;border-style:dash;",
113 | "children": []
114 | }
115 | },
116 | {
117 | "tagName": "div",
118 | "sketchInfo": {
119 | "type": "rectangle"
120 | },
121 | "props": {
122 | "style": "position:absolute;top:961px;left:0px;width:750px;height:373px;border-color:rgba(151,151,151,1);border-width:1px;border-style:dash;",
123 | "children": []
124 | }
125 | },
126 | {
127 | "tagName": "div",
128 | "sketchInfo": {
129 | "type": "star"
130 | },
131 | "props": {
132 | "style": "position:absolute;top:474px;left:324px;width:102px;height:102px;border-color:rgba(151,151,151,1);border-width:1px;border-style:dash;",
133 | "children": []
134 | }
135 | }
136 | ]
137 | }
138 | }
139 | ]
140 | }
141 | },
142 | {
143 | "tagName": "div",
144 | "sketchInfo": {},
145 | "props": {
146 | "style": "",
147 | "children": []
148 | }
149 | }
150 | ]
151 | }
--------------------------------------------------------------------------------
/moo-css-react/dist/handleJsx.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @utils handleJsx
4 | */
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | function getReactComponent(renderStr, propsArr) {
7 | return `
8 | import * as React from 'react'
9 | import './index.css'
10 |
11 | export default function Component (props) {
12 | ${propsArr && propsArr.length ? `let {${propsArr.join('')}} = props;` : ''}
13 | return (${renderStr.replace(/body/g, 'section').replace(/class=/g, 'className=')})
14 | }
15 | `;
16 | }
17 | exports.getReactComponent = getReactComponent;
18 |
--------------------------------------------------------------------------------
/moo-css-react/dist/handleVue.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @utils handleVue
4 | */
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | function getVueComponent(renderStr, propsArr) {
7 | return `
8 | import * as Vue from 'vue'
9 | import Component from 'vue-class-component'
10 | import './index.css'
11 |
12 | @Component({
13 | props: {${propsArr && propsArr.length && propsArr.join(',') || ''}}
14 | })
15 | export default class MyComponent extends Vue {
16 | render () {
17 | ${propsArr && propsArr.length ? `let {${propsArr.join('')}} = this;` : ''}
18 | return (${renderStr.replace(/body/g, 'section').replace(/class=/g, 'className=')})
19 | }
20 | }
21 | `;
22 | }
23 | exports.getVueComponent = getVueComponent;
24 |
--------------------------------------------------------------------------------
/moo-css-react/dist/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @namespace mvdom2web
4 | */
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | const json2html_1 = require("./json2html");
7 | const handleJsx_1 = require("./handleJsx");
8 | exports.getReactComponent = handleJsx_1.getReactComponent;
9 | const handleVue_1 = require("./handleVue");
10 | exports.getVueComponent = handleVue_1.getVueComponent;
11 | const moo_css_transformer_1 = require("moo-css-transformer");
12 | function humpToOther(value, symbol = '-') {
13 | return value.replace(/[A-Z]/g, (word) => {
14 | return `${symbol}${word.toLowerCase()}`;
15 | });
16 | }
17 | function json2Arr(obj) {
18 | let arr = [];
19 | for (let i in obj) {
20 | arr.push(humpToOther(i) + ':' + obj[i]);
21 | }
22 | return arr;
23 | }
24 | function handleData(config) {
25 | let { data, handleImg, nostyle, viewport, vueBool, } = config;
26 | let cssTextObj = {};
27 | const _style2MooSelector = (str) => {
28 | let _arr = str.split(':');
29 | if (!_arr[1] || _arr[1] === 'undefined')
30 | return undefined;
31 | return moo_css_transformer_1.c2m.style2MooSelector(_arr[0], _arr[1]);
32 | };
33 | const _handleStyleProps = (props) => {
34 | let styleList = json2Arr(props.style);
35 | let classList = [];
36 | if (!nostyle) {
37 | let newStyle = styleList.filter((item) => {
38 | if (viewport && ~item.indexOf('px')) { // mobile
39 | let arr = item.split(':');
40 | item = `${arr[0]}:${(parseInt(arr[1]) / viewport * 100).toFixed(4)}vw`;
41 | }
42 | let moo = _style2MooSelector(item);
43 | if (moo) {
44 | classList.push(moo);
45 | if (!cssTextObj[moo])
46 | cssTextObj[moo] = item;
47 | return false;
48 | }
49 | else if (moo !== undefined) {
50 | return item;
51 | }
52 | else
53 | return false;
54 | }).join(';');
55 | props.style = newStyle;
56 | }
57 | else {
58 | let moduleClassList = [];
59 | styleList.forEach((item) => {
60 | if (viewport && ~item.indexOf('px')) { // mobile
61 | let arr = item.split(':');
62 | item = `${arr[0]}:${(parseInt(arr[1]) / viewport * 100).toFixed(4)}vw`;
63 | }
64 | let moo = _style2MooSelector(item);
65 | if (moo) {
66 | classList.push(moo);
67 | if (!cssTextObj[moo])
68 | cssTextObj[moo] = item;
69 | return false;
70 | }
71 | else if (moo !== undefined) {
72 | moduleClassList.push(item);
73 | return item;
74 | }
75 | else
76 | return false;
77 | });
78 | if (moduleClassList.length) {
79 | props.className = 'm-' + ('' + Math.random()).slice(-6);
80 | cssTextObj[props.className] = moduleClassList.join(';');
81 | }
82 | delete props.style;
83 | }
84 | if (classList.length) {
85 | let className = classList.join(' ');
86 | props.className = (props.className ? props.className + ' ' : '') + className;
87 | return className;
88 | }
89 | };
90 | let propsList = [];
91 | let htmlTxt = json2html_1.default.build(data, {
92 | handleStyle: _handleStyleProps,
93 | handleImg,
94 | propsList,
95 | });
96 | let cssTxt = '';
97 | for (let selector in cssTextObj) {
98 | cssTxt += `
99 | .${selector} {
100 | ${cssTextObj[selector]}
101 | }`;
102 | }
103 | return {
104 | jsx: vueBool ? handleVue_1.getVueComponent(htmlTxt, propsList) : handleJsx_1.getReactComponent(htmlTxt, propsList),
105 | css: cssTxt
106 | };
107 | }
108 | exports.default = handleData;
109 |
--------------------------------------------------------------------------------
/moo-css-react/dist/json2html.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @module json2html
4 | */
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | class JSON2HTML {
7 | static get selfCloseTags() {
8 | return [
9 | 'area', 'base', 'br', 'col', 'embed', 'hr',
10 | 'img', 'input', 'link', 'meta', 'param', 'source',
11 | 'track', 'wbr', 'command', 'keygen', 'menuitem',
12 | ];
13 | }
14 | static build(json, handlers) {
15 | if (!json || !json.tagName)
16 | return '';
17 | const props = JSON2HTMLBuilder.props(json, handlers);
18 | if (JSON2HTMLBuilder.isSelfCloseTag(json)) {
19 | return `<${json.tagName}${props}/>`;
20 | }
21 | const children = JSON2HTMLBuilder.children(json, handlers);
22 | return `
23 | <${json.tagName}${props}>${children}${json.tagName}>`;
24 | }
25 | }
26 | exports.default = JSON2HTML;
27 | class JSON2HTMLBuilder {
28 | static props(json, handlers) {
29 | let props = json.props;
30 | if (!props)
31 | return '';
32 | let html = '';
33 | const { handleStyle, handleImg, } = handlers;
34 | if (props.style && handleStyle) {
35 | handleStyle(props);
36 | }
37 | if (props.src && handleImg && props.src.startsWith('data:image')) {
38 | handleImg(props);
39 | }
40 | const keys = Object.keys(props);
41 | for (const index in keys) {
42 | let key = keys[index];
43 | if (key === 'children' || key === 'text')
44 | continue;
45 | else if (key === 'className')
46 | html += ` class="${props[key]}"`;
47 | else if ({}.hasOwnProperty.call(keys, index)) {
48 | if (props[key])
49 | html += ` ${key}="${props[key]}"`;
50 | }
51 | }
52 | return html;
53 | }
54 | static children(json, handlers) {
55 | let children = json.props && json.props.children;
56 | if (!children) {
57 | let text = json.props.text;
58 | if (text && text.startsWith('{') && text.endsWith('}') && handlers && handlers.propsList) {
59 | handlers.propsList.push(text);
60 | }
61 | delete json.props.text;
62 | return text || '';
63 | }
64 | let html = '';
65 | for (const index in children) {
66 | if ({}.hasOwnProperty.call(children, index)) {
67 | if (typeof children[index] == 'object') {
68 | html += JSON2HTML.build(children[index], handlers);
69 | }
70 | else {
71 | html += children[index];
72 | }
73 | }
74 | }
75 | return html;
76 | }
77 | static isSelfCloseTag(json) {
78 | return (JSON2HTML.selfCloseTags.indexOf(json.tag) > -1);
79 | }
80 | }
81 | exports.JSON2HTMLBuilder = JSON2HTMLBuilder;
82 | ;
83 |
--------------------------------------------------------------------------------
/moo-css-react/dist/utils/handleImage.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * handle image base64
4 | */
5 | /*
6 | export default function handleImgBase64 (base64: string) {
7 | let base64Data = base64.replace(/^data:image\/\w+;base64,/, '');
8 | let dataBuffer = new Buffer(base64Data, 'base64');
9 | return dataBuffer;
10 | }*/
11 |
--------------------------------------------------------------------------------
/moo-css-react/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testEnvironment: 'node',
3 | roots: ['__tests__'],
4 | testRegex: '__tests__/(.+)\\.test\\.(jsx?|tsx?)$',
5 | moduleFileExtensions: ['js', 'json', 'node'],
6 | };
7 |
--------------------------------------------------------------------------------
/moo-css-react/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "moo-css-react",
3 | "version": "1.0.1",
4 | "author": "Wayne",
5 | "description": "mvdom data to jsx file.",
6 | "main": "dist/index.js",
7 | "scripts": {
8 | "test": "node ./__test__/",
9 | "build": "tsc"
10 | },
11 | "devDependencies": {
12 | "@types/node": "^13.13.12"
13 | },
14 | "dependencies": {
15 | "moo-css-transformer": "^0.1.1"
16 | },
17 | "keywords": [
18 | "moo-css"
19 | ],
20 | "license": "ISC"
21 | }
22 |
--------------------------------------------------------------------------------
/moo-css-react/src/handleJsx.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @utils handleReact
3 | * @author Wayne
4 | * @Date 2020-07-28 13:07:16
5 | * @LastEditTime 2023-04-25 10:36:12
6 | */
7 |
8 | export function getReactComponent(renderStr: string, propsArr?: string[]): string {
9 | return `
10 | import * as React from 'react'
11 | import './index.css'
12 |
13 | export default function Component (props) {
14 | ${propsArr?.length ? `let {${propsArr.join('')}} = props;` : ''}
15 | return (${renderStr.replace(/body/g, 'section').replace(/class=/g, 'className=')})
16 | }
17 | `;
18 | }
19 |
--------------------------------------------------------------------------------
/moo-css-react/src/handleVue.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @utils handleVue
3 | * @author Wayne
4 | * @Date 2020-07-30 13:58:02
5 | * @LastEditTime 2023-04-25 10:36:05
6 | */
7 |
8 | export function getVueComponent(renderStr: string, propsArr?: string[]): string {
9 | return `
10 | import * as Vue from 'vue'
11 | import Component from 'vue-class-component'
12 | import './index.css'
13 |
14 | @Component({
15 | props: {${(propsArr?.length && propsArr.join(',')) || ''}}
16 | })
17 | export default class MyComponent extends Vue {
18 | render () {
19 | ${propsArr?.length ? `let {${propsArr.join('')}} = this;` : ''}
20 | return (${renderStr.replace(/body/g, 'section').replace(/class=/g, 'className=')})
21 | }
22 | }
23 | `;
24 | }
25 |
--------------------------------------------------------------------------------
/moo-css-react/src/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @namespace mvdom2web
3 | * @Date 2020-02-28 20:36:16
4 | * @LastEditTime 2023-04-25 10:39:38
5 | */
6 |
7 | import JSON2HTML from './json2html';
8 | import { getReactComponent } from './handleJsx';
9 | import { getVueComponent } from './handleVue';
10 | import { c2m } from 'moo-css-transformer';
11 |
12 | function humpToOther(value: string, symbol: string = '-') {
13 | return value.replace(/[A-Z]/g, word => {
14 | return `${symbol}${word.toLowerCase()}`;
15 | });
16 | }
17 |
18 | function json2Arr(obj: any) {
19 | const arr: string[] = [];
20 | for (const i in obj) {
21 | arr.push(humpToOther(i) + ':' + obj[i]);
22 | }
23 | return arr;
24 | }
25 |
26 | export { getVueComponent, getReactComponent };
27 |
28 | /**
29 | * @function handleData
30 | * @description 处理样式数据
31 | * @param config
32 | * @returns
33 | */
34 | export default function handleData(config: any) {
35 | const { data, handleImg, nostyle, viewport, vueBool } = config;
36 | const cssTextObj: any = {};
37 | const _style2MooSelector = (str: string) => {
38 | const _arr = str.split(':');
39 | if (!_arr[1] || _arr[1] === 'undefined') return undefined;
40 | return c2m.style2MooSelector(_arr[0], _arr[1]);
41 | };
42 |
43 | const _handleStyleProps = (props: any) => {
44 | const styleList = json2Arr(props.style);
45 | const classList: any = [];
46 |
47 | if (!nostyle) {
48 | const newStyle = styleList
49 | .filter((item: any) => {
50 | if (viewport && ~item.indexOf('px')) {
51 | // mobile
52 | const arr = item.split(':');
53 |
54 | item = `${arr[0]}:${((parseInt(arr[1]) / viewport) * 100).toFixed(4)}vw`;
55 | }
56 | const moo = _style2MooSelector(item);
57 | if (moo) {
58 | classList.push(moo);
59 | if (!cssTextObj[moo]) cssTextObj[moo] = item;
60 | return false;
61 | } else if (moo !== undefined) {
62 | return item;
63 | } else return false;
64 | })
65 | .join(';');
66 | props.style = newStyle;
67 | } else {
68 | const moduleClassList: string[] = [];
69 | styleList.forEach(item => {
70 | if (viewport && ~item.indexOf('px')) {
71 | // mobile
72 | const arr = item.split(':');
73 | item = `${arr[0]}:${((parseInt(arr[1]) / viewport) * 100).toFixed(4)}vw`;
74 | }
75 | const moo = _style2MooSelector(item);
76 | if (moo) {
77 | classList.push(moo);
78 |
79 | if (!cssTextObj[moo]) cssTextObj[moo] = item;
80 | return false;
81 | } else if (moo !== undefined) {
82 | moduleClassList.push(item);
83 | return item;
84 | } else return false;
85 | });
86 | if (moduleClassList.length) {
87 | props.className = 'm-' + ('' + Math.random()).slice(-6);
88 | cssTextObj[props.className] = moduleClassList.join(';');
89 | }
90 | delete props.style;
91 | }
92 |
93 | if (classList.length) {
94 | const className = classList.join(' ');
95 | props.className = (props.className ? `${props.className} ` : '') + className;
96 | return className;
97 | }
98 | };
99 | const propsList: any[] = [];
100 | const htmlTxt = JSON2HTML.build(data, {
101 | handleStyle: _handleStyleProps,
102 | handleImg,
103 | propsList,
104 | });
105 | let cssTxt = '';
106 | for (const selector in cssTextObj) {
107 | cssTxt += `
108 | .${selector} {
109 | ${cssTextObj[selector]}
110 | }`;
111 | }
112 | return {
113 | jsx: vueBool ? getVueComponent(htmlTxt, propsList) : getReactComponent(htmlTxt, propsList),
114 | css: cssTxt,
115 | };
116 | }
117 |
--------------------------------------------------------------------------------
/moo-css-react/src/json2html.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @module json2html
3 | * @author Wayne
4 | * @Date 2020-02-28 20:36:16
5 | * @LastEditTime 2023-04-25 10:36:40
6 | */
7 |
8 | export default class JSON2HTML {
9 | static get selfCloseTags() {
10 | return [
11 | 'area',
12 | 'base',
13 | 'br',
14 | 'col',
15 | 'embed',
16 | 'hr',
17 | 'img',
18 | 'input',
19 | 'link',
20 | 'meta',
21 | 'param',
22 | 'source',
23 | 'track',
24 | 'wbr',
25 | 'command',
26 | 'keygen',
27 | 'menuitem',
28 | ];
29 | }
30 |
31 | static build(json: any, handlers?: any) {
32 | if (!json || !json.tagName) return '';
33 | const props = JSON2HTMLBuilder.props(json, handlers);
34 | if (JSON2HTMLBuilder.isSelfCloseTag(json)) {
35 | return `<${json.tagName}${props}/>`;
36 | }
37 | const children = JSON2HTMLBuilder.children(json, handlers);
38 | return `
39 | <${json.tagName}${props}>${children}${json.tagName}>`;
40 | }
41 | }
42 |
43 | export class JSON2HTMLBuilder {
44 | static props(json: any, handlers: any) {
45 | let props = json.props;
46 | if (!props) return '';
47 | let html = '';
48 | const { handleStyle, handleImg } = handlers;
49 |
50 | if (props.style && handleStyle) {
51 | handleStyle(props);
52 | }
53 | if (props.src && handleImg && props.src.startsWith('data:image')) {
54 | handleImg(props);
55 | }
56 |
57 | const keys = Object.keys(props);
58 | // 属性处理
59 | for (const index in keys) {
60 | let key = keys[index];
61 | if (key === 'children' || key === 'text') continue;
62 | else if (key === 'className') html += ` class="${props[key]}"`;
63 | else if ({}.hasOwnProperty.call(keys, index)) {
64 | if (props[key]) html += ` ${key}="${props[key]}"`;
65 | }
66 | }
67 | return html;
68 | }
69 |
70 | // 处理子元素
71 | static children(json: any, handlers?: any) {
72 | const children = json.props?.children;
73 |
74 | if (!children) {
75 | const text = json.props.text;
76 | if (text?.startsWith('{') && text.endsWith('}') && handlers && handlers.propsList) {
77 | handlers.propsList.push(text);
78 | }
79 | delete json.props.text;
80 | return text || '';
81 | }
82 | let html = '';
83 | for (const index in children) {
84 | if ({}.hasOwnProperty.call(children, index)) {
85 | if (typeof children[index] === 'object') {
86 | html += JSON2HTML.build(children[index], handlers);
87 | } else {
88 | html += children[index];
89 | }
90 | }
91 | }
92 | return html;
93 | }
94 |
95 | static isSelfCloseTag(json: any) {
96 | return JSON2HTML.selfCloseTags.indexOf(json.tag) > -1;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/moo-css-react/src/types/moo.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Wayne
3 | * @Date 2020-02-24 20:13:10
4 | * @LastEditTime 2022-07-12 13:21:13
5 | */
6 |
7 | // Type definitions for weapp
8 | declare module 'moo-css-transformer';
9 |
--------------------------------------------------------------------------------
/moo-css-react/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["./src/"],
3 | "compilerOptions": {
4 | "outDir": "./dist/",
5 | "rootDir": "./src/",
6 | "sourceMap": false,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "module": "commonjs",
10 | "target": "es6",
11 | "allowJs": true,
12 | "baseUrl": ".",
13 | "paths": {
14 | "@/*": [
15 | "src/*"
16 | ]
17 | },
18 | "typeRoots": ["./src/types/"]
19 | }
20 | }
--------------------------------------------------------------------------------
/moo-css-sketch/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "moo-css-sketch",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "./dist/index.js",
6 | "dependencies": {
7 | "canvas": "^2.6.1",
8 | "jszip": "^3.2.2",
9 | "mime-types": "^2.1.26"
10 | },
11 | "devDependencies": {},
12 | "scripts": {
13 | "test": "echo \"Error: no test specified\" && exit 1"
14 | },
15 | "author": "Micheal Wang",
16 | "license": "ISC",
17 | "dependencies": {}
18 | }
19 |
--------------------------------------------------------------------------------
/moo-css-sketch/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist/",
4 | "sourceMap": true,
5 | "strict": true,
6 | "noImplicitAny": true,
7 | "module": "commonjs",
8 | "target": "es5",
9 | "allowJs": true,
10 | "baseUrl": ".",
11 | "paths": {
12 | "@/*": [
13 | "src/*"
14 | ]
15 | },
16 | "typeRoots": ["./src/types/"],
17 | "rootDir": "./src/"
18 | }
19 | }
--------------------------------------------------------------------------------
/moo-css-transformer/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/env",
5 | {
6 | "loose": true
7 | }
8 | ]
9 | ]
10 | }
--------------------------------------------------------------------------------
/moo-css-transformer/.eslintignore:
--------------------------------------------------------------------------------
1 | /node_modules/*
2 | src/js/lib/*.js
3 | lib/*.js
4 | test/*.js
5 | types/*
--------------------------------------------------------------------------------
/moo-css-transformer/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | node: true,
4 | browser: true,
5 | es6: true,
6 | },
7 | extends: [
8 | 'eslint:recommended',
9 | ],
10 | parserOptions: {
11 | sourceType: 'module',
12 | },
13 | rules: {
14 | 'no-useless-escape': [0],
15 | },
16 | };
17 |
--------------------------------------------------------------------------------
/moo-css-transformer/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /npm-debug.log*
6 | /yarn-error.log
7 | /yarn.lock
8 | # /package-lock.json
9 | /coverage
10 |
11 | # production
12 | /dist
13 |
14 | # datas
15 | /datas
16 |
17 | # misc
18 | .DS_Store
19 |
20 | # logs
21 | /*.log
22 |
23 | # vscode
24 | /.vscode
25 |
26 | # zip
27 | /*.zip
28 |
--------------------------------------------------------------------------------
/moo-css-transformer/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | printWidth: 100,
3 | tabWidth: 2,
4 | useTabs: false,
5 | singleQuote: true,
6 | semi: true,
7 | trailingComma: 'es5',
8 | bracketSpacing: true,
9 | arrowParens: 'avoid',
10 | };
11 |
--------------------------------------------------------------------------------
/moo-css-transformer/README.md:
--------------------------------------------------------------------------------
1 | # moo-css-transformer
2 |
3 |
4 |
5 | MooCSS transform tool.
6 |
7 |
8 |
9 | ## Version
10 |
11 | 0.1.0
12 |
13 |
14 |
15 | ## Installation
16 |
17 | ``` sh
18 | npm install --save moo-css-transformer
19 | ```
20 |
21 | or
22 |
23 | ``` sh
24 | yarn add moo-css-transformer
25 | ```
26 |
27 |
28 |
29 |
30 |
31 |
32 | ## Use
33 |
34 | ``` js
35 | const { m2c, c2m, styleScaner } = require('moo-css-transformer');
36 | console.log(m2c('g-mt20'));
37 | console.log(c2m('margin-top', '20px'));
38 | console.log(styleScaner('.d{color:red}.c{width: 50px}'));
39 | ```
40 |
41 | ### API
42 |
43 | - m2c: MooCSS selector --> CSS values
44 | - c2m: CSS values --> MooCSS selector
45 | - styleScaner: CSS sheet --> CSS list
46 |
47 |
48 |
49 | #### c2m
50 |
51 | - params:
52 | - attribute: `{String}` css attribute;
53 | - value: `{String|Number} `css value.(if value is a number, it defaults to px, 70 -> 70px);
54 | - return:
55 | - `{String}`: if params can be moo-css selector, return selector string, else return false.
56 |
57 | for example:
58 |
59 | ``` js
60 | c2m('text-align', 'center'); // 'f-tc'
61 | c2m('line-height', '150%'); // 'g-lh150per'
62 | c2m('padding', '0 4% 50px'); // ''
63 | ```
64 |
65 |
66 |
67 | #### m2c
68 |
69 | - params:
70 | - minName: `{String}` ,MooCSS selector, such as `u-w10`
71 | - lenUnit: `{String}`, css length unit`"vw"/"rem"/"px"`, default: `"vw"`
72 | - Viewport: `{Number}`, responsive mobile screen, default: `750`
73 | - return:`{Object}`
74 | - key: `{String}`, key name
75 | - attr: `{String}`, css style attribute
76 | - val: `{String | Number}`, css style value
77 |
78 |
79 |
80 | for example:
81 |
82 | ``` js
83 | m2c('g-mt10'); // key: 'g-mt10', attr: 'margin-top', val: '1.33333vw'
84 | m2c('u-w100', 'rem'); // key: 'u-w100', attr: 'width', val: '1.33333rem'
85 | m2c('u-w100', 'px'); // key: 'u-w100', attr: 'width', val: '100px'
86 | m2c('u-w100', 'rem', 500); // key: 'u-w100', attr: 'width', val: '2rem'
87 | ```
88 |
89 |
90 |
91 | #### styleScaner
92 |
93 | - params: `{String}` css sheet
94 | - return: `{Array}`
95 | - item: `{String}` css style
96 |
97 |
98 |
99 | for example:
100 |
101 | ``` js
102 | styleScaner(`
103 | .test1 {
104 | color: red;
105 | line-height: 150%;
106 | }
107 | .test2 {
108 | width: 50px;
109 | height: 60px;
110 | line-height: 2;
111 | color: red;
112 | }
113 | `); // ['color:red', 'line-height:150%', 'width:50px', 'height:60px', 'line-height:2']
114 | ```
115 |
116 |
117 |
118 |
119 |
120 | ## Update
121 |
122 | 2022.05.14
--------------------------------------------------------------------------------
/moo-css-transformer/build/getMooDatas.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | /**
3 | * moo get moo-css.json (delete useless data)-> data.json
4 | * @author MichealWayne
5 | */
6 |
7 | const fs = require('fs');
8 | const { join } = require('path');
9 | const http = require('http');
10 | const utils = require('../src/utils');
11 |
12 | function getMooList() {
13 | return new Promise((resolve, reject) => {
14 | http
15 | .get(
16 | {
17 | hostname: 'blog.michealwayne.cn',
18 | port: 80,
19 | path: '/fe-tools/datas/moo-css.json',
20 | agent: false,
21 | },
22 | res => {
23 | let datas = '';
24 | res.on('data', data => {
25 | datas += data;
26 | });
27 |
28 | res.on('end', () => {
29 | resolve(JSON.parse(datas));
30 | });
31 |
32 | res.on('error', e => {
33 | reject(e);
34 | });
35 | }
36 | )
37 | .on('error', e => {
38 | reject(e);
39 | });
40 | });
41 | }
42 |
43 | const NUMBER_MAP = {
44 | NO_ZERO: 0,
45 | NO_TWO: 2,
46 | NO_LAST: -1,
47 | };
48 |
49 | function handleStyleList(styleList) {
50 | const M2Cdata = {};
51 | const C2Mdata = {};
52 |
53 | utils.each(styleList, function (moduleitem) {
54 | const name = moduleitem.name || '';
55 | const moduleName = name.split('-')[NUMBER_MAP.NO_ZERO].slice(NUMBER_MAP.NO_LAST);
56 | if (!M2Cdata[moduleName]) {
57 | M2Cdata[moduleName] = {};
58 | }
59 | const _module = M2Cdata[moduleName];
60 |
61 | const childrenList = moduleitem.children;
62 | utils.each(childrenList, function (item) {
63 | const css = item['属性'];
64 |
65 | if (!css.includes('、')) {
66 | const minName = utils.getStyleMinName(css);
67 |
68 | if (!_module[minName]) _module[minName] = css;
69 | else {
70 | _module[utils.getStyleMinName(css, true)] = css;
71 | }
72 |
73 | C2Mdata[css] = `${moduleName}-${minName}`;
74 | } else {
75 | css.split('、').map(_css => {
76 | const minName = utils.getStyleMinName(_css);
77 |
78 | if (!_module[minName]) {
79 | _module[minName] = _css;
80 | } else {
81 | _module[utils.getStyleMinName(_css, true)] = _css;
82 | }
83 |
84 | C2Mdata[_css] = `${moduleName}-${minName}`;
85 | return true;
86 | });
87 | }
88 | });
89 | });
90 |
91 | fs.writeFile(
92 | join(__dirname, '../datas/m2c-data.json'),
93 | JSON.stringify(M2Cdata, null, NUMBER_MAP.NO_TWO),
94 | err => {
95 | if (err) {
96 | console.error(err);
97 | } else {
98 | console.log('m2c-data.json build success!');
99 | }
100 | }
101 | );
102 | fs.writeFile(
103 | join(__dirname, '../datas/c2m-data.json'),
104 | JSON.stringify(C2Mdata, null, NUMBER_MAP.NO_TWO),
105 | err => {
106 | if (err) {
107 | console.error(err);
108 | } else {
109 | console.log('c2m-data.json build success!');
110 | }
111 | }
112 | );
113 | }
114 |
115 | function handleList(data) {
116 | for (const i in data) {
117 | if (!utils.hasOwnProp(data, i)) continue;
118 | if (data[i].name === '样式模块词典') {
119 | handleStyleList(data[i].children);
120 | }
121 | }
122 | }
123 |
124 | getMooList().then(resultData => handleList(resultData));
125 |
--------------------------------------------------------------------------------
/moo-css-transformer/config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @config
3 | * @author Wayne
4 | */
5 |
6 | // semantiztion style name abbreviation
7 | const NAMEID_MAP = {
8 | background: 'bg',
9 | 'box-sizing': 'box',
10 | border: 'bd',
11 | overflow: 'ov',
12 | opacity: 'hide',
13 | flex: 'flex',
14 | transform: 'trans',
15 | 'text-align': 't',
16 | 'vertical-align': 'v',
17 | color: 'cr',
18 | };
19 |
20 | // semantiztion style value abbreviation
21 | const VALUEID_MAP = {
22 | left: 'l',
23 | right: 'r',
24 | center: 'c',
25 | middle: 'm',
26 | top: 't',
27 | bottom: 'b',
28 | relative: 'r',
29 | absolute: 'a',
30 | fixed: 'f',
31 | };
32 |
33 | // box css attribute
34 | const BOX_LIST = [
35 | 'top',
36 | 'right',
37 | 'bottom',
38 | 'left',
39 | 'margin',
40 | 'margin-top',
41 | 'margin-right',
42 | 'margin-bottom',
43 | 'margin-left',
44 | 'padding',
45 | 'padding-top',
46 | 'padding-right',
47 | 'padding-bottom',
48 | 'padding-left',
49 | 'width',
50 | 'height',
51 | 'font-size',
52 | 'line-height',
53 | 'border-top',
54 | 'border-right',
55 | 'border-bottom',
56 | 'border-left',
57 | 'border-top-left-radius',
58 | 'border-top-right-radius',
59 | 'border-bottom-left-radius',
60 | 'border-bottom-right-radius',
61 | ];
62 |
63 | // minify css attribute
64 | const MINI_LIST = ['position', 'text-align', 'float', 'vertical-align'];
65 |
66 | // minify css map
67 | const MINI_LIST_MAP = {
68 | position: {
69 | f: 'fixed',
70 | r: 'relative',
71 | a: 'absolute',
72 | s: 'static',
73 | sk: 'sticky',
74 | },
75 | 'text-align': {
76 | c: 'center',
77 | l: 'left',
78 | r: 'right',
79 | j: 'justify',
80 | },
81 | float: {
82 | c: 'center',
83 | l: 'left',
84 | r: 'right',
85 | },
86 | 'vertical-align': {
87 | t: 'top',
88 | m: 'middle',
89 | b: 'bottom',
90 | },
91 | };
92 |
93 | module.exports = {
94 | NAMEID_MAP,
95 | VALUEID_MAP,
96 | BOX_LIST,
97 | MINI_LIST,
98 | MINI_LIST_MAP,
99 | };
100 |
--------------------------------------------------------------------------------
/moo-css-transformer/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * moo-css-transformer
3 | * @author MichealWayne
4 | * @update 2020.02.20
5 | */
6 |
7 | const c2m = require('./dist/c2m');
8 |
9 | module.exports = {
10 | m2c: require('./dist/m2c').m2c,
11 | c2m: c2m.style2MooSelector,
12 | styleScaner: c2m.styleScaner,
13 | };
14 |
--------------------------------------------------------------------------------
/moo-css-transformer/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testEnvironment: 'node',
3 | roots: ['/test'],
4 | testRegex: 'test/(.+)\\.test\\.(jsx?|tsx?)$',
5 | moduleFileExtensions: ['js', 'jsx', 'json', 'node'],
6 | };
7 |
--------------------------------------------------------------------------------
/moo-css-transformer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "moo-css-transformer",
3 | "version": "1.0.1",
4 | "description": "moo-css, css style transform function.",
5 | "main": "index.js",
6 | "types": "types/index.d.ts",
7 | "files": [
8 | "dist/",
9 | "types/",
10 | "index.js"
11 | ],
12 | "scripts": {
13 | "test": "jest",
14 | "update:data": "node build/getMooDatas",
15 | "build": "webpack -p --env.config production --env.prod --config ./webpack.config.js"
16 | },
17 | "keywords": [
18 | "moo-css"
19 | ],
20 | "repository": {
21 | "type": "git",
22 | "url": "git+https://github.com/MichealWayne/moo-css-transformer.git"
23 | },
24 | "homepage": "https://github.com/MichealWayne/moo-css-transformer.git",
25 | "author": "MichealWayne",
26 | "license": "ISC",
27 | "devDependencies": {
28 | "@babel/cli": "^7.0.0-beta.40",
29 | "@babel/core": "^7.0.0-beta.40",
30 | "@babel/preset-env": "^7.13.15",
31 | "@babel/preset-stage-2": "^7.8.3",
32 | "babel-loader": "^8.0.0-beta.0",
33 | "webpack": "^4.28.1",
34 | "webpack-cli": "^3.2.1"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/moo-css-transformer/src/c2m.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-bitwise */
2 | /**
3 | * @module c2m
4 | * @description css to moo
5 | * @author Wayne
6 | * @time 2020.02.19
7 | */
8 | const utils = require('./utils');
9 | const scaner = require('./scaner');
10 | const C2Mdata = require('../datas/c2m-data.json');
11 | const CONST = require('./const');
12 |
13 | const MooValueHandler = {
14 | display(styleVal) {
15 | return `${styleVal === 'none' ? 'z-' : 'u-'}${
16 | {
17 | 'inline-block': 'block_il',
18 | none: 'hide',
19 | }[styleVal] || styleVal
20 | }`;
21 | },
22 |
23 | opacity(styleVal) {
24 | return `${~~(styleVal * CONST.ONE_HUNDRED)}`;
25 | },
26 |
27 | 'font-family'(styleVal) {
28 | return styleVal && styleVal.split(',')[CONST.NO_ZERO];
29 | },
30 |
31 | 'box-size'() {
32 | return 'box-sizing';
33 | },
34 |
35 | 'line-height'(styleVal) {
36 | if (!Number.isNaN(+styleVal)) {
37 | return `${~~parseFloat(styleVal * CONST.ONE_HUNDRED)}%`;
38 | } else {
39 | return styleVal;
40 | }
41 | },
42 | };
43 |
44 | /**
45 | * @function style2MooSelector
46 | * @description style content -> moo-css selector
47 | * @param {string} stylename
48 | * @param {string} styleVal
49 | * @return {string | false}
50 | */
51 | function style2MooSelector(stylename, _styleVal) {
52 | // handle display
53 | if (stylename === 'display') {
54 | return MooValueHandler.display(_styleVal);
55 | }
56 | let styleVal = _styleVal;
57 | // handle rgba color
58 | if (styleVal.startsWith('rgba') && styleVal.endsWith('1)')) {
59 | styleVal = styleVal.replace(/\s/g, '').replace('rgba', 'rgb').replace(',1)', ')');
60 | } else if (MooValueHandler[stylename]) {
61 | styleVal = MooValueHandler[stylename](styleVal);
62 | }
63 |
64 | const name = C2Mdata[stylename];
65 | const value = utils.getStyleValue(styleVal);
66 |
67 | return name && value ? name + value : '';
68 | }
69 |
70 | module.exports = {
71 | style2MooSelector,
72 | styleScaner: scaner,
73 | };
74 |
--------------------------------------------------------------------------------
/moo-css-transformer/src/const.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @constants
3 | * @author Wayne
4 | * @time 2020.02.19
5 | */
6 |
7 | const NO_ZERO = 0;
8 | const NO_ONE = 1;
9 | const NO_LAST = -1;
10 | const ONE_HUNDRED = 100;
11 | const DEFAULT_SCREEN_SIZE = 750;
12 | const HEX_LENGTH = 6;
13 |
14 | module.exports = {
15 | NO_ZERO,
16 | NO_ONE,
17 | NO_LAST,
18 | ONE_HUNDRED,
19 | DEFAULT_SCREEN_SIZE,
20 | HEX_LENGTH,
21 | };
22 |
--------------------------------------------------------------------------------
/moo-css-transformer/src/m2c.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @module m2c
3 | * @description moo to css
4 | * @author Wayne
5 | * @time 2020.02.19
6 | */
7 | const utils = require('./utils');
8 | const M2Cdata = require('../datas/m2c-data.json');
9 | const CONST = require('./const');
10 | const { BOX_LIST, MINI_LIST, MINI_LIST_MAP } = require('../config');
11 |
12 | function _getBasicCSS(moduleName, minname) {
13 | let cssAttr = '';
14 | let cssVal = '';
15 | const tagMap = M2Cdata[moduleName];
16 |
17 | if (tagMap) {
18 | for (const key in tagMap) {
19 | if (!utils.hasOwnProp(tagMap, key)) continue;
20 | const _tag = `${moduleName}-${key}`;
21 |
22 | if (
23 | minname.includes(_tag) &&
24 | (minname[_tag.length] === '_' ||
25 | +minname[_tag.length] ||
26 | _tag.length >= minname.length - CONST.NO_ONE)
27 | ) {
28 | cssAttr = tagMap[key];
29 | cssVal = minname.replace(_tag, '');
30 | break;
31 | }
32 | }
33 | }
34 | return {
35 | cssAttr,
36 | cssVal,
37 | };
38 | }
39 |
40 | /**
41 | * @function m2c
42 | * @param {String} minname
43 | * @param {String} lenUnit
44 | * @param {Number} viewport
45 | * @returns
46 | */
47 | // eslint-disable-next-line complexity
48 | function m2c(minname, lenUnit = 'vw', viewport = CONST.DEFAULT_SCREEN_SIZE) {
49 | let cssAttr = '';
50 | let cssVal = '';
51 | if (minname.includes('-')) {
52 | const moduleName = minname.split('-')[CONST.NO_ZERO];
53 |
54 | const basicCSS = _getBasicCSS(moduleName, minname);
55 | cssAttr = basicCSS.cssAttr;
56 | cssVal = basicCSS.cssVal;
57 |
58 | if (BOX_LIST.find(item => cssAttr.includes(item))) {
59 | // handle size
60 | const _val = cssVal.match(/\d+/g);
61 |
62 | if (cssVal.endsWith('per')) {
63 | cssVal = `${parseInt(cssVal, 10)}%`;
64 | } else if (lenUnit !== 'px') {
65 | let _valNum = String(utils.SizeUnit[`px2${lenUnit}`](_val[CONST.NO_ZERO], viewport));
66 | const _index = _valNum.indexOf('.');
67 | if (_index > -1) {
68 | _valNum = _valNum.slice(0, _index + 6);
69 | }
70 | cssVal = _val ? _valNum + lenUnit : '';
71 | } else {
72 | cssVal += lenUnit;
73 | }
74 | } else if (MINI_LIST.includes(cssAttr)) {
75 | cssVal = MINI_LIST_MAP[cssAttr][cssVal] || cssVal;
76 | } else if (cssAttr.includes('color')) {
77 | // handle colors
78 | cssVal = `#${cssVal.slice(CONST.NO_ONE)}`;
79 | } else if (moduleName === 'f' && cssVal.startsWith('_r')) {
80 | // handle rotate
81 | cssVal = `rotate(${parseInt(cssVal.replace('_r', ''), 10)}deg)`;
82 | } else if (cssVal.startsWith('_')) {
83 | cssVal = cssVal.slice(CONST.NO_ONE);
84 | }
85 | //}
86 | }
87 | return {
88 | key: minname,
89 | attr: cssAttr,
90 | val: cssVal,
91 | };
92 | }
93 |
94 | module.exports = {
95 | m2c,
96 | };
97 |
--------------------------------------------------------------------------------
/moo-css-transformer/src/scaner.js:
--------------------------------------------------------------------------------
1 | /**
2 | * DFS css style scaner
3 | */
4 |
5 | const TAG_STATUS_MAP = {
6 | OUTTER: 0,
7 | INNER: 1,
8 | };
9 |
10 | /**
11 | * @function scanner
12 | * @description css string scanner
13 | * @param {string} cssStr
14 | * @returns {Array}
15 | */
16 | function scaner(cssStr) {
17 | cssStr = String(cssStr);
18 | if (!cssStr || !cssStr.includes('{')) {
19 | return false;
20 | }
21 | cssStr = cssStr.replace(/[\r\n\t]/g, '').replace(/\:\s/g, ':');
22 | // 0: out of tag; 1: in css selector
23 | let tagStatus = TAG_STATUS_MAP.OUTTER;
24 | let _styleStr = '';
25 | const styleSet = new Set();
26 | for (let i = 0, len = cssStr.length; i < len; i++) {
27 | const _str = cssStr[i];
28 | if (tagStatus) {
29 | if (_str !== '}') {
30 | if (_str !== ';') {
31 | _styleStr += _str;
32 | } else {
33 | styleSet.add(_styleStr.trim());
34 | _styleStr = '';
35 | }
36 | } else {
37 | // close
38 | if (_styleStr) {
39 | _styleStr = _styleStr.trim();
40 | _styleStr && styleSet.add(_styleStr);
41 | _styleStr = '';
42 | }
43 | tagStatus = TAG_STATUS_MAP.OUTTER;
44 | continue;
45 | }
46 | } else {
47 | if (_str !== '{') continue;
48 | else {
49 | tagStatus = TAG_STATUS_MAP.INNER;
50 | }
51 | }
52 | }
53 |
54 | return Array.from(styleSet);
55 | }
56 |
57 | module.exports = scaner;
58 |
--------------------------------------------------------------------------------
/moo-css-transformer/src/utils.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-magic-numbers */
2 | /**
3 | * @module utils
4 | * @author Wayne
5 | * @time 2020.02.19
6 | */
7 |
8 | const CONST = require('./const');
9 | const { NAMEID_MAP, VALUEID_MAP } = require('../config');
10 |
11 | /**
12 | * @function type
13 | * @description get value type
14 | * @param {any} val
15 | * @return {string}
16 | */
17 | function type(val) {
18 | return Object.prototype.toString.call(val).replace(/\[object\s|\]/g, '');
19 | }
20 |
21 | /**
22 | * @function hasOwnProp
23 | * @param {Object} obj
24 | * @param {string} key
25 | * @returns
26 | */
27 | function hasOwnProp(obj, key) {
28 | return Object.prototype.hasOwnProperty.call(obj, key);
29 | }
30 |
31 | /**
32 | * @function each
33 | * @description traverse array
34 | * @param {array} array
35 | * @param {Function} fn
36 | */
37 | function each(array, fn) {
38 | for (let i = 0, len = array.length; i < len; i++) {
39 | fn(array[i], i);
40 | }
41 | }
42 |
43 | /**
44 | * @function getStrnumInt
45 | * @param {string} str
46 | * @param {number} multiple
47 | */
48 | function getStrnumInt(str, multiple = 1) {
49 | // eslint-disable-next-line no-bitwise
50 | return ~~(parseFloat(str) * multiple);
51 | }
52 |
53 | /**
54 | * grb转16进制
55 | * @param {string[]} rgb
56 | * @return {number}
57 | */
58 | function rgbToHex(rgb) {
59 | return rgb
60 | .map(value => {
61 | const _value = Number(value);
62 | return `${_value < 15 ? '0' : ''}${_value.toString(16)}`;
63 | })
64 | .join('');
65 | }
66 |
67 | function _getNameId(name) {
68 | return NAMEID_MAP[name] || name.charAt(CONST.NO_ZERO);
69 | }
70 | /**
71 | * get style name abbreviation
72 | * @param {string} name
73 | * @param {boolean} extendbool
74 | * @return {string}
75 | */
76 | function getStyleMinName(name, extendbool) {
77 | if (NAMEID_MAP[name]) {
78 | return NAMEID_MAP[name];
79 | } else if (name.includes('-')) {
80 | const nameArr = name.split('-');
81 | return (
82 | _getNameId(nameArr[CONST.NO_ZERO]) +
83 | (extendbool ? name.slice(CONST.NO_LAST) : '') +
84 | nameArr
85 | .slice(1)
86 | .map(letter => letter.charAt(CONST.NO_ZERO))
87 | .join('')
88 | );
89 | } else {
90 | return _getNameId(name) + (extendbool ? name.slice(CONST.NO_LAST) : '');
91 | }
92 | }
93 |
94 | /**
95 | * @Object SizeUnit
96 | * @description 长度单位计算集合
97 | */
98 | const SizeUnit = {
99 | vw2px(val, viewport) {
100 | return getStrnumInt(val, viewport / 100);
101 | },
102 | rem2px(val, viewport) {
103 | return getStrnumInt(val, viewport / 10);
104 | },
105 | px2rem(val, viewport) {
106 | return val / (viewport / 10);
107 | },
108 | px2vw(val, viewport) {
109 | return val / (viewport / 100);
110 | },
111 |
112 | handleSize(styleval, viewport) {
113 | const _unit = styleval.slice(-3).replace(/\d/, '');
114 | if (_unit === 'px') {
115 | return styleval.replace('px', '');
116 | }
117 | if (SizeUnit[`${_unit}2px`]) {
118 | return SizeUnit[`${_unit}2px`](styleval, viewport);
119 | }
120 | if (styleval.includes('.')) {
121 | return '';
122 | }
123 | return styleval.replace('%', 'per');
124 | },
125 | };
126 |
127 | /**
128 | * get style value abbreviation
129 | * @param {string|number} styleval
130 | * @param {number} viewport
131 | * @return {string}
132 | * @todo box-shadow,animation,transition,transform...
133 | */
134 | function getStyleValue(_styleVal = '', viewport = CONST.DEFAULT_SCREEN_SIZE) {
135 | const styleval = _styleVal.trim();
136 | if (!styleval || (styleval.includes(' ') && !styleval.startsWith('rgb('))) {
137 | return '';
138 | }
139 |
140 | if (VALUEID_MAP[styleval]) {
141 | return VALUEID_MAP[styleval];
142 | }
143 |
144 | if (styleval[CONST.NO_ZERO].match(/\d/) || styleval[CONST.NO_ZERO] === '.') {
145 | // number value
146 | return SizeUnit.handleSize(styleval, viewport);
147 | } else if (styleval.startsWith('#')) {
148 | // hex color
149 | return `_${styleval.replace('#', '')}`;
150 | } else if (styleval.startsWith('rgb(')) {
151 | // rgb color
152 | return `_${rgbToHex(styleval.replace(/[^\d|\,]/g, '').split(','))}`;
153 | } else if (styleval.startsWith('rotate(')) {
154 | // rotate
155 | return `_r${parseInt(styleval.replace('rotate(', ''), 10)}`;
156 | } else {
157 | return `_${getStyleMinName(styleval)}`;
158 | }
159 | }
160 |
161 | module.exports = {
162 | type,
163 | each,
164 | getStyleMinName,
165 | getStyleValue,
166 | getStrnumInt,
167 | SizeUnit,
168 | hasOwnProp,
169 | };
170 |
--------------------------------------------------------------------------------
/moo-css-transformer/test/c2m.test.js:
--------------------------------------------------------------------------------
1 | const c2m = require('../src/c2m');
2 | const { style2MooSelector, styleScaner } = c2m;
3 |
4 | /**
5 | * dom
6 | */
7 | describe('c2m font test', () => {
8 | it('text test', () => {
9 | // text
10 | expect(style2MooSelector('font-size', '20px')).toBe('g-fs20');
11 | expect(style2MooSelector('font-size', '0.333rem')).toBe('g-fs24');
12 | expect(style2MooSelector('font-size', '2vw')).toBe('g-fs15');
13 |
14 | // color
15 | expect(style2MooSelector('color', '#fff')).toBe('s-cr_fff');
16 | expect(style2MooSelector('color', 'rgb(255, 30, 0)')).toBe('s-cr_ff1e00');
17 |
18 | // text-align
19 | expect(style2MooSelector('text-align', 'center')).toBe('f-tc');
20 | expect(style2MooSelector('text-align', 'left')).toBe('f-tl');
21 | expect(style2MooSelector('text-align', 'right')).toBe('f-tr');
22 |
23 | expect(style2MooSelector('vertical-align', 'middle')).toBe('f-vm');
24 | expect(style2MooSelector('vertical-align', 'top')).toBe('f-vt');
25 | expect(style2MooSelector('vertical-align', 'bottom')).toBe('f-vb');
26 |
27 | // line-height
28 | expect(style2MooSelector('line-height', '1.5')).toBe('g-lh150per');
29 | expect(style2MooSelector('line-height', '40px')).toBe('g-lh40');
30 | expect(style2MooSelector('line-height', '150%')).toBe('g-lh150per');
31 |
32 | // text-shadow
33 | });
34 |
35 | it('shape test', () => {
36 | expect(style2MooSelector('width', '300px')).toBe('u-w300');
37 | expect(style2MooSelector('width', '3rem')).toBe('u-w225');
38 | expect(style2MooSelector('width', '3vw')).toBe('u-w22');
39 | expect(style2MooSelector('height', '200px')).toBe('u-h200');
40 | expect(style2MooSelector('height', '1rem')).toBe('u-h75');
41 | expect(style2MooSelector('height', '5.5vw')).toBe('u-h41');
42 | expect(style2MooSelector('border-radius', '5px')).toBe('f-bdr5');
43 | });
44 |
45 | it('grid test', () => {
46 | expect(style2MooSelector('margin-top', '30px')).toBe('g-mt30');
47 | expect(style2MooSelector('margin-left', '20px')).toBe('g-ml20');
48 | expect(style2MooSelector('margin-bottom', '10px')).toBe('g-mb10');
49 | expect(style2MooSelector('margin-right', '5px')).toBe('g-mr5');
50 | expect(style2MooSelector('padding-top', '30px')).toBe('u-pt30');
51 | expect(style2MooSelector('padding-left', '20px')).toBe('u-pl20');
52 | expect(style2MooSelector('padding-bottom', '10px')).toBe('u-pb10');
53 | expect(style2MooSelector('padding-right', '5px')).toBe('u-pr5');
54 |
55 | expect(style2MooSelector('top', '30px')).toBe('g-t30');
56 | expect(style2MooSelector('left', '20px')).toBe('g-l20');
57 | expect(style2MooSelector('bottom', '10px')).toBe('g-b10');
58 | expect(style2MooSelector('right', '5px')).toBe('g-r5');
59 |
60 | expect(style2MooSelector('position', 'relative')).toBe('g-pr');
61 | expect(style2MooSelector('position', 'absolute')).toBe('g-pa');
62 | expect(style2MooSelector('position', 'fixed')).toBe('g-pf');
63 | });
64 |
65 | it('scanner test', () => {
66 | expect(
67 | styleScaner(`
68 | body{
69 | padding: 0 4% 50px;
70 | color: #333;
71 | font-size: 13px;
72 | line-height: 1.5;
73 | }`)[0]
74 | ).toBe('padding:0 4% 50px');
75 |
76 | expect(
77 | styleScaner(`
78 | table th, table td{border: solid 1px #d8d8d8;}
79 | table tbody tr td:first-child{text-align: center;}`)[0]
80 | ).toBe('border:solid 1px #d8d8d8');
81 | });
82 | });
83 |
--------------------------------------------------------------------------------
/moo-css-transformer/test/m2c.test.js:
--------------------------------------------------------------------------------
1 | const { m2c } = require('../dist/m2c');
2 |
3 | /**
4 | * m2c test
5 | */
6 | describe('m2c keys test', () => {
7 | it('size attribute analyse test', () => {
8 | expect(m2c('g-m10').attr).toBe('margin');
9 | expect(m2c('g-mt10').attr).toBe('margin-top');
10 | expect(m2c('g-ml10').attr).toBe('margin-left');
11 | expect(m2c('g-mr10').attr).toBe('margin-right');
12 | expect(m2c('g-mb10').attr).toBe('margin-bottom');
13 | expect(m2c('g-t10').attr).toBe('top');
14 | expect(m2c('g-l10').attr).toBe('left');
15 | expect(m2c('g-r10').attr).toBe('right');
16 | expect(m2c('g-b10').attr).toBe('bottom');
17 | expect(m2c('g-lh10').attr).toBe('line-height');
18 | expect(m2c('u-h100').attr).toBe('height');
19 | expect(m2c('u-mh100').attr).toBe('max-height');
20 | expect(m2c('u-mth100').attr).toBe('min-height');
21 | expect(m2c('u-w100').attr).toBe('width');
22 | expect(m2c('u-mw100').attr).toBe('max-width');
23 | expect(m2c('u-mhw100').attr).toBe('min-width');
24 | expect(m2c('u-p10').attr).toBe('padding');
25 | expect(m2c('u-pl10').attr).toBe('padding-left');
26 | expect(m2c('u-pr10').attr).toBe('padding-right');
27 | expect(m2c('u-pb10').attr).toBe('padding-bottom');
28 | expect(m2c('u-pt10').attr).toBe('padding-top');
29 |
30 | expect(m2c('u-bdbw100').attr).toBe('border-bottom-width');
31 | expect(m2c('u-bdiw100').attr).toBe('border-image-width');
32 | expect(m2c('u-bdlw100').attr).toBe('border-left-width');
33 | expect(m2c('u-bdrw100').attr).toBe('border-right-width');
34 | expect(m2c('u-bdtw100').attr).toBe('border-top-width');
35 | expect(m2c('u-bdtw100').attr).toBe('border-top-width');
36 | expect(m2c('u-bdw100').attr).toBe('border-width');
37 | expect(m2c('u-ow100').attr).toBe('outline-width');
38 | });
39 |
40 | it('color attribute analyse test', () => {
41 | expect(m2c('s-cr_f00').attr).toBe('color');
42 | expect(m2c('s-oc_f00').attr).toBe('outline-color');
43 | expect(m2c('s-bdtc_f00').attr).toBe('border-top-color');
44 | expect(m2c('s-bdrc_f00').attr).toBe('border-right-color');
45 | expect(m2c('s-bdlc_f00').attr).toBe('border-left-color');
46 | expect(m2c('s-bdbc_f00').attr).toBe('border-bottom-color');
47 | expect(m2c('s-bgc_f00').attr).toBe('background-color');
48 | });
49 |
50 | it('transform attribute analyse test', () => {
51 | expect(m2c('f-trans_r90').attr).toBe('transform');
52 | });
53 |
54 | it('simple attribute analyse test', () => {
55 | expect(m2c('g-box_border-box').attr).toBe('box-sizing');
56 | expect(m2c('g-pr').attr).toBe('position');
57 | expect(m2c('g-pf').attr).toBe('position');
58 | expect(m2c('g-pa').attr).toBe('position');
59 | expect(m2c('g-fs24').attr).toBe('font-size');
60 | expect(m2c('f-bgc_border-box').attr).toBe('background-clip');
61 | expect(m2c('f-bgo_center').attr).toBe('background-origin');
62 | expect(m2c('f-bgr_no-repeat').attr).toBe('background-repeat');
63 | expect(m2c('f-bdb10').attr).toBe('border-bottom');
64 | expect(m2c('f-bdl10').attr).toBe('border-left');
65 | expect(m2c('f-bdt10').attr).toBe('border-top');
66 | expect(m2c('f-bdtr10').attr).toBe('border-right');
67 | expect(m2c('f-bdtlr10').attr).toBe('border-top-left-radius');
68 | expect(m2c('f-bdtrr10').attr).toBe('border-top-right-radius');
69 | expect(m2c('f-bdblr10').attr).toBe('border-bottom-left-radius');
70 | expect(m2c('f-bdbrr10').attr).toBe('border-bottom-right-radius');
71 | expect(m2c('f-c_both').attr).toBe('clear');
72 | expect(m2c('f-fr').attr).toBe('float');
73 | expect(m2c('f-fl').attr).toBe('float');
74 | expect(m2c('f-ov_hidden').attr).toBe('overflow');
75 | expect(m2c('f-ovx_hidden').attr).toBe('overflow-x');
76 | expect(m2c('f-ovy_hidden').attr).toBe('overflow-y');
77 | expect(m2c('f-ff_DIN').attr).toBe('font-family');
78 | expect(m2c('f-fs_italic').attr).toBe('font-style');
79 | expect(m2c('f-fw_bold').attr).toBe('font-weight');
80 | expect(m2c('f-tc').attr).toBe('text-align');
81 | expect(m2c('f-td_underline').attr).toBe('text-decoration');
82 | expect(m2c('f-ti2').attr).toBe('text-indent');
83 | expect(m2c('f-tj_center').attr).toBe('text-justify');
84 | expect(m2c('f-cr_pointer').attr).toBe('cursor');
85 | expect(m2c('u-ai_center').attr).toBe('align-items');
86 | expect(m2c('u-jc_center').attr).toBe('justify-content');
87 | expect(m2c('u-d_block').attr).toBe('display');
88 | expect(m2c('u-flexd_row').attr).toBe('flex-direction');
89 | expect(m2c('z-v_hidden').attr).toBe('visibility');
90 | expect(m2c('z-zi_999').attr).toBe('z-index');
91 | expect(m2c('z-hide_99').attr).toBe('opacity');
92 | });
93 | it('simple value analyse test', () => {
94 | expect(m2c('g-box_border-box').val).toBe('border-box');
95 | expect(m2c('g-pr').val).toBe('relative');
96 | expect(m2c('g-pf').val).toBe('fixed');
97 | expect(m2c('g-pa').val).toBe('absolute');
98 | expect(m2c('g-fs20').val).toBe('2.66666vw');
99 | expect(m2c('g-lh200per').val).toBe('200%');
100 | expect(m2c('f-bgc_border-box').val).toBe('border-box');
101 | expect(m2c('f-bgo_center').val).toBe('center');
102 | expect(m2c('f-bgr_no-repeat').val).toBe('no-repeat');
103 | expect(m2c('f-bdb10').val).toBe('1.33333vw');
104 | expect(m2c('f-bdl10').val).toBe('1.33333vw');
105 | expect(m2c('f-bdt10').val).toBe('1.33333vw');
106 | expect(m2c('f-bdtr10').val).toBe('1.33333vw');
107 | expect(m2c('f-bdtlr10').val).toBe('1.33333vw');
108 | expect(m2c('f-bdtrr10').val).toBe('1.33333vw');
109 | expect(m2c('f-bdblr10').val).toBe('1.33333vw');
110 | expect(m2c('f-bdbrr10').val).toBe('1.33333vw');
111 | expect(m2c('f-c_both').val).toBe('both');
112 | expect(m2c('f-fr').val).toBe('right');
113 | expect(m2c('f-fl').val).toBe('left');
114 | expect(m2c('f-ov_hidden').val).toBe('hidden');
115 | expect(m2c('f-ovx_hidden').val).toBe('hidden');
116 | expect(m2c('f-ovy_hidden').val).toBe('hidden');
117 | expect(m2c('f-ff_DIN').val).toBe('DIN');
118 | expect(m2c('f-fs_italic').val).toBe('italic');
119 | expect(m2c('f-fw_bold').val).toBe('bold');
120 | expect(m2c('f-tc').val).toBe('center');
121 | expect(m2c('f-td_underline').val).toBe('underline');
122 | expect(m2c('f-ti2').val).toBe('2');
123 | expect(m2c('f-tj_center').val).toBe('center');
124 | expect(m2c('f-cr_pointer').val).toBe('pointer');
125 | expect(m2c('u-ai_center').val).toBe('center');
126 | expect(m2c('u-jc_center').val).toBe('center');
127 | expect(m2c('u-d_block').val).toBe('block');
128 | expect(m2c('u-flexd_row').val).toBe('row');
129 | expect(m2c('z-v_hidden').val).toBe('hidden');
130 | expect(m2c('z-zi_999').val).toBe('999');
131 | expect(m2c('z-hide_99').val).toBe('99');
132 | });
133 | });
134 |
--------------------------------------------------------------------------------
/moo-css-transformer/types/index.d.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 | type cssValue = string | number;
4 |
5 | interface m2cResult {
6 | key: string;
7 | attr: string;
8 | val: cssValue;
9 | }
10 |
11 |
12 | declare module 'moo-css-transformer' {
13 | /**
14 | * MooCSS selector --> CSS values
15 | * @param minName
16 | * @param lenUnit
17 | * @param viewport
18 | */
19 | export function m2c (minName: string, lenUnit?: string, viewport?: number): m2cResult;
20 |
21 | /**
22 | * CSS values --> MooCSS selector
23 | * @param styleName
24 | * @param styleVal
25 | */
26 | export function c2m (styleName: string, styleVal: cssValue): string;
27 |
28 | /**
29 | * CSS sheet --> CSS list
30 | * @param cssStr
31 | */
32 | export function styleScaner (cssStr: string): string[];
33 |
34 | interface MooCssTransformerType {
35 | m2c: typeof m2c,
36 | c2m: typeof c2m,
37 | styleScaner: typeof styleScaner
38 | }
39 | const MooCssTransformer: {
40 | m2c: typeof m2c,
41 | c2m: typeof c2m,
42 | styleScaner: typeof styleScaner,
43 | }
44 | export default MooCssTransformer
45 | }
--------------------------------------------------------------------------------
/moo-css-transformer/webpack.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * moo-css-transformer webpack config
3 | * @author Wayne
4 | * @date 2021.02.21
5 | */
6 |
7 | const path = require('path');
8 | const webpack = require('webpack');
9 | const pkg = require('./package.json');
10 | const myBanner = `
11 | ${pkg.name}
12 | @github ${pkg.repository.url}
13 | `;
14 |
15 | module.exports = {
16 | mode: 'production',
17 | entry: {
18 | c2m: path.join(__dirname, './src/c2m.js'),
19 | m2c: path.join(__dirname, './src/m2c.js'),
20 | },
21 | output: {
22 | path: path.join(__dirname, 'dist'),
23 | filename: '[name].js',
24 | publicPath: path.join(__dirname),
25 | libraryTarget: 'commonjs',
26 | },
27 | module: {
28 | rules: [
29 | {
30 | test: /\.js$/,
31 | loader: 'babel-loader',
32 | query: {
33 | presets: [
34 | [
35 | '@babel/env',
36 | {
37 | loose: true,
38 | },
39 | ],
40 | ],
41 | },
42 | },
43 | ],
44 | },
45 | node: {
46 | fs: 'empty',
47 | },
48 | plugins: [new webpack.BannerPlugin(myBanner)],
49 | };
50 |
--------------------------------------------------------------------------------
/moo-css-weapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "moo-css-weapp",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": ""
8 | },
9 | "author": "Micheal Wang",
10 | "license": "ISC",
11 | "dependencies": {}
12 | }
13 |
--------------------------------------------------------------------------------
/moo-css-weapp/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist/",
4 | "sourceMap": true,
5 | "strict": true,
6 | "noImplicitAny": true,
7 | "module": "commonjs",
8 | "target": "es5",
9 | "allowJs": true,
10 | "baseUrl": ".",
11 | "paths": {
12 | "@/*": [
13 | "src/*"
14 | ]
15 | },
16 | "typeRoots": ["./src/types/"],
17 | "rootDir": "./src/"
18 | }
19 | }
--------------------------------------------------------------------------------
/moo-css-web/.eslintignore:
--------------------------------------------------------------------------------
1 | /node_modules/*
2 | src/js/lib/*.js
3 | lib/*.js
--------------------------------------------------------------------------------
/moo-css-web/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /npm-debug.log*
6 | /yarn-error.log
7 | /yarn.lock
8 | # /package-lock.json
9 | /coverage
10 |
11 |
12 | # production
13 | /dist
14 |
15 | # misc
16 | .DS_Store
17 |
18 | # logs
19 | /*.log
20 |
21 | # vscode
22 | /.vscode
23 |
24 | # zip
25 | /*.zip
26 |
--------------------------------------------------------------------------------
/moo-css-web/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "printWidth": 100, // 每行代码长度
3 | "tabWidth": 2, // tab 宽度(2个空格)
4 | "useTabs": false, // 不使用 tab 缩进
5 | "singleQuote": true, // 使用单引号
6 | "semi": true, // 使用分号
7 | "trailingComma": "es5", // 在 es5 中合法的地方加尾逗号
8 | "bracketSpacing": true, // 对象字面量的大括号间使用空格
9 | "arrowParens": "avoid" // 只有一个参数的箭头函数参数不带圆括号
10 | };
11 |
--------------------------------------------------------------------------------
/moo-css-web/dist/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @namespace mvdom2web
4 | */
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | const json2html_1 = require("./json2html");
7 | const moo_css_transformer_1 = require("moo-css-transformer");
8 | function handleData(config) {
9 | let { data, handleImg, nostyle, viewport, } = config;
10 | let cssTextObj = {};
11 | const _style2MooSelector = (str) => {
12 | let _arr = str.split(':');
13 | if (!_arr[1] || _arr[1] === 'undefined')
14 | return undefined;
15 | return moo_css_transformer_1.c2m.style2MooSelector(_arr[0], _arr[1]);
16 | };
17 | const _handleStyleProps = (props) => {
18 | let styleList = moo_css_transformer_1.c2m.styleScaner(`{${props.style}}`);
19 | let classList = [];
20 | if (!nostyle) {
21 | let newStyle = styleList.filter((item) => {
22 | if (viewport && ~item.indexOf('px')) { // mobile
23 | let arr = item.split(':');
24 | item = `${arr[0]}:${(parseInt(arr[1]) / viewport * 100).toFixed(4)}vw`;
25 | }
26 | let moo = _style2MooSelector(item);
27 | if (moo) {
28 | classList.push(moo);
29 | if (!cssTextObj[moo])
30 | cssTextObj[moo] = item;
31 | return false;
32 | }
33 | else if (moo !== undefined) {
34 | return item;
35 | }
36 | else
37 | return false;
38 | }).join(';');
39 | props.style = newStyle;
40 | }
41 | else {
42 | let moduleClassList = [];
43 | styleList.forEach((item) => {
44 | if (viewport && ~item.indexOf('px')) { // mobile
45 | let arr = item.split(':');
46 | item = `${arr[0]}:${(parseInt(arr[1]) / viewport * 100).toFixed(4)}vw`;
47 | }
48 | let moo = _style2MooSelector(item);
49 | if (moo) {
50 | classList.push(moo);
51 | if (!cssTextObj[moo])
52 | cssTextObj[moo] = item;
53 | return false;
54 | }
55 | else if (moo !== undefined) {
56 | moduleClassList.push(item);
57 | return item;
58 | }
59 | else
60 | return false;
61 | });
62 | if (moduleClassList.length) {
63 | props.className = 'm-' + ('' + Math.random()).slice(-6);
64 | cssTextObj[props.className] = moduleClassList.join(';');
65 | }
66 | delete props.style;
67 | }
68 | if (classList.length) {
69 | let className = classList.join(' ');
70 | props.className = (props.className ? props.className + ' ' : '') + className;
71 | return className;
72 | }
73 | };
74 | let htmlTxt = json2html_1.default.build(data, {
75 | handleStyle: _handleStyleProps,
76 | handleImg
77 | });
78 | let cssTxt = '';
79 | for (let selector in cssTextObj) {
80 | cssTxt += `
81 | .${selector} {
82 | ${cssTextObj[selector]}
83 | }`;
84 | }
85 | return {
86 | html: htmlTxt,
87 | css: cssTxt
88 | };
89 | }
90 | exports.default = handleData;
91 |
--------------------------------------------------------------------------------
/moo-css-web/dist/json2html.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @module json2html
4 | */
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | class JSON2HTML {
7 | static get selfCloseTags() {
8 | return [
9 | 'area', 'base', 'br', 'col', 'embed', 'hr',
10 | 'img', 'input', 'link', 'meta', 'param', 'source',
11 | 'track', 'wbr', 'command', 'keygen', 'menuitem',
12 | ];
13 | }
14 | static build(json, handlers) {
15 | if (!json || !json.tagName)
16 | return '';
17 | const props = JSON2HTMLBuilder.props(json, handlers);
18 | if (JSON2HTMLBuilder.isSelfCloseTag(json)) {
19 | return `<${json.tagName}${props}/>`;
20 | }
21 | const children = JSON2HTMLBuilder.children(json, handlers);
22 | return `
23 | <${json.tagName}${props}>${children}${json.tagName}>`;
24 | }
25 | }
26 | exports.default = JSON2HTML;
27 | class JSON2HTMLBuilder {
28 | static props(json, handlers) {
29 | let props = json.props;
30 | if (!props)
31 | return '';
32 | let html = '';
33 | const { handleStyle, handleImg, } = handlers;
34 | if (props.style && handleStyle) {
35 | handleStyle(props);
36 | }
37 | if (props.src && handleImg && props.src.startsWith('data:image')) {
38 | handleImg(props);
39 | }
40 | const keys = Object.keys(props);
41 | for (const index in keys) {
42 | let key = keys[index];
43 | if (key === 'children')
44 | continue;
45 | else if (key === 'className')
46 | html += ` class="${props[key]}"`;
47 | else if ({}.hasOwnProperty.call(keys, index)) {
48 | if (props[key])
49 | html += ` ${key}="${props[key]}"`;
50 | }
51 | }
52 | return html;
53 | }
54 | static children(json, handlers) {
55 | let children = json.props && json.props.children;
56 | if (!children)
57 | return '';
58 | let html = '';
59 | for (const index in children) {
60 | if ({}.hasOwnProperty.call(children, index)) {
61 | if (typeof children[index] == 'object') {
62 | html += JSON2HTML.build(children[index], handlers);
63 | }
64 | else {
65 | html += children[index];
66 | }
67 | }
68 | }
69 | return html;
70 | }
71 | static isSelfCloseTag(json) {
72 | return (JSON2HTML.selfCloseTags.indexOf(json.tag) > -1);
73 | }
74 | }
75 | exports.JSON2HTMLBuilder = JSON2HTMLBuilder;
76 | ;
77 |
--------------------------------------------------------------------------------
/moo-css-web/dist/src/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @namespace mvdom2web
4 | */
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | const json2html_1 = require("./json2html");
7 | function test(json) {
8 | console.log(json2html_1.default.build(json));
9 | }
10 | exports.default = test;
11 |
--------------------------------------------------------------------------------
/moo-css-web/dist/src/json2html.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * @module json2html
4 | */
5 | Object.defineProperty(exports, "__esModule", { value: true });
6 | class JSON2HTML {
7 | static get selfCloseTags() {
8 | return [
9 | 'area', 'base', 'br', 'col', 'embed', 'hr',
10 | 'img', 'input', 'link', 'meta', 'param', 'source',
11 | 'track', 'wbr', 'command', 'keygen', 'menuitem',
12 | ];
13 | }
14 | static build(json, handleStyle) {
15 | if (!json || !json.tagName)
16 | return '';
17 | const props = JSON2HTMLBuilder.props(json, handleStyle);
18 | if (JSON2HTMLBuilder.isSelfCloseTag(json)) {
19 | return `<${json.tagName}${props}/>`;
20 | }
21 | const children = JSON2HTMLBuilder.children(json);
22 | return `<${json.tagName}${props}>
23 | ${children}
24 | ${json.tagName}>`;
25 | }
26 | }
27 | exports.default = JSON2HTML;
28 | class JSON2HTMLBuilder {
29 | static props(json, handleStyle) {
30 | if (!json.props)
31 | return '';
32 | let html = '';
33 | const keys = Object.keys(json.props);
34 | if (json.props.style && handleStyle) {
35 | handleStyle(json.props);
36 | }
37 | for (const index in keys) {
38 | let key = keys[index];
39 | if (key === 'children')
40 | continue;
41 | if ({}.hasOwnProperty.call(keys, index)) {
42 | html += ` ${key}="${json.props[key]}"`;
43 | }
44 | }
45 | return html;
46 | }
47 | static children(json) {
48 | let children = json.props && json.props.children;
49 | if (!children)
50 | return '';
51 | let html = '';
52 | for (const index in children) {
53 | if ({}.hasOwnProperty.call(children, index)) {
54 | if (typeof children[index] == 'object') {
55 | html += JSON2HTML.build(children[index]);
56 | }
57 | else {
58 | html += children[index];
59 | }
60 | }
61 | }
62 | return html;
63 | }
64 | static isSelfCloseTag(json) {
65 | return (JSON2HTML.selfCloseTags.indexOf(json.tag) > -1);
66 | }
67 | }
68 | exports.JSON2HTMLBuilder = JSON2HTMLBuilder;
69 | ;
70 |
--------------------------------------------------------------------------------
/moo-css-web/dist/utils/handleImage.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | /**
3 | * handle image base64
4 | */
5 | /*
6 | export default function handleImgBase64 (base64: string) {
7 | let base64Data = base64.replace(/^data:image\/\w+;base64,/, '');
8 | let dataBuffer = new Buffer(base64Data, 'base64');
9 | return dataBuffer;
10 | }*/
11 |
--------------------------------------------------------------------------------
/moo-css-web/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "moo-css-web",
3 | "version": "1.0.0",
4 | "description": "mvdom data to html and css file.",
5 | "main": "dist/index.js",
6 | "scripts": {
7 | "test": "node ./__test__/",
8 | "build": "tsc"
9 | },
10 | "devDependencies": {
11 | "@types/node": "^13.7.6",
12 | "typescript": "^3.4.4"
13 | },
14 | "keywords": [
15 | "moo-css"
16 | ],
17 | "author": "MichealWayne",
18 | "license": "ISC"
19 | }
20 |
--------------------------------------------------------------------------------
/moo-css-web/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist/",
4 | "sourceMap": true,
5 | "strict": true,
6 | "noImplicitAny": true,
7 | "module": "commonjs",
8 | "target": "es5",
9 | "allowJs": true,
10 | "baseUrl": ".",
11 | "paths": {
12 | "@/*": [
13 | "src/*"
14 | ]
15 | },
16 | "typeRoots": ["./src/types/"],
17 | "rootDir": "./src/"
18 | }
19 | }
--------------------------------------------------------------------------------
/vscode/moo-css-plugin.dev.vsix:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MichealWayne/moo-css-plugins/1cb1da935358103ff286036ee19c2eee508f7c80/vscode/moo-css-plugin.dev.vsix
--------------------------------------------------------------------------------