@zohodesk/react-cli 0.0.1-exp.168.1 → 0.0.1-exp.169.1

Sign up to get free protection for your applications and to get access to all the features.
package/.prettierrc CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "trailingComma": "none",
3
3
  "singleQuote": true,
4
+ "arrowParens": "avoid",
4
5
  "jsxSingleQuote": true
5
6
  }
package/README.md CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
  A CLI tool for build modern web application and libraries
4
4
 
5
+ # 0.0.1-exp.169.1
6
+
7
+ File support added for mp4 for docs dev and prod mode
8
+
9
+ # 0.0.1-beta.169
10
+
11
+ this version has same as `0.0.1-exp.168.1`, `0.0.1-exp.168.2`, `0.0.1-exp.168.3` and below and some minor changes
12
+
13
+ 1. `--efc_version=v3` flag added for change efc version via commmand line option
14
+ 2. `hoverActive` flag added for conversion from usual hover to @media(hover:hover) and @media(hover:none) queries for hover support in mobile.
15
+ 3. `combinerMq` flag added for combination of the media queries that might be appended or existing media queries that are duplicates to create one media query with all rules put together.
16
+
17
+ # 0.0.1-exp.168.3
18
+
19
+ Changes :
20
+
21
+ 1. code optimization ( made functions for the hoverActive cases making it more easier to access)
22
+ 2. handled `hover:ignore`, `active:ignore`, `hoverActive:ignore` cases for usual queries and media queries
23
+
24
+ # 0.0.1-exp.168.2
25
+
26
+ Changes :
27
+
28
+ 1. hoverActive case handled with postcss `hover:hover` media query and `hover:none` media query is added
29
+ 2. flag for hoverActive used to add/remove postcss changes
30
+
5
31
  # 0.0.1-exp.168.1
6
32
 
7
33
  Changes:-
@@ -0,0 +1,12 @@
1
+ # hover active css handling
2
+
3
+ In general we write css with some hover in it.
4
+ But In mobile there is no hover and some times this hover css may do something messy some thing like we may need to click a button we need to click it double time.
5
+
6
+ To handle this behaviour we write a postcss plugin
7
+
8
+ PostCSS plugin that transforms :hover selectors to :active on devices where a mouse isn't the primary input mechanism.
9
+
10
+ when we write hover css it will have some problem in mobile devices the reason was in mobile device ther is no mouse
11
+
12
+ for this we have to handle that as
@@ -27,9 +27,7 @@ let commonConfig = {
27
27
  '^.+\\.css$': _path.default.resolve(__dirname, '..', 'jest', 'preProcessors', 'cssPreprocessor.js'),
28
28
  '^(?!.*\\.(js|jsx|css|json)$)': _path.default.resolve(__dirname, '..', 'jest', 'preProcessors', 'otherFilesPreprocessor.js')
29
29
  },
30
- moduleNameMapper: { ...moduleNameMapper,
31
- '\\.(css|less)$': 'identity-obj-proxy'
32
- },
30
+ moduleNameMapper: moduleNameMapper,
33
31
  transformIgnorePatterns: ['/node_modules/(?!(@zohodesk)/)'],
34
32
  // transformIgnorePatterns: ['/node_modules.*?.js$'],
35
33
  moduleFileExtensions: ['js'],
@@ -25,7 +25,9 @@ let {
25
25
  server,
26
26
  outputFolder,
27
27
  rtlExclude,
28
+ combinerMq,
28
29
  hasRTL,
30
+ hoverActive,
29
31
  cssUniqueness,
30
32
  seperateCssModules,
31
33
  changeRuntimeChunkChar,
@@ -98,11 +100,11 @@ module.exports = {
98
100
  }, seperateCssModules ? {
99
101
  test: /\.css$/,
100
102
  exclude: /\.module\.css$/,
101
- use: (0, _loaderUtils.getCSSLoaders)(hasRTL, rtlExclude, '[local]', false, null)
103
+ use: (0, _loaderUtils.getCSSLoaders)(hasRTL, rtlExclude, combinerMq, hoverActive, '[local]', false, null)
102
104
  } : null, {
103
105
  test: seperateCssModules ? /\.module\.css$/ : /(\.module)?\.css$/,
104
- use: (0, _loaderUtils.getCSSLoaders)(hasRTL, rtlExclude, null, cssUniqueness, selectorReplace, cssHashSelectors, classNamePrefix)
105
- }, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), {
106
+ use: (0, _loaderUtils.getCSSLoaders)(hasRTL, combinerMq, rtlExclude, hoverActive, null, cssUniqueness, selectorReplace, cssHashSelectors, classNamePrefix)
107
+ }, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configVideoLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), {
106
108
  test: /\.tmpl$/,
107
109
  use: [{
108
110
  loader: 'html-loader',
@@ -22,7 +22,9 @@ let {
22
22
  disableES5Transpile,
23
23
  enableChunkHash,
24
24
  cssUniqueness,
25
+ combinerMq,
25
26
  hasRTL,
27
+ hoverActive,
26
28
  rtlExclude,
27
29
  cssHashSelectors,
28
30
  classNamePrefix
@@ -73,8 +75,8 @@ module.exports = isSSTest => ({
73
75
  exclude: /node_modules/
74
76
  }, {
75
77
  test: /(\.module)?\.css$/,
76
- use: (0, _loaderUtils.getCSSLoaders)(hasRTL, rtlExclude, false, cssUniqueness, null, cssHashSelectors, classNamePrefix)
77
- }, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), {
78
+ use: (0, _loaderUtils.getCSSLoaders)(hasRTL, combinerMq, rtlExclude, hoverActive, false, cssUniqueness, null, cssHashSelectors, classNamePrefix)
79
+ }, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), (0, _configsAssetsLoaders.configVideoLoader)(nameTemplate), {
78
80
  test: /\.html$/,
79
81
  use: {
80
82
  loader: 'html-loader',
@@ -19,6 +19,8 @@ let {
19
19
  cssUniqueness,
20
20
  hasRTL,
21
21
  rtlExclude,
22
+ hoverActive,
23
+ combinerMq,
22
24
  cssHashSelectors,
23
25
  enableChunkHash,
24
26
  classNamePrefix
@@ -68,8 +70,8 @@ module.exports = {
68
70
  exclude: /node_modules/
69
71
  }, {
70
72
  test: /(\.module)?\.css$/,
71
- use: (0, _loaderUtils.getCSSLoaders)(hasRTL, rtlExclude, false, cssUniqueness, null, cssHashSelectors, classNamePrefix)
72
- }, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), {
73
+ use: (0, _loaderUtils.getCSSLoaders)(hasRTL, rtlExclude, combinerMq, hoverActive, false, cssUniqueness, null, cssHashSelectors, classNamePrefix)
74
+ }, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), (0, _configsAssetsLoaders.configVideoLoader)(nameTemplate), {
73
75
  test: /\.html$/,
74
76
  use: {
75
77
  loader: 'html-loader',
@@ -12,6 +12,8 @@ var _loaderUtils = require("../loaderUtils");
12
12
 
13
13
  var _libAlias = require("./libAlias");
14
14
 
15
+ var _configsAssetsLoaders = require("../loaderUtils/configsAssetsLoaders");
16
+
15
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
18
 
17
19
  // import TerserPlugin from 'terser-webpack-plugin';
@@ -27,8 +29,10 @@ let {
27
29
  removeAttribute,
28
30
  enableSMap,
29
31
  server,
32
+ combinerMq,
30
33
  hasRTL,
31
34
  rtlExclude,
35
+ hoverActive,
32
36
  cssUniqueness,
33
37
  server: {
34
38
  mode
@@ -144,10 +148,10 @@ module.exports = {
144
148
  }, seperateCssModules ? {
145
149
  test: /\.css$/,
146
150
  exclude: /\.module\.css$/,
147
- use: (0, _loaderUtils.getCSSLoaders)(hasRTL, rtlExclude, '[local]', false, null)
151
+ use: (0, _loaderUtils.getCSSLoaders)(hasRTL, rtlExclude, hoverActive, combinerMq, '[local]', false, null)
148
152
  } : null, {
149
153
  test: seperateCssModules ? /\.module\.css$/ : /\.css$/,
150
- use: (0, _loaderUtils.getCSSLoaders)(hasRTL, rtlExclude, false, cssUniqueness, selectorReplace, cssHashSelectors, classNamePrefix)
154
+ use: (0, _loaderUtils.getCSSLoaders)(hasRTL, combinerMq, rtlExclude, hoverActive, false, cssUniqueness, selectorReplace, cssHashSelectors, classNamePrefix)
151
155
  }, {
152
156
  test: /\.jpe?g$|\.gif$|\.png$/,
153
157
  use: [{
@@ -158,7 +162,7 @@ module.exports = {
158
162
  fallback: _path.default.join(__dirname, '..', 'loaders', 'fileLoader.js')
159
163
  }
160
164
  }]
161
- }, {
165
+ }, (0, _configsAssetsLoaders.configVideoLoaderObj)(enableChunkHash ? './images/[name].[hash:20].[ext]' : './images/[name].[ext]'), {
162
166
  test: /\.woff2|\.woff$|\.ttf$|\.eot$/,
163
167
  use: [{
164
168
  loader: 'url-loader',
@@ -24,6 +24,8 @@ module.exports = {
24
24
 
25
25
  let jsonMap = _fs.default.readFileSync(`jsonFile_test_${count}.json`, 'UTF-8');
26
26
 
27
+ _fs.default.unlinkSync(`jsonFile_test_${count}.json`);
28
+
27
29
  return `module.exports =${jsonMap}`;
28
30
  }
29
31
  };
@@ -7,12 +7,20 @@ exports.configAudioLoader = configAudioLoader;
7
7
  exports.configFontLoader = configFontLoader;
8
8
  exports.configImageLoader = configImageLoader;
9
9
  exports.configSVGLoader = configSVGLoader;
10
+ exports.configVideoLoader = configVideoLoader;
11
+ exports.configVideoLoaderObj = configVideoLoaderObj;
10
12
  exports.createNameTemplate = createNameTemplate;
13
+
14
+ var _path = _interopRequireDefault(require("path"));
15
+
16
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
+
11
18
  // function getLoaderOptionQueryString(params) {
12
19
  const ImageExtRegex = /\.jpe?g$|\.gif$|\.png$/;
13
20
  const FontExtRegex = /\.woff2|\.woff$|\.ttf$|\.eot$/;
14
21
  const SVGExtRegex = /\.svg$/;
15
22
  const AudioExtRegex = /\.ogg$/;
23
+ const VidioExtRegex = /\.mp4$/;
16
24
 
17
25
  function createLoaderOptionQueryString(loaderName, nameTemplate, limit = 1000) {
18
26
  return `${loaderName}?limit=${limit}&name=${nameTemplate}`;
@@ -46,6 +54,27 @@ function configAudioLoader(nameTemplate) {
46
54
  };
47
55
  }
48
56
 
57
+ function configVideoLoader(nameTemplate) {
58
+ return {
59
+ test: VidioExtRegex,
60
+ use: createLoaderOptionQueryString('url-loader', `./images/${nameTemplate}`, 1)
61
+ };
62
+ }
63
+
64
+ function configVideoLoaderObj(nameTemplate) {
65
+ return {
66
+ test: VidioExtRegex,
67
+ use: {
68
+ loader: 'url-loader',
69
+ options: {
70
+ limit: 1000,
71
+ name: nameTemplate,
72
+ fallback: _path.default.join(__dirname, '..', 'loaders', 'fileLoader.js')
73
+ }
74
+ }
75
+ };
76
+ }
77
+
49
78
  function createNameTemplate(enableChunkHash) {
50
79
  const ext = `${enableChunkHash ? '.[hash:20]' : ''}.[ext]`;
51
80
  return `[name]${ext}`;
@@ -16,7 +16,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
16
16
  let options = (0, _utils.getOptions)();
17
17
  let isWin = process.platform === 'win32';
18
18
 
19
- let getCSSLoaders = (hasRTL, rtlExclude, classNameBlob, cssUniqueness, selectorReplace, cssHashSelectors, classNamePrefix) => {
19
+ let getCSSLoaders = (hasRTL, combinerMq, rtlExclude, hoverActive, classNameBlob, cssUniqueness, selectorReplace, cssHashSelectors, classNamePrefix) => {
20
20
  const {
21
21
  devCssFileBountry
22
22
  } = options.app;
@@ -28,7 +28,8 @@ let getCSSLoaders = (hasRTL, rtlExclude, classNameBlob, cssUniqueness, selectorR
28
28
  } = options.impactService;
29
29
  let rtlExcludeLocal = isWin ? rtlExclude.map(r => r.replace(/\//g, '\\')) : rtlExclude;
30
30
  let cssLoaderOptions = {
31
- importLoaders: hasRTL ? 1 : 0,
31
+ // importLoaders: hasRTL||hoverActive ? 1 : 0,
32
+ importLoaders: 1,
32
33
  modules: {},
33
34
  sourceMap: true
34
35
  };
@@ -50,7 +51,8 @@ let getCSSLoaders = (hasRTL, rtlExclude, classNameBlob, cssUniqueness, selectorR
50
51
  return `${prefix} ${selector}`; // Make selectors like [dir=rtl] > .selector
51
52
  }
52
53
  })]
53
- })].filter(Boolean);
54
+ }), // require('postcss-import')(),
55
+ combinerMq && require('postcss-combine-media-query')(), hoverActive && require('../postcss-plugins/hoverActivePlugin')()].filter(Boolean);
54
56
  return [cssSelectorZipPath && {
55
57
  loader: require.resolve('../loaders/selectorMappingLoader')
56
58
  }, {
@@ -3,84 +3,93 @@
3
3
  generaly we have manage our all I18n keys and values as language specific i18n files and then we download all i18n in initial page load.
4
4
 
5
5
  ### what is the problem with this?.
6
+
6
7
  the problem is i18n file keep get's grown it will affect the the inital page load and critial rendering path.
7
8
  So, We have decide to create a plugin for split i18n per chunk's of js vise.
8
9
 
9
10
  ### what is i18n split?
10
- it is like code split for i18n.
11
- we will collect i18n from js chunk and we will create separate i18n chunk per js chunk,
12
- with this we already load Js chunks are on demand and now we also download i18n also ondemand with this the initial and forthere actions.
13
- when js download's we will download i18n with it.
14
11
 
15
- ### How to we going to i18n split?
16
- we will read the js chunk and collect I18n keys form it,
17
- then we will create i18n chunk files with these used keys.
12
+ it is like code split for i18n.
13
+ we will collect i18n from js chunk and we will create separate i18n chunk per js chunk,
14
+ with this we already load Js chunks are on demand and now we also download i18n also ondemand with this the initial and forthere actions.
15
+ when js download's we will download i18n with it.
16
+
17
+ ### How to we going to i18n split?
18
+
19
+ we will read the js chunk and collect I18n keys form it,
20
+ then we will create i18n chunk files with these used keys.
18
21
 
19
22
  ### how do you collect i18n keys from js files?
20
- we will traverse the js file's AST (static analysis) and find i18 keys,
21
- we will concider all string which is in jsResource file as i18n keys.
22
- and you can tell dynamic i18n key by js comments,
23
- Like Below:-
24
- ```js
25
- fetch("tickets?view=view1").then(data => {
26
- // I18n support.ticketsEmpty
27
- // I18n support.viewNotFount
28
- // I18n support.permissionDenied
29
- let text = getI18nValue(data.i18nkey);
30
- })
31
- ```
23
+
24
+ we will traverse the js file's AST (static analysis) and find i18 keys,
25
+ we will concider all string which is in jsResource file as i18n keys.
26
+ and you can tell dynamic i18n key by js comments,
27
+ Like Below:-
28
+
29
+ ```js
30
+ fetch('tickets?view=view1').then(data => {
31
+ // I18n support.ticketsEmpty
32
+ // I18n support.viewNotFount
33
+ // I18n support.permissionDenied
34
+ let text = getI18nValue(data.i18nkey);
35
+ });
36
+ ```
32
37
 
33
38
  ### is there any posiblity for unwanted keys in some chunk?
34
- Yes, there is two posiblity
35
- 1. js comment , if you write js comment but it is not needed then it will be add into i18n chunk
36
- `To Resolve` we currently do not have perfect idea for this, But we can check this by chunk size limit.
37
- `idea's will be welcome`
38
- 2. like we said "we will concider all string which is in jsResource file as i18n keys",
39
- So if you use string not for i18n but it was in jsResource then it will be add into i18n chunk.
40
- `To Resolve` this problem we can use some kinda prefix or something.
39
+
40
+ Yes, there is two posiblity
41
+
42
+ 1. js comment , if you write js comment but it is not needed then it will be add into i18n chunk
43
+ `To Resolve` we currently do not have perfect idea for this, But we can check this by chunk size limit.
44
+ `idea's will be welcome`
45
+ 2. like we said "we will concider all string which is in jsResource file as i18n keys",
46
+ So if you use string not for i18n but it was in jsResource then it will be add into i18n chunk.
47
+ `To Resolve` this problem we can use some kinda prefix or something.
41
48
 
42
49
  ### how do we downlowd and give to app?
43
- we have over write defualt webpack requireEnsure (every dynamic chunk requests are done by that function) function.
44
- and we parlarly dowload i18n files. and we ask jsonFunction, to our plugin.
45
- So we send i18nkeys , when it was download,
46
- you must store all i18n keys, we give asycrnsly by that function download in that patticular.
50
+
51
+ we have over write defualt webpack requireEnsure (every dynamic chunk requests are done by that function) function.
52
+ and we parlarly dowload i18n files. and we ask jsonFunction, to our plugin.
53
+ So we send i18nkeys , when it was download,
54
+ you must store all i18n keys, we give asycrnsly by that function download in that patticular.
47
55
  so you must store and update (like append or assign) everytime that function call.
48
56
 
49
57
  ### how to use this feature?
50
- to use this feature use have give the below oprtions
51
- `package.json`
52
- ```json
53
- {
54
- /// ...some things
55
- "react-cli": {
56
- // ...some things
57
- "i18n": {
58
- "chunkSplitEnable": true,
59
- "jsResource": "./deskapp/properties/JSResources.properties",
60
- "localeVarName": "window.userInfo.langCode",
61
- "jsonpFunc": "window.loadI18nChunk",
62
- "templateLabel": "{{--user-locale}}",// this is for html template i18n file path locate template
63
- "propertiesFolder": "./deskapp/properties"
64
- },
65
- // ...some things
58
+
59
+ to use this feature use have give the below oprtions
60
+ `package.json`
61
+
62
+ ```json
63
+ {
64
+ /// ...some things
65
+ "react-cli": {
66
+ // ...some things
67
+ "i18n": {
68
+ "chunkSplitEnable": true,
69
+ "jsResource": "./deskapp/properties/JSResources.properties",
70
+ "localeVarName": "window.userInfo.langCode",
71
+ "jsonpFunc": "window.loadI18nChunk",
72
+ "templateLabel": "{{--user-locale}}", // this is for html template i18n file path locate template
73
+ "propertiesFolder": "./deskapp/properties"
66
74
  }
75
+ // ...some things
67
76
  }
68
- ```
69
-
77
+ }
78
+ ```
70
79
 
71
80
  <!-- not need below -->
72
- <!--
81
+ <!--we have added new feature for css to write logic to how hover related css work in hoverhover and a
73
82
 
74
83
  ### is there any problems with static analysis?
75
- Yes,
84
+ Yes,
76
85
 
77
86
  ### how do we use dynamic i18n key?
78
87
 
79
- and we will download i18n file with
88
+ and we will download i18n file with
80
89
 
81
90
  and when js chunk download's then we will download i18n as need.
82
91
  we all know in our app we loading i18n as one single big file for each locale(language).
83
- we are going to split i18n as per js chunk, and when js chunk download's then we will download i18n as need.
84
-
85
-
92
+ we are going to split i18n as per js chunk, and when js chunk download's then we will download i18n as need.
93
+
94
+
86
95
  -->
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ const fs = require('fs');
4
+
5
+ const postcss = require('postcss');
6
+
7
+ function expectRunPostCss(inputFile, outputfile, cb) {
8
+ const inputStr = fs.readFileSync(inputFile, 'utf-8');
9
+ postcss(plugins).process(inputStr, {
10
+ from,
11
+ to
12
+ }).then(result => {
13
+ expect(result.css).toBe(fs.readFileSync(outputfile, 'utf-8'));
14
+ cb();
15
+ });
16
+ }
17
+
18
+ describe('To Check Hover active postcss Plugin ', () => {
19
+ test('should handle normal rule hover', cb => {
20
+ expectRunPostCss('test1Input.css', 'test1Output.css', cb);
21
+ });
22
+ });
@@ -0,0 +1,39 @@
1
+ /*Hover_active:ignore*/
2
+ g,a:hover{
3
+ color : red
4
+ }
5
+ /*Hover:ignore*/
6
+ h:hover{
7
+ background : yellow
8
+ }
9
+
10
+ /* Hover_active:ignore */
11
+ g,d+e:hover{
12
+ color : black
13
+ }
14
+
15
+ g,d e:hover{
16
+ color : black
17
+ }
18
+
19
+ @media screen and (max-width:61.25em){
20
+ /* Hover_active:ignore */
21
+ a,b,a:hover, b:hover{
22
+ background-color : blue
23
+ }
24
+ a + b,a:hover + b:hover{
25
+ background-color : blue
26
+ }
27
+ a b:hover{
28
+ background-color : blue
29
+ }
30
+
31
+ .cc:hover {
32
+ color: red;
33
+ }
34
+
35
+ c:hover{
36
+ color : red
37
+ }
38
+
39
+ }
@@ -0,0 +1,39 @@
1
+ /*Hover_active:ignore*/
2
+ g,a:hover{
3
+ color : red
4
+ }
5
+ /*Hover:ignore*/
6
+ h:hover{
7
+ background : yellow
8
+ }
9
+
10
+ /* Hover_active:ignore */
11
+ g,d+e:hover{
12
+ color : black
13
+ }
14
+
15
+ g,d e:hover{
16
+ color : black
17
+ }
18
+
19
+ @media screen and (max-width:61.25em){
20
+ /* Hover_active:ignore */
21
+ a,b,a:hover, b:hover{
22
+ background-color : blue
23
+ }
24
+ a + b,a:hover + b:hover{
25
+ background-color : blue
26
+ }
27
+ a b:hover{
28
+ background-color : blue
29
+ }
30
+
31
+ .cc:hover {
32
+ color: red;
33
+ }
34
+
35
+ c:hover{
36
+ color : red
37
+ }
38
+
39
+ }
@@ -0,0 +1,365 @@
1
+ "use strict";
2
+
3
+ var _postcss = _interopRequireDefault(require("postcss"));
4
+
5
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6
+
7
+ /**
8
+ * we have give support for ignore(exclude) comments
9
+ * These are the comments' keyword
10
+ */
11
+ const hoverIgnoreQuery = 'Hover:ignore',
12
+ activeIgnoreQuery = 'Active:ignore',
13
+ hoverActiveIgnoreQuery = 'HoverActive:ignore';
14
+ const medHoverIgnoreQuery = 'MedHover:ignore',
15
+ medActiveIgnoreQuery = 'MedActive:ignore',
16
+ medHoverActiveIgnoreQuery = 'MedHoverActive:ignore';
17
+ const hoverMedQuerySuffix = '(min--moz-device-pixel-ratio:0) and (hover: hover), (hover: hover)';
18
+ const ruleIgnoreCommentRegex = /(Hover:ignore|Active:ignore|HoverActive:ignore)/g;
19
+ const mediaQueryIgnoreCommentRegex = /(MedHover:ignore|MedActive:ignore|MedHoverActive:ignore)/g;
20
+
21
+ function isComment(node) {
22
+ return node && node.type === 'comment' && node.text !== undefined;
23
+ }
24
+
25
+ function isHoverPresent(atrule) {
26
+ let hoverPresent = false;
27
+ atrule.walkRules(rule => {
28
+ if (rule.selector.includes('hover')) {
29
+ hoverPresent = true;
30
+ }
31
+ });
32
+ return hoverPresent;
33
+ }
34
+
35
+ module.exports = _postcss.default.plugin('postcss-mobile-hover', () => rootOriginal => {
36
+ const hoverRules = [];
37
+ let positionsObj = {};
38
+
39
+ function isRuleHasIgnoreComment(index, type) {
40
+ const prevNode = rootOriginal.nodes[index - 1];
41
+
42
+ if (isComment(prevNode)) {
43
+ return prevNode.text === type;
44
+ }
45
+
46
+ return false;
47
+ }
48
+
49
+ function isMediaQueryHasIgnoreComment(node, type) {
50
+ if (isComment(node)) {
51
+ return node.text === type;
52
+ }
53
+
54
+ return false;
55
+ }
56
+
57
+ function hasIgnoreComment({
58
+ index,
59
+ atrule,
60
+ type
61
+ }) {
62
+ if (type.match(mediaQueryIgnoreCommentRegex)) {
63
+ return isMediaQueryHasIgnoreComment(atrule.nodes[index - 1], type.slice(3));
64
+ }
65
+
66
+ if (type.match(ruleIgnoreCommentRegex)) {
67
+ return isRuleHasIgnoreComment(index, type);
68
+ }
69
+
70
+ return false;
71
+ }
72
+
73
+ function getPositionsOfHoverAndActiveMedQueries(parent) {
74
+ const allNodes = rootOriginal.nodes;
75
+ const hoverMediaQuery = `${parent.params} and all and ${hoverMedQuerySuffix}`;
76
+ const hoverNoneMediaQuery = `${parent.params} and (hover: none)`;
77
+ const positions = {
78
+ hovMed: allNodes[positionsObj[hoverMediaQuery]],
79
+ actMed: allNodes[positionsObj[hoverNoneMediaQuery]]
80
+ };
81
+ return positions;
82
+ }
83
+
84
+ function handleMedHoverAndHoverActiveIgnore(atrule, index) {
85
+ return !hasIgnoreComment({
86
+ atrule,
87
+ index,
88
+ type: medHoverIgnoreQuery
89
+ }) && !hasIgnoreComment({
90
+ atrule,
91
+ index,
92
+ type: medHoverActiveIgnoreQuery
93
+ });
94
+ }
95
+
96
+ function handleMedActiveAndHoverActiveIgnore(atrule, index) {
97
+ return !hasIgnoreComment({
98
+ atrule,
99
+ index,
100
+ type: medActiveIgnoreQuery
101
+ }) && !hasIgnoreComment({
102
+ atrule,
103
+ index,
104
+ type: medHoverActiveIgnoreQuery
105
+ });
106
+ }
107
+
108
+ function handleHoverAndHoverActiveIgnore(index) {
109
+ return !hasIgnoreComment({
110
+ index,
111
+ type: hoverIgnoreQuery
112
+ }) && !hasIgnoreComment({
113
+ index,
114
+ type: hoverActiveIgnoreQuery
115
+ });
116
+ }
117
+
118
+ function handleActiveAndHoverActiveIgnore(index) {
119
+ return !hasIgnoreComment({
120
+ index,
121
+ type: activeIgnoreQuery
122
+ }) && !hasIgnoreComment({
123
+ index,
124
+ type: hoverActiveIgnoreQuery
125
+ });
126
+ }
127
+
128
+ function handleAllIgnoreCases(index) {
129
+ return !hasIgnoreComment({
130
+ index,
131
+ type: activeIgnoreQuery
132
+ }) && !hasIgnoreComment({
133
+ index,
134
+ type: hoverIgnoreQuery
135
+ }) && !hasIgnoreComment({
136
+ index,
137
+ type: hoverActiveIgnoreQuery
138
+ });
139
+ }
140
+
141
+ function mediaCommaQuery(rule, index) {
142
+ if (rule.parent.params !== undefined && !rule.parent.params.includes('hover')) {
143
+ //console.log(hovMed, actMed);
144
+ let newSelector = '';
145
+ let {
146
+ hovMed,
147
+ actMed
148
+ } = getPositionsOfHoverAndActiveMedQueries(rule.parent);
149
+ let hovQueries = [];
150
+ let actQueries = [];
151
+ rule.selector.split(/\s*,\s*/).forEach(_subrule => {
152
+ let subrule = _subrule.trim();
153
+
154
+ let clone = rule.clone();
155
+
156
+ if (subrule.includes('hover')) {
157
+ clone.selector = subrule;
158
+
159
+ if (handleMedHoverAndHoverActiveIgnore(rule.parent, index)) {
160
+ hovQueries.push(subrule);
161
+ }
162
+
163
+ if (handleMedActiveAndHoverActiveIgnore(rule.parent, index)) {
164
+ actQueries.push(subrule);
165
+ }
166
+ } else {
167
+ newSelector += `${subrule}, `;
168
+ }
169
+ });
170
+
171
+ if (hovQueries.length > 0) {
172
+ let clone = rule.clone();
173
+ clone.selector = hovQueries.join(',');
174
+ hovMed.append(clone);
175
+ }
176
+
177
+ if (actQueries.length > 0) {
178
+ let clone = rule.clone();
179
+ clone.selector = actQueries.join(',');
180
+ actMed.append(clone.clone({
181
+ selector: clone.selector.replace(/:hover/gi, ':active')
182
+ }));
183
+ }
184
+
185
+ if (handleMedHoverAndHoverActiveIgnore(rule.parent, index)) {
186
+ rule.selector = newSelector.substring(0, newSelector.length - 2);
187
+ }
188
+
189
+ if (rule.selector === '') {
190
+ rule.remove();
191
+ }
192
+ }
193
+ }
194
+
195
+ function mediaQuery(rule, index) {
196
+ if (rule.parent.params !== undefined && !rule.parent.params.includes('hover')) {
197
+ let {
198
+ hovMed,
199
+ actMed
200
+ } = getPositionsOfHoverAndActiveMedQueries(rule.parent);
201
+
202
+ if (rule.selector.includes('hover') && hovMed !== undefined && rule.parent.type === 'atrule') {
203
+ if (handleMedHoverAndHoverActiveIgnore(rule.parent, index)) {
204
+ hovMed.append(rule);
205
+ }
206
+
207
+ if (handleMedActiveAndHoverActiveIgnore(rule.parent, index)) {
208
+ actMed.append(rule.clone({
209
+ selector: rule.selector.replace(/:hover/gi, ':active')
210
+ }));
211
+ }
212
+ }
213
+ }
214
+ }
215
+
216
+ function commaQuery(rule, index) {
217
+ //console.log("comma" , rule.selector.split('\n'));
218
+ let newSelector = '';
219
+ let hovQueries = [];
220
+ rule.selector.split(/\s*,\s*/).forEach(_subrule => {
221
+ let subrule = _subrule.trim();
222
+
223
+ if (subrule.includes('hover')) {
224
+ // hoverRules.push({ rule: clone, index });
225
+ hovQueries.push(subrule);
226
+ } else {
227
+ newSelector += `${subrule}, `;
228
+ }
229
+ });
230
+
231
+ if (hovQueries.length > 0) {
232
+ let clone = rule.clone();
233
+ clone.selector = hovQueries.join(',');
234
+ hoverRules.push({
235
+ rule: clone,
236
+ index
237
+ });
238
+ }
239
+
240
+ if (handleHoverAndHoverActiveIgnore(index)) {
241
+ rule.selector = newSelector.substring(0, newSelector.length - 2).trim();
242
+ }
243
+
244
+ if (rule.selector === '') {
245
+ rule.remove();
246
+ }
247
+ } // Start by identifying all :hover rules
248
+
249
+
250
+ rootOriginal.walkAtRules(atrule => {
251
+ const hoverQuery = `${atrule.params} and all and ${hoverMedQuerySuffix}`;
252
+ const activeQuery = `${atrule.params} and (hover: none)`;
253
+
254
+ if (isHoverPresent(atrule)) {
255
+ if (!positionsObj[hoverQuery] && !positionsObj[activeQuery]) {
256
+ rootOriginal.append({
257
+ name: 'media',
258
+ params: hoverQuery
259
+ });
260
+ positionsObj[hoverQuery] = rootOriginal.nodes.length - 1;
261
+ rootOriginal.append({
262
+ name: 'media',
263
+ params: activeQuery
264
+ });
265
+ positionsObj[activeQuery] = rootOriginal.nodes.length - 1;
266
+ }
267
+ }
268
+ });
269
+ rootOriginal.walkRules(/:hover/i, (rule, index) => {
270
+ // media hover query with ',' ' ' '+'
271
+ // console.log("media query" , rule.selector)
272
+ if (rule.parent.type === 'atrule' && rule.selector.includes(',')) {
273
+ //console.log("media comma", rule.selector)
274
+ mediaCommaQuery(rule, index);
275
+ } else {
276
+ // plus, space and other media queries
277
+ //console.log("media", rule.selector)
278
+ mediaQuery(rule, index);
279
+ } // usual hover query
280
+
281
+
282
+ if (!rule.selector.match(/,+| +|\++/g) && rule.parent !== undefined && rule.parent.name === undefined) {
283
+ hoverRules.push({
284
+ rule,
285
+ index
286
+ });
287
+ } //usual hover query with ',' ' ' '+'
288
+
289
+
290
+ if (rule.selector.match(/,+| +|\++/g) && rule.parent.name === undefined) {
291
+ if (rule.selector.includes(',')) {
292
+ commaQuery(rule, index);
293
+ } else if (rule.selector.match(/ +|\++/g)) {
294
+ //console.log("plus or space" , rule.selector);
295
+ if (rule.selector.includes('hover')) {
296
+ hoverRules.push({
297
+ rule,
298
+ index
299
+ }); //rule.remove();
300
+ }
301
+ }
302
+ }
303
+ }); // If there are any :hover rules in the input, then create media queries
304
+ // to automatically translate it into :active on touch-based devices
305
+
306
+ if (hoverRules.length > 0) {
307
+ // Create a media query targetting devices that actually support
308
+ // hover
309
+ const hoverQuery = rootOriginal.append({
310
+ name: 'media',
311
+ params: `all and ${hoverMedQuerySuffix}`
312
+ }).last; // Create a media query targetting devices that don't support hover
313
+ // (ie. devices where we should fall back to :active instead)
314
+
315
+ const activeQuery = rootOriginal.append({
316
+ name: 'media',
317
+ params: '(hover: none)'
318
+ }).last; // Loop through the hover rules and apply them to each of the media
319
+ // queries
320
+ // eslint-disable-next-line no-labels
321
+
322
+ outerLoop: for (const hoverRule of hoverRules) {
323
+ // determine if the rule has been nested inside another media
324
+ // query; in that case bail out as we have no way of reliably
325
+ // nesting these queries
326
+ let parentRule = hoverRule.rule.parent;
327
+
328
+ while (parentRule) {
329
+ if (parentRule.type === 'atrule' && parentRule.name === 'media') {
330
+ // eslint-disable-next-line no-labels
331
+ continue outerLoop;
332
+ }
333
+
334
+ parentRule = parentRule.parent;
335
+ } // Push a clone of the :hover rule 'as is' to queries where we
336
+ // expect the user's device to support hover
337
+ // ieQuery.append(hoverRule.clone());
338
+
339
+
340
+ if (handleHoverAndHoverActiveIgnore(hoverRule.index)) {
341
+ hoverQuery.append(hoverRule.rule.clone());
342
+ } // Push a clone of the :hover rule, where we transform the
343
+ // selector to :active to the query targetting devices that
344
+ // don't support hover
345
+
346
+
347
+ if (handleActiveAndHoverActiveIgnore(hoverRule.index)) {
348
+ activeQuery.append(hoverRule.rule.clone({
349
+ selector: hoverRule.rule.selector.replace(/:hover/gi, ':active')
350
+ }));
351
+ } // remove legacy rule from output
352
+
353
+
354
+ if (handleAllIgnoreCases(hoverRule.index)) {
355
+ hoverRule.rule.remove();
356
+ }
357
+ }
358
+ }
359
+
360
+ rootOriginal.walkAtRules(atrule => {
361
+ if (atrule !== undefined && atrule.nodes !== undefined && atrule.nodes.length === 0 || atrule.nodes === undefined) {
362
+ atrule.remove();
363
+ }
364
+ });
365
+ });
@@ -71,7 +71,10 @@ var _default = {
71
71
  },
72
72
  createSDkFile: false,
73
73
  nameScope: 'ZOHODESK',
74
- version: 'default',
74
+ version: {
75
+ value: 'stable',
76
+ cli: 'efc_version'
77
+ },
75
78
  outputFile: {
76
79
  value: 'efc-sdk-[version].js',
77
80
  cli: 'efc_output_file'
@@ -218,6 +221,8 @@ var _default = {
218
221
  value: 'zd',
219
222
  cli: 'class_prefix'
220
223
  },
224
+ combinerMq: false,
225
+ hoverActive: false,
221
226
  selectorReplace: null,
222
227
  devConsoleExculde: {
223
228
  value: false,
@@ -271,6 +276,8 @@ var _default = {
271
276
  cli: 'css_unique'
272
277
  },
273
278
  enableChunkHash: false,
279
+ combinerMq: false,
280
+ hoverActive: false,
274
281
  folder: 'src',
275
282
  disableES5Transpile: false,
276
283
  hasRTL: false,
@@ -13,18 +13,16 @@ var _fs = require("fs");
13
13
 
14
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
15
 
16
- let appPath = process.cwd();
16
+ const appPath = process.cwd();
17
17
  const isNodeModuleUnderAppFolder = __dirname.indexOf(appPath) !== -1;
18
- let isWindows = (0, _os.platform)().toLowerCase() === 'win32';
18
+ const isWindows = (0, _os.platform)().toLowerCase() === 'win32';
19
19
 
20
- const _getCliPath = !isNodeModuleUnderAppFolder ? libName => {
21
- const cliPath = _path.default.join(__dirname, '..', '..', 'node_modules', '.bin', libName);
22
-
23
- return (0, _fs.existsSync)(cliPath) ? cliPath : libName;
24
- } : libName => libName;
20
+ const _getCliPath = !isNodeModuleUnderAppFolder ? libName => _path.default.join(__dirname, '..', '..', 'node_modules', '.bin', libName) : libName => libName;
25
21
 
26
22
  const suffixExt = isWindows ? '.cmd' : '';
27
23
 
28
24
  function getCliPath(libName) {
29
- return _getCliPath(libName + suffixExt);
25
+ const cliPath = _getCliPath(libName + suffixExt);
26
+
27
+ return (0, _fs.existsSync)(cliPath) ? cliPath : libName;
30
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zohodesk/react-cli",
3
- "version": "0.0.1-exp.168.1",
3
+ "version": "0.0.1-exp.169.1",
4
4
  "description": "A CLI tool for build modern web application and libraries",
5
5
  "scripts": {
6
6
  "init": "node ./lib/utils/init.js",
@@ -91,8 +91,11 @@
91
91
  "nodemon": "2.0.4",
92
92
  "optimize-js": "1.0.3",
93
93
  "postcss": "7.0.32",
94
+ "postcss-combine-media-query": "1.0.1",
94
95
  "postcss-hash-classname": "0.4.0",
96
+ "postcss-import": "14.1.0",
95
97
  "postcss-loader": "3.0.0",
98
+ "postcss-mobile-hover": "1.0.2",
96
99
  "postcss-selector-replace": "1.0.2",
97
100
  "prop-types": "15.7.2",
98
101
  "react": "16.13.1",