@zohodesk/react-cli 0.0.1-beta.168 → 0.0.1-beta.170
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierrc +6 -0
- package/README.md +46 -1
- package/bin/cli.js +10 -20
- package/docs/HoverActive.md +12 -0
- package/lib/configs/webpack.dev.config.js +5 -5
- package/lib/configs/webpack.docs.config.js +4 -4
- package/lib/configs/webpack.impact.config.js +4 -4
- package/lib/configs/webpack.prod.config.js +7 -5
- package/lib/loaderUtils/configsAssetsLoaders.js +29 -0
- package/lib/loaderUtils/getCSSLoaders.js +37 -5
- package/lib/plugins/I18nSplitPlugin/I18nSplit.md +63 -54
- package/lib/postcss-plugins/{ExcludeRTLPlugin.js → ExcludePlugin.js} +1 -1
- package/lib/postcss-plugins/__test__/hoverActivePlugin.spec.js +22 -0
- package/lib/postcss-plugins/__test__/test1Input.css +39 -0
- package/lib/postcss-plugins/__test__/test1Output.css +39 -0
- package/lib/postcss-plugins/hoverActivePlugin.js +365 -0
- package/lib/postcss-plugins/variableModifier.js +243 -0
- package/lib/schemas/index.js +28 -6
- package/lib/servers/getCliPath.js +7 -3
- package/package.json +4 -1
package/.prettierrc
ADDED
package/README.md
CHANGED
@@ -2,6 +2,51 @@
|
|
2
2
|
|
3
3
|
A CLI tool for build modern web application and libraries
|
4
4
|
|
5
|
+
# 0.0.1-beta.170
|
6
|
+
|
7
|
+
this version has same as `0.0.1-exp.169.1`, `0.0.1-exp.169.2`
|
8
|
+
|
9
|
+
# 0.0.1-exp.169.2
|
10
|
+
|
11
|
+
1. flags are converted to one variable 'plugin' and used in getCssLoaders.js.
|
12
|
+
2. files for exclusion can be put in seperate arrays in 'exclude' present in package.json.
|
13
|
+
3. `combinerMq` has been converted to `combinerMediaQuery` for clarity.
|
14
|
+
|
15
|
+
# 0.0.1-exp.169.1
|
16
|
+
|
17
|
+
File support added for mp4 for docs dev and prod mode
|
18
|
+
|
19
|
+
# 0.0.1-beta.169
|
20
|
+
|
21
|
+
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
|
22
|
+
|
23
|
+
1. `--efc_version=v3` flag added for change efc version via commmand line option
|
24
|
+
2. `hoverActive` flag added for conversion from usual hover to @media(hover:hover) and @media(hover:none) queries for hover support in mobile.
|
25
|
+
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.
|
26
|
+
|
27
|
+
# 0.0.1-exp.168.3
|
28
|
+
|
29
|
+
Changes :
|
30
|
+
|
31
|
+
1. code optimization ( made functions for the hoverActive cases making it more easier to access)
|
32
|
+
2. handled `hover:ignore`, `active:ignore`, `hoverActive:ignore` cases for usual queries and media queries
|
33
|
+
|
34
|
+
# 0.0.1-exp.168.2
|
35
|
+
|
36
|
+
Changes :
|
37
|
+
|
38
|
+
1. hoverActive case handled with postcss `hover:hover` media query and `hover:none` media query is added
|
39
|
+
2. flag for hoverActive used to add/remove postcss changes
|
40
|
+
|
41
|
+
# 0.0.1-exp.168.1
|
42
|
+
|
43
|
+
Changes:-
|
44
|
+
|
45
|
+
1. `cliRootPath` option removed `react-cli.app.cliRootPath` in `package.json`
|
46
|
+
Due to the reason we updated our logic to find package's executable path.
|
47
|
+
2. `--efc_output_file=efc-sdk-[version].js` option added to modify efc output file by terminal
|
48
|
+
3. added logic to print error message during command run, Previously when executable not found error messages not printed
|
49
|
+
|
5
50
|
# 0.0.1-beta.168
|
6
51
|
|
7
52
|
Changes:-
|
@@ -157,7 +202,7 @@ this version has same as `# 0.0.1-exp.164.1`, `# 0.0.1-exp.164.2` and below and
|
|
157
202
|
|
158
203
|
# 0.0.1-exp.159
|
159
204
|
|
160
|
-
-
|
205
|
+
- issue fix:-
|
161
206
|
- when rtl ltr css split enable manifest json css filename keys comes with hash .
|
162
207
|
|
163
208
|
# 0.0.1-beta.158
|
package/bin/cli.js
CHANGED
@@ -1,19 +1,26 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
3
|
const path = require('path');
|
4
|
-
const os = require('os');
|
5
4
|
const { existsSync } = require('fs');
|
6
|
-
const { spawnSync, spawn } = require('child_process');
|
5
|
+
const { spawnSync: _spawnSync, spawn } = require('child_process');
|
7
6
|
const { getOptions } = require('../lib/utils/index.js');
|
8
7
|
|
9
8
|
const { log } = require('../lib/utils');
|
9
|
+
const { getCliPath } = require('../lib/servers/getCliPath.js');
|
10
10
|
//initPreCommitHook();
|
11
11
|
|
12
12
|
const options = getOptions();
|
13
13
|
|
14
|
+
function spawnSync(...args) {
|
15
|
+
const result = _spawnSync(...args);
|
16
|
+
if (result.error) {
|
17
|
+
console.error(result.error);
|
18
|
+
}
|
19
|
+
return result;
|
20
|
+
}
|
21
|
+
|
14
22
|
const { esLint: esLintOptions } = options || {};
|
15
23
|
const { preprocess } = options;
|
16
|
-
let { cliRootPath } = options;
|
17
24
|
const {
|
18
25
|
ignoreFilePaths: esLintIgnorePaths,
|
19
26
|
fix: esLintFix,
|
@@ -21,27 +28,10 @@ const {
|
|
21
28
|
reportPath: reportPath
|
22
29
|
} = esLintOptions || {};
|
23
30
|
|
24
|
-
const isWindows = os.platform().toLowerCase() === 'win32';
|
25
|
-
|
26
31
|
const [, , option] = process.argv;
|
27
32
|
const args = process.argv.slice(3);
|
28
33
|
const appPath = process.cwd();
|
29
34
|
|
30
|
-
const isNodeModuleUnderAppFolder = __dirname.indexOf(appPath) !== -1;
|
31
|
-
|
32
|
-
if (!cliRootPath) {
|
33
|
-
cliRootPath = path.join(__dirname, '..');
|
34
|
-
}
|
35
|
-
|
36
|
-
const _getCliPath = !isNodeModuleUnderAppFolder
|
37
|
-
? libName => path.join(cliRootPath, 'node_modules', '.bin', libName)
|
38
|
-
: libName => libName;
|
39
|
-
const suffixExt = isWindows ? '.cmd' : '';
|
40
|
-
|
41
|
-
function getCliPath(libName) {
|
42
|
-
return _getCliPath(libName) + suffixExt;
|
43
|
-
}
|
44
|
-
|
45
35
|
const webpack = getCliPath('webpack');
|
46
36
|
|
47
37
|
const nodemon = getCliPath('nodemon');
|
@@ -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
|
@@ -24,8 +24,8 @@ let {
|
|
24
24
|
context,
|
25
25
|
server,
|
26
26
|
outputFolder,
|
27
|
-
|
28
|
-
|
27
|
+
plugins,
|
28
|
+
exclude,
|
29
29
|
cssUniqueness,
|
30
30
|
seperateCssModules,
|
31
31
|
changeRuntimeChunkChar,
|
@@ -98,11 +98,11 @@ module.exports = {
|
|
98
98
|
}, seperateCssModules ? {
|
99
99
|
test: /\.css$/,
|
100
100
|
exclude: /\.module\.css$/,
|
101
|
-
use: (0, _loaderUtils.getCSSLoaders)(
|
101
|
+
use: (0, _loaderUtils.getCSSLoaders)(plugins, exclude, '[local]', false, null)
|
102
102
|
} : null, {
|
103
103
|
test: seperateCssModules ? /\.module\.css$/ : /(\.module)?\.css$/,
|
104
|
-
use: (0, _loaderUtils.getCSSLoaders)(
|
105
|
-
}, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), {
|
104
|
+
use: (0, _loaderUtils.getCSSLoaders)(plugins, exclude, null, cssUniqueness, selectorReplace, cssHashSelectors, classNamePrefix)
|
105
|
+
}, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configVideoLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), {
|
106
106
|
test: /\.tmpl$/,
|
107
107
|
use: [{
|
108
108
|
loader: 'html-loader',
|
@@ -22,8 +22,8 @@ let {
|
|
22
22
|
disableES5Transpile,
|
23
23
|
enableChunkHash,
|
24
24
|
cssUniqueness,
|
25
|
-
|
26
|
-
|
25
|
+
plugins,
|
26
|
+
exclude,
|
27
27
|
cssHashSelectors,
|
28
28
|
classNamePrefix
|
29
29
|
},
|
@@ -73,8 +73,8 @@ module.exports = isSSTest => ({
|
|
73
73
|
exclude: /node_modules/
|
74
74
|
}, {
|
75
75
|
test: /(\.module)?\.css$/,
|
76
|
-
use: (0, _loaderUtils.getCSSLoaders)(
|
77
|
-
}, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), {
|
76
|
+
use: (0, _loaderUtils.getCSSLoaders)(plugins, exclude, false, cssUniqueness, null, cssHashSelectors, classNamePrefix)
|
77
|
+
}, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), (0, _configsAssetsLoaders.configVideoLoader)(nameTemplate), {
|
78
78
|
test: /\.html$/,
|
79
79
|
use: {
|
80
80
|
loader: 'html-loader',
|
@@ -17,8 +17,8 @@ let {
|
|
17
17
|
docs: {
|
18
18
|
componentFolder,
|
19
19
|
cssUniqueness,
|
20
|
-
|
21
|
-
|
20
|
+
plugins,
|
21
|
+
exclude,
|
22
22
|
cssHashSelectors,
|
23
23
|
enableChunkHash,
|
24
24
|
classNamePrefix
|
@@ -68,8 +68,8 @@ module.exports = {
|
|
68
68
|
exclude: /node_modules/
|
69
69
|
}, {
|
70
70
|
test: /(\.module)?\.css$/,
|
71
|
-
use: (0, _loaderUtils.getCSSLoaders)(
|
72
|
-
}, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), {
|
71
|
+
use: (0, _loaderUtils.getCSSLoaders)(plugins, exclude, false, cssUniqueness, null, cssHashSelectors, classNamePrefix)
|
72
|
+
}, (0, _configsAssetsLoaders.configImageLoader)(nameTemplate), (0, _configsAssetsLoaders.configFontLoader)(nameTemplate), (0, _configsAssetsLoaders.configSVGLoader)(nameTemplate), (0, _configsAssetsLoaders.configAudioLoader)(nameTemplate), (0, _configsAssetsLoaders.configVideoLoader)(nameTemplate), {
|
73
73
|
test: /\.html$/,
|
74
74
|
use: {
|
75
75
|
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,8 @@ let {
|
|
27
29
|
removeAttribute,
|
28
30
|
enableSMap,
|
29
31
|
server,
|
30
|
-
|
31
|
-
|
32
|
+
plugins,
|
33
|
+
exclude,
|
32
34
|
cssUniqueness,
|
33
35
|
server: {
|
34
36
|
mode
|
@@ -144,10 +146,10 @@ module.exports = {
|
|
144
146
|
}, seperateCssModules ? {
|
145
147
|
test: /\.css$/,
|
146
148
|
exclude: /\.module\.css$/,
|
147
|
-
use: (0, _loaderUtils.getCSSLoaders)(
|
149
|
+
use: (0, _loaderUtils.getCSSLoaders)(plugins, exclude, '[local]', false, null)
|
148
150
|
} : null, {
|
149
151
|
test: seperateCssModules ? /\.module\.css$/ : /\.css$/,
|
150
|
-
use: (0, _loaderUtils.getCSSLoaders)(
|
152
|
+
use: (0, _loaderUtils.getCSSLoaders)(plugins, exclude, false, cssUniqueness, selectorReplace, cssHashSelectors, classNamePrefix)
|
151
153
|
}, {
|
152
154
|
test: /\.jpe?g$|\.gif$|\.png$/,
|
153
155
|
use: [{
|
@@ -158,7 +160,7 @@ module.exports = {
|
|
158
160
|
fallback: _path.default.join(__dirname, '..', 'loaders', 'fileLoader.js')
|
159
161
|
}
|
160
162
|
}]
|
161
|
-
}, {
|
163
|
+
}, (0, _configsAssetsLoaders.configVideoLoaderObj)(enableChunkHash ? './images/[name].[hash:20].[ext]' : './images/[name].[ext]'), {
|
162
164
|
test: /\.woff2|\.woff$|\.ttf$|\.eot$/,
|
163
165
|
use: [{
|
164
166
|
loader: 'url-loader',
|
@@ -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,26 @@ 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
|
-
|
19
|
+
function windowsModification(array) {
|
20
|
+
return isWin ? array.map(r => r.replace(/\//g, '\\')) : array;
|
21
|
+
}
|
22
|
+
|
23
|
+
function excludeEmptyCheckPlugin({
|
24
|
+
enable,
|
25
|
+
ignore,
|
26
|
+
plugins
|
27
|
+
}) {
|
28
|
+
return enable ? ignore.length == 0 ? plugins : [require('../postcss-plugins/ExcludePlugin')({
|
29
|
+
ignore,
|
30
|
+
plugins
|
31
|
+
})] : [];
|
32
|
+
}
|
33
|
+
|
34
|
+
let getCSSLoaders = (plugins, exclude, classNameBlob, cssUniqueness, selectorReplace, cssHashSelectors, classNamePrefix) => {
|
35
|
+
// console.log('plugins:')
|
36
|
+
// console.log(plugins)
|
37
|
+
// console.log('exclude:')
|
38
|
+
// console.log(exclude)
|
20
39
|
const {
|
21
40
|
devCssFileBountry
|
22
41
|
} = options.app;
|
@@ -26,9 +45,12 @@ let getCSSLoaders = (hasRTL, rtlExclude, classNameBlob, cssUniqueness, selectorR
|
|
26
45
|
const {
|
27
46
|
cssSelectorZipPath
|
28
47
|
} = options.impactService;
|
29
|
-
let rtlExcludeLocal =
|
48
|
+
let rtlExcludeLocal = windowsModification(exclude.rtl);
|
49
|
+
let hoverActiveExcludeLocal = windowsModification(exclude.hoverActive);
|
50
|
+
let combinerMediaQueryExcludeLocal = windowsModification(exclude.combinerMediaQuery);
|
30
51
|
let cssLoaderOptions = {
|
31
|
-
importLoaders: hasRTL ? 1 : 0,
|
52
|
+
// importLoaders: hasRTL||hoverActive ? 1 : 0,
|
53
|
+
importLoaders: 1,
|
32
54
|
modules: {},
|
33
55
|
sourceMap: true
|
34
56
|
};
|
@@ -39,7 +61,8 @@ let getCSSLoaders = (hasRTL, rtlExclude, classNameBlob, cssUniqueness, selectorR
|
|
39
61
|
cssLoaderOptions.modules.getLocalIdent = (0, _cssClassNameGenerate.default)(cssUniqueness, cssHashSelectors, classNamePrefix);
|
40
62
|
}
|
41
63
|
|
42
|
-
const postcssPlugins = [valueReplacer && require('../postcss-plugins/ValueReplacer')(valueReplacer), selectorReplace && require('postcss-selector-replace')(selectorReplace),
|
64
|
+
const postcssPlugins = [valueReplacer && require('../postcss-plugins/ValueReplacer')(valueReplacer), selectorReplace && require('postcss-selector-replace')(selectorReplace), ...excludeEmptyCheckPlugin({
|
65
|
+
enable: plugins.hasRTL,
|
43
66
|
ignore: rtlExcludeLocal,
|
44
67
|
plugins: [require('@zohodesk/postcss-rtl')({
|
45
68
|
addPrefixToSelector: function addPrefixToSelector(selector, prefix) {
|
@@ -50,7 +73,16 @@ let getCSSLoaders = (hasRTL, rtlExclude, classNameBlob, cssUniqueness, selectorR
|
|
50
73
|
return `${prefix} ${selector}`; // Make selectors like [dir=rtl] > .selector
|
51
74
|
}
|
52
75
|
})]
|
53
|
-
})
|
76
|
+
}), ...excludeEmptyCheckPlugin({
|
77
|
+
enable: plugins.combinerMediaQuery,
|
78
|
+
ignore: combinerMediaQueryExcludeLocal,
|
79
|
+
plugins: [require('postcss-combine-media-query')]
|
80
|
+
}), ...excludeEmptyCheckPlugin({
|
81
|
+
enable: plugins.hoverActive,
|
82
|
+
ignore: hoverActiveExcludeLocal,
|
83
|
+
plugins: [require('../postcss-plugins/hoverActivePlugin')]
|
84
|
+
}) // require('../postcss-plugins/variableModifier')()
|
85
|
+
].filter(Boolean);
|
54
86
|
return [cssSelectorZipPath && {
|
55
87
|
loader: require.resolve('../loaders/selectorMappingLoader')
|
56
88
|
}, {
|
@@ -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
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
},
|
65
|
-
|
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
|
-->
|
@@ -4,7 +4,7 @@ var _postcss = _interopRequireDefault(require("postcss"));
|
|
4
4
|
|
5
5
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
6
6
|
|
7
|
-
module.exports = _postcss.default.plugin('postcss-exclude-
|
7
|
+
module.exports = _postcss.default.plugin('postcss-exclude-files', opts => {
|
8
8
|
const {
|
9
9
|
plugins
|
10
10
|
} = opts;
|
@@ -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
|
+
});
|
@@ -0,0 +1,243 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
const postcss = require('postcss');
|
4
|
+
|
5
|
+
const path = require('path');
|
6
|
+
|
7
|
+
const fs = require('fs');
|
8
|
+
|
9
|
+
function populateArray(start, end) {
|
10
|
+
let temp = [];
|
11
|
+
|
12
|
+
for (var i = start; i < end; i++) {
|
13
|
+
temp.push(i);
|
14
|
+
}
|
15
|
+
|
16
|
+
return temp;
|
17
|
+
}
|
18
|
+
|
19
|
+
let allwdVars = {
|
20
|
+
'font-size': ['px', 'em']
|
21
|
+
};
|
22
|
+
let numberObject = {
|
23
|
+
'font-size': {
|
24
|
+
allowed: ['px', 'em'],
|
25
|
+
replacements: {
|
26
|
+
px: 'var(--zd_font_size$$)',
|
27
|
+
em: 'var(--zd_font_size$$em)'
|
28
|
+
},
|
29
|
+
//[5,10,15,20,25],
|
30
|
+
available: populateArray(0, 251),
|
31
|
+
replacementValues: {
|
32
|
+
px: [],
|
33
|
+
em: []
|
34
|
+
}
|
35
|
+
},
|
36
|
+
'margin': {
|
37
|
+
allowed: ['px'],
|
38
|
+
replacements: {
|
39
|
+
px: 'var(--zd_size$$)'
|
40
|
+
},
|
41
|
+
available: populateArray(-250, 251),
|
42
|
+
replacementValues: {
|
43
|
+
px: []
|
44
|
+
}
|
45
|
+
},
|
46
|
+
'margin-left': {
|
47
|
+
allowed: ['px'],
|
48
|
+
replacements: {
|
49
|
+
px: 'var(--zd_size$$)'
|
50
|
+
},
|
51
|
+
available: populateArray(-250, 251),
|
52
|
+
replacementValues: {
|
53
|
+
px: []
|
54
|
+
}
|
55
|
+
},
|
56
|
+
'margin-right': {
|
57
|
+
allowed: ['px'],
|
58
|
+
replacements: {
|
59
|
+
px: 'var(--zd_size$$)'
|
60
|
+
},
|
61
|
+
available: populateArray(-250, 251),
|
62
|
+
replacementValues: {
|
63
|
+
px: []
|
64
|
+
}
|
65
|
+
},
|
66
|
+
'margin-top': {
|
67
|
+
allowed: ['px'],
|
68
|
+
replacements: {
|
69
|
+
px: 'var(--zd_size$$)'
|
70
|
+
},
|
71
|
+
available: populateArray(-250, 251),
|
72
|
+
replacementValues: {
|
73
|
+
px: []
|
74
|
+
}
|
75
|
+
},
|
76
|
+
'margin-bottom': {
|
77
|
+
allowed: ['px'],
|
78
|
+
replacements: {
|
79
|
+
px: 'var(--zd_size$$)'
|
80
|
+
},
|
81
|
+
available: populateArray(-250, 251),
|
82
|
+
replacementValues: {
|
83
|
+
px: []
|
84
|
+
}
|
85
|
+
}
|
86
|
+
};
|
87
|
+
|
88
|
+
function hasIgnoreComment(node) {
|
89
|
+
return node ? node.type == 'comment' ? node.text == 'Variable:Ignore' ? true : false : false : false;
|
90
|
+
}
|
91
|
+
|
92
|
+
let errors = [];
|
93
|
+
module.exports = postcss.plugin('postcss-variable-report', () => rootOriginal => {
|
94
|
+
// console.log('inside postcss plugin')
|
95
|
+
// fs.writeFile('./css_error.log', '\r\nLog File: \r\n\r\n', (err) => {
|
96
|
+
// if(err)console.log(err);
|
97
|
+
// });
|
98
|
+
// console.log(rootOriginal.source.input.file);
|
99
|
+
if (!rootOriginal.source.input.file.includes('css_error')) {
|
100
|
+
rootOriginal.walkRules(rule => {
|
101
|
+
rule.walkDecls((decl, position) => {
|
102
|
+
// case font-size
|
103
|
+
if (!hasIgnoreComment(rule.nodes[position - 1])) {
|
104
|
+
let unit = decl.value.replace(/[0-9]/g, '');
|
105
|
+
let settings = numberObject[decl.prop];
|
106
|
+
let path = rootOriginal.source.input.from;
|
107
|
+
let filename = path.split('\\');
|
108
|
+
filename = filename[filename.length - 1];
|
109
|
+
|
110
|
+
if (decl.prop === 'font-size' || decl.prop === 'margin-left' || decl.prop === 'margin-right' || decl.prop === 'margin-top' || decl.prop === 'margin-bottom') {
|
111
|
+
let {
|
112
|
+
allowed,
|
113
|
+
replacements,
|
114
|
+
available
|
115
|
+
} = settings;
|
116
|
+
|
117
|
+
if (!rootOriginal.source.input.from.includes('node_modules')) {
|
118
|
+
if (unit != 0) {
|
119
|
+
if (allowed.includes(unit)) {
|
120
|
+
// console.log(available, parseInt(decl.value))
|
121
|
+
if (available.includes(parseInt(decl.value))) {
|
122
|
+
// replacementValues[unit].push({[decl.value] : replacements[unit].replace('$$', parseInt(decl.value))})
|
123
|
+
decl.value = replacements[unit].replace('$$', parseInt(decl.value)); //console.log("replacements:")
|
124
|
+
} else {
|
125
|
+
let err = {
|
126
|
+
prop: decl.prop,
|
127
|
+
value: decl.value,
|
128
|
+
filename,
|
129
|
+
filepath: rootOriginal.source.input.from,
|
130
|
+
line: decl.source.start.line,
|
131
|
+
unit,
|
132
|
+
message: 'value not available consider others'
|
133
|
+
};
|
134
|
+
errors.push(err);
|
135
|
+
}
|
136
|
+
} else {
|
137
|
+
let err = {
|
138
|
+
prop: decl.prop,
|
139
|
+
value: decl.value,
|
140
|
+
filename,
|
141
|
+
filepath: rootOriginal.source.input.from,
|
142
|
+
line: decl.source.start.line,
|
143
|
+
unit,
|
144
|
+
message: 'Unit not supported'
|
145
|
+
};
|
146
|
+
errors.push(err);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
} else if (decl.prop === 'margin') {
|
151
|
+
let {
|
152
|
+
allowed,
|
153
|
+
replacements,
|
154
|
+
available
|
155
|
+
} = settings; //console.log(decl.prop + " " + decl.value)
|
156
|
+
|
157
|
+
let valArr = decl.value.split(' '); //console.log(valArr)
|
158
|
+
//console.log(allowed, replacements, available)
|
159
|
+
|
160
|
+
let hasError = false;
|
161
|
+
let newVal = '';
|
162
|
+
valArr.forEach(val => {
|
163
|
+
let unit = val.replace(parseInt(val), '');
|
164
|
+
let numVal = parseInt(val);
|
165
|
+
|
166
|
+
if (unit != 0) {
|
167
|
+
if (allowed.includes(unit)) {
|
168
|
+
if (available.includes(numVal)) {
|
169
|
+
if (numVal >= 0) {
|
170
|
+
if (!hasError) {
|
171
|
+
newVal += replacements[unit].replace('$$', numVal) + " ";
|
172
|
+
}
|
173
|
+
} else {
|
174
|
+
if (!hasError) {
|
175
|
+
newVal += `calc(${replacements[unit].replace('$$', numVal * -1)} * -1)` + " ";
|
176
|
+
}
|
177
|
+
}
|
178
|
+
} else {
|
179
|
+
hasError = true;
|
180
|
+
let err = {
|
181
|
+
prop: decl.prop,
|
182
|
+
value: numVal,
|
183
|
+
filename,
|
184
|
+
filepath: rootOriginal.source.input.from,
|
185
|
+
line: decl.source.start.line,
|
186
|
+
unit,
|
187
|
+
message: 'value not available consider others'
|
188
|
+
};
|
189
|
+
errors.push(err);
|
190
|
+
}
|
191
|
+
} else {
|
192
|
+
hasError = true;
|
193
|
+
let err = {
|
194
|
+
prop: decl.prop,
|
195
|
+
value: decl.value,
|
196
|
+
filename,
|
197
|
+
filepath: rootOriginal.source.input.from,
|
198
|
+
line: decl.source.start.line,
|
199
|
+
unit,
|
200
|
+
message: 'Unit not supported'
|
201
|
+
};
|
202
|
+
errors.push(err);
|
203
|
+
}
|
204
|
+
}
|
205
|
+
});
|
206
|
+
|
207
|
+
if (!hasError) {
|
208
|
+
decl.value = newVal;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
});
|
213
|
+
}); //fs.writeFile('./src/trial.json', JSON.stringify(variables) ,(err) =>{
|
214
|
+
// if(err)console.log(err);
|
215
|
+
// else{
|
216
|
+
// console.log('updated successfully');
|
217
|
+
// }
|
218
|
+
// })
|
219
|
+
// console.log(errors)
|
220
|
+
|
221
|
+
let errorArr = [];
|
222
|
+
errors.forEach(errStr => {
|
223
|
+
errorArr.push(` prop: ${errStr.prop} ,\n value : ${errStr.value} ,\n filename : ${errStr.filename} ,\n filepath : ${errStr.filepath} ,\n line : ${errStr.line} ,\n unit : ${errStr.unit} ,\n message : ${errStr.message} \r`);
|
224
|
+
}); //fs.writeFile('./css_error.log','', (err) =>{
|
225
|
+
// if(err){
|
226
|
+
// console.log(err);
|
227
|
+
// }
|
228
|
+
//});
|
229
|
+
// errorArr.forEach(err => {
|
230
|
+
// let data = `\n{\n${err}\n},\n`;
|
231
|
+
// //fs.appendFile('./css_error.log',data,(err)=>{
|
232
|
+
// // if(err){
|
233
|
+
// // console.log(err);
|
234
|
+
// // }
|
235
|
+
// //})
|
236
|
+
// });
|
237
|
+
// fs.writeFileSync('./css_error.log','');
|
238
|
+
// errorArr.forEach(err => {
|
239
|
+
// let data = `\n{\n${err}\n},\n`;
|
240
|
+
// fs.appendFileSync('./css_error.log',data);
|
241
|
+
// });
|
242
|
+
}
|
243
|
+
});
|
package/lib/schemas/index.js
CHANGED
@@ -71,8 +71,14 @@ var _default = {
|
|
71
71
|
},
|
72
72
|
createSDkFile: false,
|
73
73
|
nameScope: 'ZOHODESK',
|
74
|
-
version:
|
75
|
-
|
74
|
+
version: {
|
75
|
+
value: 'stable',
|
76
|
+
cli: 'efc_version'
|
77
|
+
},
|
78
|
+
outputFile: {
|
79
|
+
value: 'efc-sdk-[version].js',
|
80
|
+
cli: 'efc_output_file'
|
81
|
+
},
|
76
82
|
templateFilePath: '',
|
77
83
|
localeAttr: 'data-efc-locale',
|
78
84
|
localeDefaultValue: 'en_US',
|
@@ -199,8 +205,16 @@ var _default = {
|
|
199
205
|
value: true,
|
200
206
|
cli: 'enable_smaphook'
|
201
207
|
},
|
202
|
-
|
203
|
-
|
208
|
+
plugins: {
|
209
|
+
hasRTL: false,
|
210
|
+
hoverActive: false,
|
211
|
+
combinerMediaQuery: false
|
212
|
+
},
|
213
|
+
exclude: {
|
214
|
+
rtl: [],
|
215
|
+
hoverActive: [],
|
216
|
+
combinerMediaQuery: []
|
217
|
+
},
|
204
218
|
seperateCssModules: {
|
205
219
|
value: false,
|
206
220
|
cli: 'sep_cssmodules'
|
@@ -270,8 +284,16 @@ var _default = {
|
|
270
284
|
enableChunkHash: false,
|
271
285
|
folder: 'src',
|
272
286
|
disableES5Transpile: false,
|
273
|
-
|
274
|
-
|
287
|
+
plugins: {
|
288
|
+
hasRTL: false,
|
289
|
+
hoverActive: false,
|
290
|
+
combinerMediaQuery: false
|
291
|
+
},
|
292
|
+
exclude: {
|
293
|
+
rtl: [],
|
294
|
+
hoverActive: [],
|
295
|
+
combinerMediaQuery: []
|
296
|
+
},
|
275
297
|
cssHashSelectors: {
|
276
298
|
filenames: [],
|
277
299
|
packages: []
|
@@ -9,16 +9,20 @@ var _path = _interopRequireDefault(require("path"));
|
|
9
9
|
|
10
10
|
var _os = require("os");
|
11
11
|
|
12
|
+
var _fs = require("fs");
|
13
|
+
|
12
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
13
15
|
|
14
|
-
|
16
|
+
const appPath = process.cwd();
|
15
17
|
const isNodeModuleUnderAppFolder = __dirname.indexOf(appPath) !== -1;
|
16
|
-
|
18
|
+
const isWindows = (0, _os.platform)().toLowerCase() === 'win32';
|
17
19
|
|
18
20
|
const _getCliPath = !isNodeModuleUnderAppFolder ? libName => _path.default.join(__dirname, '..', '..', 'node_modules', '.bin', libName) : libName => libName;
|
19
21
|
|
20
22
|
const suffixExt = isWindows ? '.cmd' : '';
|
21
23
|
|
22
24
|
function getCliPath(libName) {
|
23
|
-
|
25
|
+
const cliPath = _getCliPath(libName + suffixExt);
|
26
|
+
|
27
|
+
return (0, _fs.existsSync)(cliPath) ? cliPath : libName + suffixExt;
|
24
28
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@zohodesk/react-cli",
|
3
|
-
"version": "0.0.1-beta.
|
3
|
+
"version": "0.0.1-beta.170",
|
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",
|