mirror of
https://gitee.com/openharmony/developtools_ace_js2bundle
synced 2024-11-23 07:20:22 +00:00
Signed-off-by: zhongjianfei <zhongjianfei@huawei.com>
This commit is contained in:
parent
c075db5164
commit
87223c37dd
94
BUILD.gn
Normal file
94
BUILD.gn
Normal file
@ -0,0 +1,94 @@
|
||||
# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
|
||||
|
||||
import("//build/ohos.gni")
|
||||
import("//build/ohos/ace/ace.gni")
|
||||
import("//foundation/ace/ace_engine/ace_config.gni")
|
||||
|
||||
ace_loader_lib_dir =
|
||||
get_label_info(":build_ace_loader_library", "target_out_dir") + "/lib"
|
||||
|
||||
action("build_ace_loader_library") {
|
||||
script = "//foundation/ace/huawei_proprietary/tools/ace-loader/build_ace_loader_library.py"
|
||||
depfile = "$target_gen_dir/$target_name.d"
|
||||
outputs = [ ace_loader_lib_dir ]
|
||||
|
||||
_ace_loader_dir =
|
||||
"//foundation/ace/huawei_proprietary/tools/ace-loader/ace-loader"
|
||||
_ace_toolkit_dir = "//prebuilts/ace-toolkit/ace-loader/linux-x64"
|
||||
|
||||
_module_source_js = _ace_loader_dir + "/module-source.js"
|
||||
|
||||
_babel_js = _ace_toolkit_dir + "/node_modules/@babel/cli/bin/babel.js"
|
||||
_babel_config_js = _ace_toolkit_dir + "/babel.config.js"
|
||||
_uglify_source_js = _ace_toolkit_dir + "/uglify-source.js"
|
||||
|
||||
inputs = [
|
||||
_babel_config_js,
|
||||
_babel_js,
|
||||
_module_source_js,
|
||||
_uglify_source_js,
|
||||
]
|
||||
|
||||
# different host platform nodejs tool directory
|
||||
if (host_os == "linux") {
|
||||
nodejs_path =
|
||||
"//prebuilts/ace-toolkit/nodejs/node-v12.18.4-linux-x64/bin/node"
|
||||
} else if (host_os == "mac") {
|
||||
nodejs_path =
|
||||
"//prebuilts/ace-toolkit/nodejs/node-v12.18.4-darwin-x64/bin/node"
|
||||
} else {
|
||||
assert(false, "Unsupported host_os: $host_os")
|
||||
}
|
||||
|
||||
args = [
|
||||
"--depfile",
|
||||
rebase_path(depfile, root_build_dir),
|
||||
"--node",
|
||||
rebase_path(nodejs_path, root_build_dir),
|
||||
"--babel-js",
|
||||
rebase_path(_babel_js, root_build_dir),
|
||||
"--weex-loader-src-dir",
|
||||
rebase_path(_ace_loader_dir + "/third_party/weex-loader/src",
|
||||
root_build_dir),
|
||||
"--ace-loader-src-dir",
|
||||
rebase_path(_ace_loader_dir + "/src", root_build_dir),
|
||||
"--babel-config-js",
|
||||
rebase_path(_babel_config_js, root_build_dir),
|
||||
"--module-source-js",
|
||||
rebase_path(_module_source_js, root_build_dir),
|
||||
"--uglify-source-js",
|
||||
rebase_path(_uglify_source_js, root_build_dir),
|
||||
"--output-dir",
|
||||
rebase_path(ace_loader_lib_dir, root_build_dir),
|
||||
]
|
||||
}
|
||||
|
||||
ohos_copy("ace_loader") {
|
||||
sources = [
|
||||
"ace-loader/.npmignore",
|
||||
"ace-loader/babel.config.js",
|
||||
"ace-loader/index.js",
|
||||
"ace-loader/main.product.js",
|
||||
"ace-loader/npm-install.js",
|
||||
"ace-loader/package-lock.json",
|
||||
"ace-loader/package.json",
|
||||
"ace-loader/router",
|
||||
"ace-loader/sample",
|
||||
"ace-loader/webpack.lite.config.js",
|
||||
"ace-loader/webpack.rich.config.js",
|
||||
"ace-loader/webpack.router.config.js",
|
||||
]
|
||||
outputs = [ target_out_dir + "/$target_name/{{source_file_part}}" ]
|
||||
module_source_dir = target_out_dir + "/$target_name/"
|
||||
module_install_name = ""
|
||||
license_file = "//third_party/parse5/LICENSE"
|
||||
}
|
||||
|
||||
ohos_copy("ace_loader_library") {
|
||||
deps = [ ":build_ace_loader_library" ]
|
||||
sources = [ ace_loader_lib_dir ]
|
||||
outputs = [ target_out_dir + "/$target_name" ]
|
||||
module_source_dir = target_out_dir + "/$target_name"
|
||||
module_install_name = ""
|
||||
license_file = "//third_party/weex-loader/NOTICE"
|
||||
}
|
177
LICENSE
Normal file
177
LICENSE
Normal file
@ -0,0 +1,177 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
36
ace-loader/.eslintrc.js
Normal file
36
ace-loader/.eslintrc.js
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
node: true,
|
||||
},
|
||||
extends: ['google'],
|
||||
globals: {
|
||||
profiler: 'readonly',
|
||||
initStyleSheet: 'readonly',
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
sourceType: 'module',
|
||||
},
|
||||
rules: {
|
||||
'comma-dangle': ['error', 'always-multiline'],
|
||||
'object-curly-spacing': ['error', 'always'],
|
||||
'max-len': ['error', { 'code': 120 }],
|
||||
},
|
||||
};
|
3
ace-loader/.gitignore
vendored
Normal file
3
ace-loader/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
lib
|
||||
build
|
3
ace-loader/.npmignore
Normal file
3
ace-loader/.npmignore
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
src
|
||||
test
|
27
ace-loader/README.md
Normal file
27
ace-loader/README.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Ace Loader
|
||||
|
||||
A webpack loader for Ace.
|
||||
|
||||
## Install Dependencies under the ace-loader dir.
|
||||
|
||||
npm install
|
||||
|
||||
## Build built-in sample for Rich devices under the ace-loader dir.
|
||||
|
||||
npm run rich
|
||||
|
||||
## Build built-in sample for Lite devices under the ace-loader dir.
|
||||
|
||||
npm run lite
|
||||
|
||||
## How to build custom ace project
|
||||
|
||||
Windows:
|
||||
Step 1. set aceModuleRoot=path/to/your/ace/project
|
||||
Step 2. set aceModuleBuild=path/to/your/jsbundle/build
|
||||
Step 3. node ./node_modules/webpack/bin/webpack.js --config webpack.rich.config.js
|
||||
|
||||
Linux:
|
||||
Step 1. export aceModuleRoot=path/to/your/ace/project
|
||||
Step 2. export aceModuleBuild=path/to/your/jsbundle/build
|
||||
Step 3. node ./node_modules/webpack/bin/webpack.js --config webpack.rich.config.js
|
36
ace-loader/babel.config.js
Normal file
36
ace-loader/babel.config.js
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module.exports = function(api) {
|
||||
api.cache(true);
|
||||
|
||||
const presets = ['@babel/preset-env'];
|
||||
const plugins = [
|
||||
'@babel/plugin-transform-modules-commonjs',
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
'@babel/plugin-transform-runtime',
|
||||
[
|
||||
'@babel/plugin-transform-arrow-functions',
|
||||
{
|
||||
spec: true,
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
return {
|
||||
presets,
|
||||
plugins,
|
||||
};
|
||||
};
|
16
ace-loader/index.js
Normal file
16
ace-loader/index.js
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module.exports = require('./lib/loader')
|
79
ace-loader/main.product.js
Normal file
79
ace-loader/main.product.js
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var path = require('path')
|
||||
var fs = require('fs')
|
||||
|
||||
const red = '\u001b[31m';
|
||||
const reset = '\u001b[39m';
|
||||
|
||||
function deleteFolderRecursive(url) {
|
||||
let files = [];
|
||||
if (fs.existsSync(url)) {
|
||||
files = fs.readdirSync(url);
|
||||
files.forEach(function(file) {
|
||||
const curPath = path.join(url, file);
|
||||
if (fs.statSync(curPath).isDirectory()) {
|
||||
deleteFolderRecursive(curPath);
|
||||
} else {
|
||||
fs.unlinkSync(curPath);
|
||||
}
|
||||
});
|
||||
fs.rmdir(url, function(err) {});
|
||||
}
|
||||
}
|
||||
|
||||
function readManifest(manifestFilePath) {
|
||||
let manifest = {};
|
||||
try {
|
||||
const jsonString = fs.readFileSync(manifestFilePath).toString()
|
||||
manifest = JSON.parse(jsonString)
|
||||
} catch (e) {
|
||||
throw Error('\u001b[31m' + 'ERROR: the manifest file is lost or format is invalid.' + '\u001b[39m').message
|
||||
}
|
||||
return manifest;
|
||||
}
|
||||
|
||||
function loadEntryObj(manifest, projectPath, device_level) {
|
||||
let entryObj = {}
|
||||
const appJSPath = path.resolve(projectPath, 'app.js');
|
||||
if (device_level === 'card') {
|
||||
entryObj = addPageEntryObj(manifest, projectPath);
|
||||
} else {
|
||||
if (!fs.existsSync(appJSPath)) {
|
||||
throw Error(red + 'ERROR: missing app.js' + reset).message;
|
||||
}
|
||||
entryObj['./app'] = projectPath + '/app.js?entry';
|
||||
}
|
||||
return entryObj;
|
||||
}
|
||||
|
||||
function addPageEntryObj(manifest, projectPath) {
|
||||
let entryObj = {};
|
||||
const pages = manifest.pages;
|
||||
if (pages === undefined) {
|
||||
throw Error('ERROR: missing pages').message;
|
||||
}
|
||||
pages.forEach((element) => {
|
||||
entryObj['./' + element] = projectPath + path.sep + element + '.hml?entry'
|
||||
})
|
||||
return entryObj;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
deleteFolderRecursive: deleteFolderRecursive,
|
||||
readManifest: readManifest,
|
||||
loadEntryObj: loadEntryObj
|
||||
};
|
73
ace-loader/module-source.js
Normal file
73
ace-loader/module-source.js
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const exists = function(src, dst, callback) {
|
||||
if (src.match(/\/test$/)) {
|
||||
return;
|
||||
}
|
||||
fs.exists(dst, function(exists) {
|
||||
if(exists){
|
||||
callback(src, dst);
|
||||
} else{
|
||||
fs.mkdir(dst, function() {
|
||||
callback(src, dst);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
stat = fs.stat;
|
||||
const copy = function(src, dst){
|
||||
fs.readdir(src, function(err, paths){
|
||||
if(err){
|
||||
throw err;
|
||||
}
|
||||
paths.forEach(function(_path){
|
||||
var _src = src + '/' + _path,
|
||||
_dst = dst + '/' + _path,
|
||||
readable, writable;
|
||||
stat(_src, function(err, st){
|
||||
if(err){
|
||||
throw err;
|
||||
}
|
||||
if(st.isFile()){
|
||||
const pathInfo = path.parse(_src);
|
||||
if (pathInfo.name == 'gulpfile' || pathInfo.ext != '.js') {
|
||||
return;
|
||||
}
|
||||
readable = fs.createReadStream(_src);
|
||||
writable = fs.createWriteStream(_dst);
|
||||
readable.pipe(writable);
|
||||
} else if(st.isDirectory()){
|
||||
exists(_src, _dst, copy);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function copyResource(src, dist) {
|
||||
exists(path.resolve(__dirname, src), dist, copy);
|
||||
}
|
||||
|
||||
copyResource(path.resolve(__dirname, './plugin/templater'), process.argv[2] + '/templater');
|
||||
copyResource(path.resolve(__dirname, './plugin/theme'), process.argv[2] + '/theme');
|
||||
copyResource(path.resolve(__dirname, './plugin/codegen'), process.argv[2] + '/codegen');
|
||||
copyResource(path.resolve(__dirname, './third_party/weex-loader/deps/weex-scripter'), process.argv[2] + '/scripter');
|
||||
copyResource(path.resolve(__dirname, './third_party/weex-loader/deps/weex-styler'), process.argv[2] + '/styler');
|
||||
copyResource(path.resolve(__dirname, '../../../../../../third_party/parse5/packages/parse5/lib'), process.argv[2] + '/parse');
|
37
ace-loader/npm-install.js
Normal file
37
ace-loader/npm-install.js
Normal file
@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
let exec = require('child_process').exec;
|
||||
|
||||
if ( !fs.existsSync(path.resolve(path.join(__dirname, 'bin'), "ark"))) return;
|
||||
|
||||
var build_linux = path.join(__dirname, "bin", "ark", "build");
|
||||
var build_win = path.join(__dirname, "bin", "ark", "build-win");
|
||||
var build_mac = path.join(__dirname, "bin", "ark", "build-mac");
|
||||
|
||||
var isWin = !1;
|
||||
var isMac = !1;
|
||||
|
||||
if (fs.existsSync(path.resolve(path.join(__dirname, 'bin'), "ark/build-win"))) {
|
||||
isWin = !0;
|
||||
} else if (fs.existsSync(path.resolve(path.join(__dirname, 'bin'), "ark/build-mac"))) {
|
||||
isMac = !0;
|
||||
} else if (!fs.existsSync(path.resolve(path.join(__dirname, 'bin'), "ark/build"))) {
|
||||
throw Error("Error: find build fail").message;
|
||||
}
|
||||
|
||||
let cwd;
|
||||
if (isWin) {
|
||||
cwd = build_win
|
||||
} else if (isMac) {
|
||||
cwd = build_mac
|
||||
} else {
|
||||
cwd = build_linux
|
||||
}
|
||||
|
||||
exec("npm install", { cwd: cwd }, function (err, stdout, stderr) {
|
||||
console.log("[31m", stdout, "[39m");
|
||||
if (err != null) {
|
||||
throw Error(`npm install filed: ${err}`).message;
|
||||
}
|
||||
});
|
6423
ace-loader/package-lock.json
generated
Normal file
6423
ace-loader/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
74
ace-loader/package.json
Normal file
74
ace-loader/package.json
Normal file
@ -0,0 +1,74 @@
|
||||
{
|
||||
"name": "ace-loader",
|
||||
"version": "1.0.11",
|
||||
"description": "a webpack loader for ace",
|
||||
"main": "index.js",
|
||||
"private": true,
|
||||
"keywords": [
|
||||
"ace",
|
||||
"loader",
|
||||
"webpack",
|
||||
"Lite",
|
||||
"Rich"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "",
|
||||
"rich": "cd sample/rich && webpack --config ../../webpack.rich.config.js",
|
||||
"lite": "cd sample/lite && webpack --config ../../webpack.lite.config.js",
|
||||
"card": "cd sample/card && webpack --config ../../webpack.rich.config.js",
|
||||
"postinstall": "node npm-install.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^3.5.0",
|
||||
"eslint": "^7.3.1",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"mocha": "^7.1.2",
|
||||
"sinon": "^1.17.3",
|
||||
"sinon-chai": "^2.8.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/cli": "^7.8.4",
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
"@babel/plugin-transform-runtime": "^7.12.10",
|
||||
"@babel/preset-env": "^7.9.0",
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-plugin-require-context-hook": "^1.0.0",
|
||||
"copy-webpack-plugin": "^8.1.0",
|
||||
"css": "^3.0.0",
|
||||
"css-loader": "^3.4.2",
|
||||
"deccjsunit": "latest",
|
||||
"escodegen": "^2.0.0",
|
||||
"esprima": "^4.0.1",
|
||||
"hash-sum": "^1.0.2",
|
||||
"jimp": "^0.12.1",
|
||||
"less": "^3.11.1",
|
||||
"less-loader": "^5.0.0",
|
||||
"loader-utils": "^1.1.0",
|
||||
"md5": "^2.1.0",
|
||||
"parse5": "^2.1.5",
|
||||
"resolve-bin": "^0.4.0",
|
||||
"sass": "^1.26.8",
|
||||
"sass-loader": "^7.3.1",
|
||||
"source-map": "^0.7.3",
|
||||
"uglify-es": "^3.3.9",
|
||||
"webpack": "^5.48.0",
|
||||
"webpack-cli": "^4.6.0"
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
"@babel/preset-env"
|
||||
],
|
||||
"plugins": [
|
||||
"@babel/plugin-transform-modules-commonjs",
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
[
|
||||
"@babel/plugin-transform-arrow-functions",
|
||||
{
|
||||
"spec": true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
736
ace-loader/plugin/codegen/index.js
Normal file
736
ace-loader/plugin/codegen/index.js
Normal file
@ -0,0 +1,736 @@
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ var __webpack_modules__ = ({
|
||||
|
||||
/***/ 784:
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
|
||||
/**
|
||||
* Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.errorMap = void 0;
|
||||
exports.errorMap = new Map([
|
||||
["fileError", "Visual file is damaged"],
|
||||
["versionError", "Version number of visual file does not match"],
|
||||
["modelError", "Visual model in visual file is damaged"],
|
||||
["codegenError", "Codegen hml and css failed"],
|
||||
]);
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 243:
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
|
||||
/*
|
||||
* @Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.Style = exports.Tag = void 0;
|
||||
class Tag {
|
||||
/**
|
||||
* @description: constructor for Tag
|
||||
* @param tagName is name of component
|
||||
* @param attributes is attributes of component
|
||||
* @param content is child elements or innerHtml of component
|
||||
*/
|
||||
constructor(tagName, attributes, content) {
|
||||
this.tagName = tagName;
|
||||
this.attributes = attributes;
|
||||
this.content = content;
|
||||
}
|
||||
accept(v) {
|
||||
return v.genTag(this);
|
||||
}
|
||||
}
|
||||
exports.Tag = Tag;
|
||||
class Style {
|
||||
/**
|
||||
* @description: constructor for Style
|
||||
* @param kind distinguishes id and class
|
||||
* @param name is name of id or class
|
||||
* @param content is style name and value of component
|
||||
*/
|
||||
constructor(kind, name, content) {
|
||||
this.kind = kind;
|
||||
this.name = name;
|
||||
this.content = content;
|
||||
}
|
||||
accept(v) {
|
||||
return v.genStyle(this);
|
||||
}
|
||||
}
|
||||
exports.Style = Style;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 245:
|
||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||||
|
||||
|
||||
/*
|
||||
* @Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.StringWriter = void 0;
|
||||
const ASTNodeVisitor_1 = __webpack_require__(573);
|
||||
const Cache_1 = __webpack_require__(695);
|
||||
class StringWriter {
|
||||
constructor() {
|
||||
this.generator = ASTNodeVisitor_1.ASTNodeGenerator.getMethodGen(new Cache_1.Cache(""));
|
||||
}
|
||||
/**
|
||||
* @description: generate HML
|
||||
* @param t is Tag in AST
|
||||
* @return HML code
|
||||
*/
|
||||
genHML(t) {
|
||||
t.accept(this.generator);
|
||||
return this.generator.cache.toString();
|
||||
}
|
||||
/**
|
||||
* @description: generate CSS
|
||||
* @param t is Style in AST
|
||||
* @return CSS code
|
||||
*/
|
||||
genCSS(t) {
|
||||
t.forEach((value) => {
|
||||
value.accept(this.generator);
|
||||
});
|
||||
return this.generator.cache.toString();
|
||||
}
|
||||
}
|
||||
exports.StringWriter = StringWriter;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 573:
|
||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||||
|
||||
|
||||
/*
|
||||
* @Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.ASTNodeGenerator = void 0;
|
||||
const Token_1 = __webpack_require__(334);
|
||||
class ASTNodeGenerator {
|
||||
/**
|
||||
* @description: constructor for BridgeVisitor
|
||||
* @param reference is cache for Harmony FA code
|
||||
*/
|
||||
constructor(reference) {
|
||||
this.cache = reference;
|
||||
}
|
||||
/**
|
||||
* @description: code generator
|
||||
* @param ref is cache for code
|
||||
* @return ast node generator
|
||||
*/
|
||||
static getMethodGen(ref) {
|
||||
if (ASTNodeGenerator.instance === undefined) {
|
||||
ASTNodeGenerator.instance = new ASTNodeGenerator(ref);
|
||||
}
|
||||
else {
|
||||
ASTNodeGenerator.instance.setCache(ref);
|
||||
}
|
||||
return ASTNodeGenerator.instance;
|
||||
}
|
||||
/**
|
||||
* @description: cache for code
|
||||
* @param ref is cache for code
|
||||
* @return void
|
||||
*/
|
||||
setCache(ref) {
|
||||
this.cache = ref;
|
||||
}
|
||||
/**
|
||||
* @description: parse Tag in AST and generate code for Tag in cache
|
||||
* @param Tag in AST
|
||||
* @return void
|
||||
*/
|
||||
genTag(t) {
|
||||
this.cache.concat(Token_1.TokenClass.TAG_START, t.tagName);
|
||||
this.cache.indentOff();
|
||||
t.attributes.forEach((value, key) => {
|
||||
let valueBK = "";
|
||||
for (const char of value) {
|
||||
valueBK += (char === "\"" ? """ : (char === "\n" ? " " : char));
|
||||
}
|
||||
this.cache.concat(Token_1.TokenClass.SPACE, key, Token_1.TokenClass.ASSIGN, Token_1.TokenClass.LQUOTE, valueBK, Token_1.TokenClass.RQUOTE);
|
||||
});
|
||||
if (t.content === null) {
|
||||
this.cache.concat(Token_1.TokenClass.EMPTY_TAG_END);
|
||||
}
|
||||
else {
|
||||
this.cache.concat(Token_1.TokenClass.TAG_END);
|
||||
if (typeof t.content === "string") {
|
||||
let contentBK = "";
|
||||
for (const char of t.content) {
|
||||
contentBK += (char === "<" ? "<" : (char === "\n" ? " " : char));
|
||||
}
|
||||
this.cache.concat(contentBK);
|
||||
}
|
||||
else if (t.content.length !== 0) {
|
||||
this.cache.concat(Token_1.TokenClass.NEW_LINE);
|
||||
this.cache.indentOn();
|
||||
this.cache.incIndent();
|
||||
t.content.forEach((tag) => {
|
||||
tag.accept(this);
|
||||
this.cache.indentOff();
|
||||
this.cache.concat(Token_1.TokenClass.NEW_LINE);
|
||||
this.cache.indentOn();
|
||||
});
|
||||
this.cache.decIndent();
|
||||
this.cache.indentOn();
|
||||
}
|
||||
this.cache.concat(Token_1.TokenClass.END_TAG_START, t.tagName, Token_1.TokenClass.TAG_END);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @description: parse Style in AST and generate code for Style in cache
|
||||
* @param Style in AST
|
||||
* @return void
|
||||
*/
|
||||
genStyle(s) {
|
||||
if (s.kind === "IDStyle") {
|
||||
this.cache.concat(Token_1.TokenClass.ID_STYLE_START);
|
||||
this.cache.indentOff();
|
||||
}
|
||||
this.cache.concat(s.name, Token_1.TokenClass.SPACE, Token_1.TokenClass.LBRA, Token_1.TokenClass.NEW_LINE);
|
||||
this.cache.indentOn();
|
||||
this.cache.incIndent();
|
||||
s.content.forEach((value, key) => {
|
||||
this.cache.concat(key, Token_1.TokenClass.COLON, Token_1.TokenClass.SPACE, value, Token_1.TokenClass.SEMICOLON, Token_1.TokenClass.NEW_LINE);
|
||||
});
|
||||
this.cache.decIndent();
|
||||
this.cache.concat(Token_1.TokenClass.RBRA, Token_1.TokenClass.NEW_LINE, Token_1.TokenClass.NEW_LINE);
|
||||
}
|
||||
}
|
||||
exports.ASTNodeGenerator = ASTNodeGenerator;
|
||||
ASTNodeGenerator.instance = undefined;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 844:
|
||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||||
|
||||
|
||||
/*
|
||||
* @Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.CSSBridge = exports.HMLBridge = void 0;
|
||||
const FATypeChecker_1 = __webpack_require__(335);
|
||||
const AST_1 = __webpack_require__(243);
|
||||
class HMLBridge {
|
||||
constructor() {
|
||||
this.errors = 0;
|
||||
}
|
||||
/**
|
||||
* @description: generate error message
|
||||
* @param msg is error message to showup in console
|
||||
*/
|
||||
error(msg) {
|
||||
console.error("Code generating error: " + msg);
|
||||
this.errors += 1;
|
||||
}
|
||||
/**
|
||||
* @description: get error number
|
||||
* @return error number
|
||||
*/
|
||||
getErrorCount() {
|
||||
return this.errors;
|
||||
}
|
||||
/**
|
||||
* @description: code generator for Tag, which is HML type in AST in IR
|
||||
* @param tag is a object with HML type to be generated
|
||||
* @return a code tree representing Harmony FA HML code
|
||||
*/
|
||||
genTag(tag) {
|
||||
let content = null;
|
||||
if (FATypeChecker_1.hasTextContent(tag)) {
|
||||
content = tag.content;
|
||||
}
|
||||
else if (FATypeChecker_1.hasArrayContent(tag)) {
|
||||
const subTags = [];
|
||||
tag.content.forEach((t) => {
|
||||
const tree = t.accept(this);
|
||||
if (tree instanceof AST_1.Tag) {
|
||||
subTags.push(tree);
|
||||
}
|
||||
else {
|
||||
throw new Error("WTF: what a trrrible failure");
|
||||
}
|
||||
});
|
||||
content = subTags;
|
||||
}
|
||||
return new AST_1.Tag(tag.tagName, tag.attributes, content);
|
||||
}
|
||||
/**
|
||||
* @description: visitor gurdance method for contents,
|
||||
* sort out incoming type and guide to matching code generator
|
||||
* @param obj is a object with Model or Container or CharUI primitive types to be generated
|
||||
* @return a code tree representing input object
|
||||
*/
|
||||
visit(obj) {
|
||||
if (FATypeChecker_1.isHmlNode(obj)) {
|
||||
return this.genTag(obj);
|
||||
}
|
||||
throw new Error("no return");
|
||||
}
|
||||
}
|
||||
exports.HMLBridge = HMLBridge;
|
||||
class CSSBridge {
|
||||
constructor() {
|
||||
this.errors = 0;
|
||||
this.styles = [];
|
||||
}
|
||||
/**
|
||||
* @description: generate error message
|
||||
* @param msg is error message to showup in console
|
||||
*/
|
||||
error(msg) {
|
||||
console.error("Code generating error: " + msg);
|
||||
this.errors += 1;
|
||||
}
|
||||
/**
|
||||
* @description: get error number
|
||||
* @return error number
|
||||
*/
|
||||
getErrorCount() {
|
||||
return this.errors;
|
||||
}
|
||||
/**
|
||||
* @description: code generator for ID Style, which is CSS type in AST in IR
|
||||
* @param tag is a object with CSS type to be generated
|
||||
* @return a code tree representing Harmony FA CSS code
|
||||
*/
|
||||
genIDStyle(tag) {
|
||||
if (tag.idStyle.size > 0) {
|
||||
this.styles.push(new AST_1.Style("IDStyle", tag.id, tag.idStyle));
|
||||
}
|
||||
if (FATypeChecker_1.hasArrayContent(tag)) {
|
||||
for (const child of tag.content) {
|
||||
child.accept(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @description: code generator for Class Style, which is CSS type in AST in IR
|
||||
* @param style is a object with CSS type to be generated
|
||||
* @return a code tree representing Harmony FA CSS code
|
||||
*/
|
||||
genClassStyle(style) {
|
||||
this.styles.push(new AST_1.Style("ClassStyle", style.className, style.content));
|
||||
}
|
||||
/**
|
||||
* @description: visitor gurdance method for contents,
|
||||
* sort out incoming type and guide to matching code generator
|
||||
* @param obj is a object with Model or Container or CharUI primitive types to be generated
|
||||
* @return a code tree representing input object
|
||||
*/
|
||||
visit(obj) {
|
||||
if (FATypeChecker_1.isHmlNode(obj)) {
|
||||
this.genIDStyle(obj);
|
||||
return this.styles;
|
||||
}
|
||||
else if (FATypeChecker_1.isClassStyle(obj)) {
|
||||
this.genClassStyle(obj);
|
||||
return this.styles;
|
||||
}
|
||||
throw new Error("no return");
|
||||
}
|
||||
}
|
||||
exports.CSSBridge = CSSBridge;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 695:
|
||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||||
|
||||
|
||||
/**
|
||||
* Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.Cache = void 0;
|
||||
const Token_1 = __webpack_require__(334);
|
||||
// There is no way pass value by reference with JS and TS, but object
|
||||
class Cache {
|
||||
/**
|
||||
* @description: constructor for Cache
|
||||
* @param value is HML/CSS code with no indents
|
||||
*/
|
||||
constructor(value) {
|
||||
this.value = value;
|
||||
this.indent = 0;
|
||||
this.flag = true;
|
||||
}
|
||||
/**
|
||||
* @description: when flag is true, there should be some indents
|
||||
* @return void
|
||||
*/
|
||||
indentOn() {
|
||||
this.flag = true;
|
||||
}
|
||||
/**
|
||||
* @description: when flag is false, there should be no indents
|
||||
* @return void
|
||||
*/
|
||||
indentOff() {
|
||||
this.flag = false;
|
||||
}
|
||||
/**
|
||||
* @description: increase indent
|
||||
* @return void
|
||||
*/
|
||||
incIndent() {
|
||||
this.indent++;
|
||||
}
|
||||
/**
|
||||
* @description: decrease indent
|
||||
* @return void
|
||||
*/
|
||||
decIndent() {
|
||||
this.indent--;
|
||||
}
|
||||
/**
|
||||
* @description: check whether indent is LT 0
|
||||
* @return boolean value representing whether indent is LT 0
|
||||
*/
|
||||
checkIndent() {
|
||||
return this.indent < 0;
|
||||
}
|
||||
/**
|
||||
* @description: get indent
|
||||
* @return indents
|
||||
*/
|
||||
getIndents() {
|
||||
if (this.flag) {
|
||||
let indents = "";
|
||||
Array.from(Array(this.indent).keys()).forEach(element => {
|
||||
indents += Token_1.TokenClass.INDENT;
|
||||
});
|
||||
return indents;
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @description: concat indents and HML/CSS code
|
||||
* @param strings means HML/CSS code
|
||||
* @return HML/CSS code after indents are set
|
||||
*/
|
||||
concat(...strings) {
|
||||
this.value += this.getIndents();
|
||||
this.value = this.value.concat(...strings);
|
||||
return String(this.value);
|
||||
}
|
||||
/**
|
||||
* @description: concat indents and HML/CSS code
|
||||
* @return HML/CSS code
|
||||
*/
|
||||
toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
exports.Cache = Cache;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 334:
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
|
||||
/**
|
||||
* Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.TokenClass = void 0;
|
||||
var TokenClass;
|
||||
(function (TokenClass) {
|
||||
TokenClass[TokenClass["IDENTIFIER"] = 0] = "IDENTIFIER";
|
||||
// literals
|
||||
TokenClass[TokenClass["STRING_LITERAL"] = 1] = "STRING_LITERAL";
|
||||
TokenClass[TokenClass["NUMBER"] = 2] = "NUMBER";
|
||||
TokenClass[TokenClass["CHARACTER"] = 3] = "CHARACTER";
|
||||
// special tokens
|
||||
TokenClass[TokenClass["EOF"] = 4] = "EOF";
|
||||
TokenClass[TokenClass["INVALID"] = 5] = "INVALID";
|
||||
TokenClass["EMPTY_DATA"] = "empty";
|
||||
TokenClass["ASSIGN"] = "=";
|
||||
// Escape character
|
||||
TokenClass["NEW_LINE"] = "\n";
|
||||
TokenClass["CARRIAGE_RETURN"] = "\r";
|
||||
TokenClass["INDENT"] = " ";
|
||||
// delimiters
|
||||
TokenClass["SPACE"] = " ";
|
||||
TokenClass["LQUOTE"] = "\"";
|
||||
TokenClass["RQUOTE"] = "\"";
|
||||
TokenClass["TAG_START"] = "<";
|
||||
TokenClass["TAG_END"] = ">";
|
||||
TokenClass["EMPTY_TAG_END"] = "/>";
|
||||
TokenClass["END_TAG_START"] = "</";
|
||||
TokenClass["ID_STYLE_START"] = "#";
|
||||
TokenClass["CLASS_STYLE_START"] = ".";
|
||||
TokenClass["LBRA"] = "{";
|
||||
TokenClass["RBRA"] = "}";
|
||||
TokenClass["SEMICOLON"] = ";";
|
||||
TokenClass["COLON"] = ":";
|
||||
})(TokenClass = exports.TokenClass || (exports.TokenClass = {}));
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 704:
|
||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.emit = exports.emitCSS = exports.emitHml = void 0;
|
||||
/**
|
||||
* Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
|
||||
*/
|
||||
const BridgeVisitor_1 = __webpack_require__(844);
|
||||
const ASTFileVisitor_1 = __webpack_require__(245);
|
||||
/**
|
||||
* @description: output the HML source code of the model
|
||||
*/
|
||||
function emitHml(rootModel) {
|
||||
const visitor = new BridgeVisitor_1.HMLBridge();
|
||||
const ast = rootModel.accept(visitor);
|
||||
const stringWriter = new ASTFileVisitor_1.StringWriter();
|
||||
const res = stringWriter.genHML(ast);
|
||||
if (visitor.getErrorCount() > 0) {
|
||||
console.error("Cannot generate code, error found: " + visitor.getErrorCount().toString());
|
||||
return "error";
|
||||
}
|
||||
else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
exports.emitHml = emitHml;
|
||||
/**
|
||||
* @description: output the CSS source code of the model
|
||||
*/
|
||||
function emitCSS(rootModel) {
|
||||
const visitor = new BridgeVisitor_1.CSSBridge();
|
||||
const styles = rootModel.accept(visitor);
|
||||
const stringWriter = new ASTFileVisitor_1.StringWriter();
|
||||
const res = stringWriter.genCSS(styles);
|
||||
if (visitor.getErrorCount() > 0) {
|
||||
console.error("Cannot generate code, error found: " + visitor.getErrorCount().toString());
|
||||
return "error";
|
||||
}
|
||||
else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
exports.emitCSS = emitCSS;
|
||||
/**
|
||||
* @description: output all source code of the model
|
||||
*/
|
||||
function emit(rootModel) {
|
||||
const obj = {
|
||||
hml: emitHml(rootModel),
|
||||
css: emitCSS(rootModel),
|
||||
};
|
||||
return obj;
|
||||
}
|
||||
exports.emit = emit;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 335:
|
||||
/***/ ((__unused_webpack_module, exports) => {
|
||||
|
||||
|
||||
/**
|
||||
* Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.hasJsonTextContent = exports.hasJsonArrayContent = exports.isClassStyle = exports.hasArrayContent = exports.hasTextContent = exports.isText = exports.isHmlNode = exports.isContainer = void 0;
|
||||
function isContainer(obj) {
|
||||
return obj.type === "Container";
|
||||
}
|
||||
exports.isContainer = isContainer;
|
||||
function isHmlNode(obj) {
|
||||
return obj.type === "Container" || obj.type === "TextContent" || obj.type === "Base" || obj.type === "Text";
|
||||
}
|
||||
exports.isHmlNode = isHmlNode;
|
||||
function isText(obj) {
|
||||
return obj.type === "Text";
|
||||
}
|
||||
exports.isText = isText;
|
||||
function hasTextContent(obj) {
|
||||
return obj.content !== undefined && typeof obj.content === "string";
|
||||
}
|
||||
exports.hasTextContent = hasTextContent;
|
||||
function hasArrayContent(obj) {
|
||||
return obj.content !== undefined && obj.content instanceof Array;
|
||||
}
|
||||
exports.hasArrayContent = hasArrayContent;
|
||||
function isClassStyle(obj) {
|
||||
return obj.kind === "ClassStyle";
|
||||
}
|
||||
exports.isClassStyle = isClassStyle;
|
||||
/**
|
||||
* @description: judge whether jsonmodel is nested
|
||||
* @param obj is jsonModel
|
||||
* @return obj is JsonContainerModel
|
||||
*/
|
||||
function hasJsonArrayContent(obj) {
|
||||
return obj.content !== undefined && obj.content instanceof Array;
|
||||
}
|
||||
exports.hasJsonArrayContent = hasJsonArrayContent;
|
||||
/**
|
||||
* @description: judge whether type of jsonmodel's content is string
|
||||
* @param obj is jsonModel
|
||||
* @return obj is JsonTextContentModel
|
||||
*/
|
||||
function hasJsonTextContent(obj) {
|
||||
return obj.content !== undefined && typeof obj.content === "string";
|
||||
}
|
||||
exports.hasJsonTextContent = hasJsonTextContent;
|
||||
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
/************************************************************************/
|
||||
/******/ // The module cache
|
||||
/******/ var __webpack_module_cache__ = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/ // Check if module is in cache
|
||||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||
/******/ if(cachedModule !== undefined) {
|
||||
/******/ return cachedModule.exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||
/******/ // no module.id needed
|
||||
/******/ // no module.loaded needed
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/************************************************************************/
|
||||
var __webpack_exports__ = {};
|
||||
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
|
||||
(() => {
|
||||
var exports = __webpack_exports__;
|
||||
|
||||
/**
|
||||
* Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
const FATypeChecker_1 = __webpack_require__(335);
|
||||
const Emit_1 = __webpack_require__(704);
|
||||
const errorMap_1 = __webpack_require__(784);
|
||||
const visualVersion = 10;
|
||||
/**
|
||||
* @description: codegen hml and css according to code in visual file
|
||||
* @param source is code in visual file
|
||||
* @return object of hmlCSS, errorType and errorMessage
|
||||
*/
|
||||
function genHmlAndCss(source) {
|
||||
const retObj = {
|
||||
hmlCss: {
|
||||
hml: "",
|
||||
css: "",
|
||||
},
|
||||
errorType: "",
|
||||
errorMessage: "",
|
||||
};
|
||||
try {
|
||||
// parse source code in visual file
|
||||
const visualSource = JSON.parse(source);
|
||||
const destVisualVersion = visualSource.VisualVersion;
|
||||
const regex = /^([1-9]+[0-9]*)$/;
|
||||
if (destVisualVersion === undefined) {
|
||||
retObj.errorType = "versionError";
|
||||
}
|
||||
else {
|
||||
const expression = destVisualVersion.match(regex);
|
||||
if (expression === null || parseInt(expression[1]) > visualVersion) {
|
||||
retObj.errorType = "versionError";
|
||||
}
|
||||
}
|
||||
try {
|
||||
const model = genHmlNode(JSON.parse(visualSource.content));
|
||||
const hmlCss = Emit_1.emit(model);
|
||||
if (hmlCss.hml === "error" || hmlCss.css === "error") {
|
||||
retObj.errorType = "codegenError";
|
||||
}
|
||||
retObj.hmlCss = hmlCss;
|
||||
}
|
||||
catch (e) {
|
||||
retObj.errorType = "modelError";
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
retObj.errorType = "fileError";
|
||||
}
|
||||
if (retObj.errorType !== "") {
|
||||
retObj.errorMessage = errorMap_1.errorMap.get(retObj.errorType);
|
||||
retObj.hmlCss.hml = "";
|
||||
retObj.hmlCss.css = "";
|
||||
}
|
||||
return retObj;
|
||||
}
|
||||
/**
|
||||
* @description: generate HmlNode
|
||||
* @param model is json format of HmlNode
|
||||
* @return HmlNode after codegen
|
||||
*/
|
||||
function genHmlNode(model) {
|
||||
const res = {
|
||||
id: model.id,
|
||||
tagName: model.tagName,
|
||||
type: model.type,
|
||||
idStyle: new Map(model.idStyle),
|
||||
attributes: new Map(model.attributes),
|
||||
accept: (v) => {
|
||||
return v.visit(res);
|
||||
},
|
||||
};
|
||||
if (FATypeChecker_1.hasJsonTextContent(model)) {
|
||||
res.content = model.content;
|
||||
}
|
||||
else if (FATypeChecker_1.hasJsonArrayContent(model)) {
|
||||
const content = [];
|
||||
for (const child of model.content) {
|
||||
content.push(genHmlNode(child));
|
||||
}
|
||||
res.content = content;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
exports.genHmlAndCss = genHmlAndCss;
|
||||
|
||||
})();
|
||||
|
||||
var __webpack_export_target__ = exports;
|
||||
for(var i in __webpack_exports__) __webpack_export_target__[i] = __webpack_exports__[i];
|
||||
if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });
|
||||
/******/ })()
|
||||
;
|
239
ace-loader/plugin/templater/bind.js
Normal file
239
ace-loader/plugin/templater/bind.js
Normal file
@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const content = require('./content')
|
||||
const data = require('./data')
|
||||
const { DEVICE_LEVEL } = require('../lite/lite-enum')
|
||||
const card = process.env.DEVICE_LEVEL === DEVICE_LEVEL.CARD
|
||||
const REG_CARD_ARRAY = /(\['.+?'\])|(\[".+?"\])/g
|
||||
|
||||
/**
|
||||
* Check if there is data binding.
|
||||
* @param {Object} initValue Hml text token information.
|
||||
* @param {Object} functionFlag Hml text token information.
|
||||
* @return {String} Compiled data binding
|
||||
*/
|
||||
function transExp(initValue, functionFlag, isValue, out, nodeLoc) {
|
||||
let value = initValue.toString().trim()
|
||||
const hasExpFlag = isExp(value)
|
||||
if (hasExpFlag) {
|
||||
value = parseExp(value, functionFlag, isValue, out, nodeLoc)
|
||||
}
|
||||
return value
|
||||
}
|
||||
/**
|
||||
* parse data binding.
|
||||
* @param {Object} value Hml text token information.
|
||||
* @param {Object} functionFlag Hml text token information.
|
||||
* @return {String} Compiled data binding
|
||||
*/
|
||||
function parseExp(value, functionFlag, isValue, out, nodeLoc) {
|
||||
const textArray = data.parseText(value)
|
||||
const explist = []
|
||||
for (let i = 0; i < textArray.length; i++) {
|
||||
const exp = textArray[i]
|
||||
let transValue
|
||||
if (exp.tag) {
|
||||
if (card) {
|
||||
checkCard(exp.value, out, nodeLoc)
|
||||
}
|
||||
transValue = card ? `{{${transCardArray(exp.value)}}}` : content.parseExpression(exp.value)
|
||||
if (textArray.length !== 1 && !card) {
|
||||
transValue = `(${transValue})`
|
||||
}
|
||||
} else {
|
||||
transValue = card ? exp.value : `decodeURI('${encodeURI(exp.value).replace(/\'/g, '%27')}')`
|
||||
}
|
||||
explist.push(transValue)
|
||||
}
|
||||
if (card && checkCardVersionLimit() && isValue) {
|
||||
if (explist.length > 1) {
|
||||
out.log.push({
|
||||
line: nodeLoc.line || 1,
|
||||
column: nodeLoc.col || 1,
|
||||
reason: 'ERROR: The variable concatenation is not supported in card (supproted later).',
|
||||
})
|
||||
}
|
||||
}
|
||||
let func = explist.join(card ? '' : ' + ')
|
||||
if (functionFlag !== false && !card) {
|
||||
func = eval('(function () {return ' + func + '})')
|
||||
}
|
||||
func = card && textArray.length > 1 ? '$f(' + func + ')' : func
|
||||
|
||||
return func
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is data binding in the list.
|
||||
* @param {String} initValue Hml text token information.
|
||||
* @return {String} Compiled data binding in list
|
||||
*/
|
||||
function transExpForList(initValue) {
|
||||
let value = initValue.toString().trim()
|
||||
const hasExpListFlag = containExp(value)
|
||||
if (hasExpListFlag) {
|
||||
value = parseExpList(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
/**
|
||||
* parse data binding in list.
|
||||
* @param {String} value Hml text token information.
|
||||
* @return {String} Compiled data binding in list
|
||||
*/
|
||||
function parseExpList(value) {
|
||||
const exprMatch = value.match(/{{{([\s\S]+?)}}}|{{([\s\S]+?)}}/g)
|
||||
const exprArray = value.replace(/{{{([\s\S]+?)}}}|{{([\s\S]+?)}}/g, '&e').split(/\s+/)
|
||||
let n = 0
|
||||
const result = []
|
||||
exprArray.forEach((item)=>{
|
||||
if (item.indexOf('&e') >= 0) {
|
||||
while (item.indexOf('&e') >= 0) {
|
||||
item = item.replace('&e', exprMatch[n++])
|
||||
}
|
||||
const textArray = data.parseText(item)
|
||||
const exprlist = []
|
||||
if (textArray) {
|
||||
textArray.forEach(function(text) {
|
||||
const transValue = text.tag ?
|
||||
card ? `{{${text.value}}}` : content.parseExpression(text.value) :
|
||||
card ? text.value : `'${text.value}'`
|
||||
exprlist.push(transValue)
|
||||
})
|
||||
result.push(exprlist.join('+'))
|
||||
}
|
||||
} else {
|
||||
const value = card ? item : `'${item}'`
|
||||
result.push(value)
|
||||
}
|
||||
})
|
||||
|
||||
return card ? result : "(function () {return [" + result.join(", ") + "]})"
|
||||
}
|
||||
|
||||
/**
|
||||
* Regexp determine whether there is data binding.
|
||||
* @param {String} value expression value.
|
||||
* @return {Boolean} Test results
|
||||
*/
|
||||
function isExp(value) {
|
||||
const REGEXP_DATABIND = /{{{([\s\S]+?)}}}|{{([\s\S]+?)}}/
|
||||
return REGEXP_DATABIND.test(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Global regexp determine whether there is data binding.
|
||||
* @param {String} value expression value.
|
||||
* @return {Boolean} Test results
|
||||
*/
|
||||
function containExp(value) {
|
||||
const REGEXP_DATABIND_ALL = /{{{([\s\S]+?)}}}|{{([\s\S]+?)}}/g
|
||||
return REGEXP_DATABIND_ALL.test(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace value on match.
|
||||
* @param {String} value expression value.
|
||||
* @return {String} The result after replacement
|
||||
*/
|
||||
function removeAllExpFix(value) {
|
||||
const REGEXP_PRE_DATABIND = /\{\{\{?|\}\}\}?/g
|
||||
return containExp(value) ? value.replace(REGEXP_PRE_DATABIND, '') : value
|
||||
}
|
||||
|
||||
/**
|
||||
* Change array format in card
|
||||
* @param {String} value Array in card
|
||||
* @return {String} The card array format
|
||||
*/
|
||||
function transCardArray(value) {
|
||||
value = value.replace(REG_CARD_ARRAY, item => {
|
||||
return `.${item.slice(2, -2)}.`
|
||||
})
|
||||
if (value.charAt(value.length - 1) === '.') {
|
||||
value = value.slice(0, -1)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
function checkCard(value, out, nodeLoc) {
|
||||
if (!checkApi(value) && !checkIdxAndItem(value)) {
|
||||
if (checkCardVersionLimit() && !checkVariable(value)){
|
||||
out.log.push({
|
||||
line: nodeLoc.line || 1,
|
||||
column: nodeLoc.col || 1,
|
||||
reason: `ERROR: The expression '${value}' is not supported in card (only support a single variable in the verion).`
|
||||
})
|
||||
} else if (!checkCardVersionLimit() && !checkExpression(value)) {
|
||||
out.log.push({
|
||||
line: nodeLoc.line || 1,
|
||||
column: nodeLoc.col || 1,
|
||||
reason: `ERROR: The expression '${value}' is not supported in card (only support the binocular expression, ` +
|
||||
`OR expression, AND expression and NOT expression).`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkCardVersionLimit() {
|
||||
return parseInt(process.env.PLATFORM_VERSION.replace('Version', '')) < 6
|
||||
}
|
||||
|
||||
function checkApi(value) {
|
||||
return /^\$(tc|t|r)/m.test(value)
|
||||
}
|
||||
|
||||
function checkExpression(value) {
|
||||
return checkVariable(value) || checkOR(value) || checkAND(value) || checkNOT(value) || checkBinocular(value)
|
||||
}
|
||||
|
||||
function checkIdxAndItem(value) {
|
||||
return value === '$idx' || value === '$item'
|
||||
}
|
||||
|
||||
function checkVariable(value) {
|
||||
return /^[a-zA-Z\$_][a-zA-Z\d_\.\[\]'"`\s]*$/.test(value)
|
||||
}
|
||||
|
||||
function checkOR(value) {
|
||||
return /^[a-zA-Z\$_][a-zA-Z\d_\.\[\]'"`\s]*\|\|[a-zA-Z\$_\s][a-zA-Z\d_\.\[\]'"`\s]*$/m.test(value)
|
||||
}
|
||||
|
||||
function checkAND(value) {
|
||||
return /^[a-zA-Z\$_][a-zA-Z\d_\.\[\]'"`\s]*&&[a-zA-Z\$_\s][a-zA-Z\d_\.\[\]'"`\s]*$/m.test(value)
|
||||
}
|
||||
|
||||
function checkNOT(value) {
|
||||
return /^![a-zA-Z\$_][a-zA-Z\d_\.\[\]'"`\s]*$/m.test(value)
|
||||
}
|
||||
|
||||
function checkBinocular(value) {
|
||||
return /^[a-zA-Z\$_][a-zA-Z\d_\.\[\]'"`\s]*\?[a-zA-Z\$_\s][a-zA-Z\d_\.\[\]'"`\s]*:[a-zA-Z\$_\s][a-zA-Z\d_\.\[\]'"`\s]*$/m.test(value)
|
||||
}
|
||||
|
||||
transExp.checkApi = checkApi
|
||||
transExp.checkExpression = checkExpression
|
||||
transExp.checkIdxAndItem = checkIdxAndItem
|
||||
transExp.checkVariable = checkVariable
|
||||
transExp.checkAND = checkAND
|
||||
transExp.checkOR = checkOR
|
||||
transExp.checkNOT = checkNOT
|
||||
transExp.isExp = isExp
|
||||
transExp.containExp = containExp
|
||||
transExp.removeAllExpFix = removeAllExpFix
|
||||
transExp.transExpForList = transExpForList
|
||||
transExp.transCardArray = transCardArray
|
||||
module.exports = transExp
|
335
ace-loader/plugin/templater/card_component_map.js
Normal file
335
ace-loader/plugin/templater/card_component_map.js
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var cardNativeTag = {
|
||||
'div': {
|
||||
events: [],
|
||||
attrs: {}
|
||||
},
|
||||
'stack': {
|
||||
events: [],
|
||||
attrs: {}
|
||||
},
|
||||
'image': {
|
||||
alias: ['img'],
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
events: ['error', 'complete'],
|
||||
attrs: {
|
||||
src: {},
|
||||
alt: {}
|
||||
}
|
||||
},
|
||||
'progress': {
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
events: [],
|
||||
attrs: {
|
||||
type: {
|
||||
def: 'horizontal',
|
||||
enum: ['horizontal', 'circular', 'ring', 'scale-ring', 'arc', 'eclipse']
|
||||
},
|
||||
percent: {
|
||||
def: 0,
|
||||
checkFunc: 'number'
|
||||
},
|
||||
secondarypercent: {
|
||||
def: 0,
|
||||
checkFunc: 'number'
|
||||
},
|
||||
clockwise: {
|
||||
def: 'true',
|
||||
enum: ['true', 'false']
|
||||
},
|
||||
},
|
||||
},
|
||||
'text': {
|
||||
textContent: true,
|
||||
events: [],
|
||||
children: ['span'],
|
||||
attrs: {}
|
||||
},
|
||||
'span': {
|
||||
textContent: true,
|
||||
excludeRoot: true,
|
||||
parents: ['text', 'span'],
|
||||
events: [],
|
||||
children: ['span'],
|
||||
attrs: {},
|
||||
},
|
||||
'chart': {
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
events: [],
|
||||
attrs: {
|
||||
type: {
|
||||
def: 'line',
|
||||
enum: ['line', 'bar', 'gauge', 'progress', 'loading', 'rainbow'],
|
||||
required: true
|
||||
},
|
||||
options: {},
|
||||
datasets: {},
|
||||
percent: {
|
||||
def: 0,
|
||||
checkFunc: 'number'
|
||||
},
|
||||
segments: {},
|
||||
effects: {
|
||||
def: 'true',
|
||||
enum: ['true', 'false']
|
||||
},
|
||||
}
|
||||
},
|
||||
'button': {
|
||||
textContent: true,
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
attrs: {
|
||||
type: {
|
||||
enum: ['capsule', 'circle', 'text', 'arc']
|
||||
},
|
||||
value: {},
|
||||
icon: {},
|
||||
waiting: {
|
||||
def: 'false',
|
||||
enum: ['false', 'true']
|
||||
},
|
||||
placement: {
|
||||
def: 'end',
|
||||
enum: ['end', 'start', 'top', 'bottom'],
|
||||
},
|
||||
}
|
||||
},
|
||||
'badge': {
|
||||
attrs: {
|
||||
placement: {
|
||||
def: 'rightTop',
|
||||
enum: ['rightTop', 'right', 'left']
|
||||
},
|
||||
count: {
|
||||
def: 0,
|
||||
checkFunc: 'number'
|
||||
},
|
||||
visible: {
|
||||
def: 'false',
|
||||
enum: ["false", "true"]
|
||||
},
|
||||
maxcount: {
|
||||
def: 99,
|
||||
checkFunc: 'number',
|
||||
},
|
||||
config: {},
|
||||
},
|
||||
},
|
||||
'list': {
|
||||
children: ['list-item'],
|
||||
attrs: {
|
||||
cachedcount: {
|
||||
def: 0,
|
||||
checkFunc: 'number',
|
||||
},
|
||||
scrollbar: {
|
||||
def: 'off',
|
||||
enum: ['off', 'auto', 'on'],
|
||||
},
|
||||
scrolleffect: {
|
||||
def: 'spring',
|
||||
enum: ['spring', 'fade', 'no'],
|
||||
},
|
||||
divider: {
|
||||
def: 'false',
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
shapemode: {
|
||||
def: 'default',
|
||||
enum: ['default', 'rect', 'round'],
|
||||
},
|
||||
updateeffect: {
|
||||
def: 'false',
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
initialindex: {
|
||||
def: 0,
|
||||
checkFunc: 'number',
|
||||
},
|
||||
initialoffset: {
|
||||
def: 0,
|
||||
checkFunc: 'length',
|
||||
},
|
||||
selected: {}
|
||||
},
|
||||
},
|
||||
'list-item': {
|
||||
excludeRoot: true,
|
||||
parents: ['list'],
|
||||
attrs: {
|
||||
for: {},
|
||||
type: {
|
||||
def: 'default',
|
||||
},
|
||||
section: {},
|
||||
sticky: {
|
||||
def: 'none',
|
||||
enum: ['none', 'normal', 'opacity'],
|
||||
},
|
||||
},
|
||||
},
|
||||
'block': {
|
||||
excludeRoot: true,
|
||||
attrs: {},
|
||||
},
|
||||
'swiper': {
|
||||
unSupportedChildren: ['list'],
|
||||
attrs: {
|
||||
indicator: {
|
||||
def: 'true',
|
||||
enum: ['true', 'false'],
|
||||
},
|
||||
index: {
|
||||
def: 0,
|
||||
checkFunc: 'number',
|
||||
},
|
||||
duration: {
|
||||
checkFunc: 'number',
|
||||
},
|
||||
vertical: {
|
||||
def: 'false',
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
digital: {
|
||||
def: 'false',
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
loop: {
|
||||
def: 'true',
|
||||
enum: ['true', 'false'],
|
||||
},
|
||||
animationopacity: {
|
||||
def: 'true',
|
||||
enum: ['true', 'false'],
|
||||
}
|
||||
},
|
||||
},
|
||||
'calendar': {
|
||||
atomic: true,
|
||||
events: [
|
||||
'selectedchange',
|
||||
'requestdata'
|
||||
],
|
||||
attrs: {
|
||||
date: {},
|
||||
cardcalendar: {
|
||||
def: 'false',
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
startdayofweek: {
|
||||
def: 6,
|
||||
},
|
||||
offdays: {},
|
||||
calendardata: {},
|
||||
showholiday: {
|
||||
def: 'true',
|
||||
enum: ['true', 'false'],
|
||||
},
|
||||
},
|
||||
},
|
||||
'clock': {
|
||||
atomic: true,
|
||||
attrs: {
|
||||
clockconfig: {
|
||||
required: true
|
||||
},
|
||||
showdigit: {
|
||||
def: 'true',
|
||||
enum: ['true', 'false'],
|
||||
},
|
||||
hourswest: {
|
||||
checkFunc: 'number',
|
||||
},
|
||||
},
|
||||
},
|
||||
'divider': {
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
attrs: {
|
||||
vertical: {
|
||||
def: 'false',
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
},
|
||||
},
|
||||
'input': {
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
events: ['change'],
|
||||
attrs: {
|
||||
checked: {
|
||||
def: 'false',
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
type: {
|
||||
def: 'radio',
|
||||
enum: ['radio'],
|
||||
required: true,
|
||||
},
|
||||
name: {},
|
||||
value: {},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var cardCommonTag = {
|
||||
'events': [
|
||||
'click'
|
||||
],
|
||||
'attrs': {
|
||||
id: {},
|
||||
style: {},
|
||||
class: {},
|
||||
disabled: {
|
||||
def: 'false',
|
||||
enum: ['false', 'true']
|
||||
},
|
||||
if: {
|
||||
excludeRoot: true,
|
||||
def: 'true'
|
||||
},
|
||||
elif: {
|
||||
def: 'true'
|
||||
},
|
||||
else: {
|
||||
excludeRoot: true
|
||||
},
|
||||
show: {
|
||||
excludeRoot: true,
|
||||
def: 'true'
|
||||
},
|
||||
accessibilitygroup: {
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
accessibilitytext: {},
|
||||
accessibilitydescription: {},
|
||||
accessibilityimportance: {
|
||||
enum: ['auto', 'yes', 'no', 'no-hide-descendants'],
|
||||
},
|
||||
},
|
||||
'children': ['block', 'slot'],
|
||||
'parents': ['block']
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
cardCommonTag: cardCommonTag,
|
||||
cardNativeTag: cardNativeTag
|
||||
}
|
1291
ace-loader/plugin/templater/component_validator.js
Normal file
1291
ace-loader/plugin/templater/component_validator.js
Normal file
File diff suppressed because it is too large
Load Diff
95
ace-loader/plugin/templater/content.js
Normal file
95
ace-loader/plugin/templater/content.js
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var parser = require("@babel/parser")
|
||||
var traverse = require("@babel/traverse").default
|
||||
var generate = require("@babel/generator").default
|
||||
|
||||
function parseExpression(expression, isEventFunc) {
|
||||
const keyWordsReg = new RegExp(`^(NaN\\b|isNaN\\b|isFinite\\b|decodeURI\\b|decodeURIComponent\\b|Math\\b|Date\\b|this\\b|true\\b|false\\b|
|
||||
encodeURI\\b|encodeURIComponent\\b|parseInt\\b|parseFloat\\b|null\\b|undefined\\b|Infinity\\b)`, 'g')
|
||||
const internalKeyWords = new RegExp(`^(var\\b|while\\b|with\\b|yield\\b|enum\\b|await\\b|implements\\b|package\\b|for\\b|function\\b|if\\b|import\\b|
|
||||
protected\\b|static\\b|interface\\b|private\\b|public\\b|break\\b|case\\b|class\\b|catch\\b|const\\b|continue\\b|debugger\\b|
|
||||
default\\b|delete\\b|do\\b|else\\b|export\\b|extends\\b|finally\\b|in\\b|instanceof\\b|let\\b|return\\b|super\\b|switch\\b|throw\\b|try\\b)`, 'g')
|
||||
const reservedKeyWords = new RegExp(`^(var\\b|while\\b|with\\b|yield\\b|enum\\b|await\\b|implements\\b|package\\b|for\\b|function\\b|if\\b|import\\b|
|
||||
protected\\b|static\\b|interface\\b|private\\b|public\\b|break\\b|case\\b|class\\b|catch\\b|const\\b|continue\\b|debugger\\b|
|
||||
default\\b|delete\\b|do\\b|else\\b|export\\b|extends\\b|finally\\b|in\\b|instanceof\\b|let\\b|return\\b|super\\b|switch\\b|throw\\b|try\\b|show\\b|tid\\b)$`, 'g')
|
||||
try {
|
||||
if (reservedKeyWords.test(expression)) {
|
||||
throw Error("A data binding parsing error occurred. Do not use the reserved:" + expression).message
|
||||
}
|
||||
let expAst = isEventFunc ? parser.parse('(' + expression + ')') : parser.parse(expression)
|
||||
traverse(expAst, {
|
||||
enter(path) {
|
||||
if (path.parent && path.node.type === "Identifier") {
|
||||
let flag = false
|
||||
if (['ConditionalExpression', 'BinaryExpression'].includes(path.parent.type) ||
|
||||
path.parent.type === 'CallExpression' && path.parent.callee === path.node) {
|
||||
flag = true
|
||||
}
|
||||
else if (path.parent.type === "ObjectProperty" && !path.parent.computed && path.parent.value === path.node) {
|
||||
flag = true
|
||||
}
|
||||
else {
|
||||
flag = addPrefix(path.node, path.parent)
|
||||
}
|
||||
if (flag && !keyWordsReg.test(path.node.name)) {
|
||||
path.node.name = 'this.' + path.node.name
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return generate(expAst, { compact: true }).code.replace(';', '').replace(/\"/g, '\'').replace(/\n/g, '')
|
||||
} catch (e) {
|
||||
if (isEventFunc) {
|
||||
throw internalKeyWords.test(expression) ? Error("An event parsing error occurred. Do not use the reserved:" + expression).message :
|
||||
Error("An event parsing error occurred:" + expression).message
|
||||
} else {
|
||||
throw internalKeyWords.test(expression) ? Error("A data binding parsing error occurred. Do not use the reserved:" + expression).message :
|
||||
Error("A data binding parsing error occurred:" + expression).message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addPrefix(node, parent) {
|
||||
const attrArr1 = ['expression', 'argument', 'expressions', 'elements', 'left', 'right']
|
||||
const attrArr2 = ['object', 'property', 'id', 'key']
|
||||
let keyArr = Object.keys(parent)
|
||||
for (let i = 0; i < attrArr1.length; i++) {
|
||||
if (keyArr.includes(attrArr1[i])) {
|
||||
if (parent[attrArr1[i]] === node || ['expressions', 'elements'].includes(attrArr1[i]) &&
|
||||
parent[attrArr1[i]].includes(node)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < attrArr2.length; i++) {
|
||||
if (keyArr.includes(attrArr2[i])) {
|
||||
if (parent.computed && parent[attrArr2[i]] === node) {
|
||||
return true
|
||||
} else {
|
||||
if (parent.type === "Property" && parent.key.range[0] === parent.value.range[0] &&
|
||||
parent.key.range[1] === parent.value.range[1]) {
|
||||
node.name = node.name + ":this." + node.name
|
||||
} else if (parent.object === node) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
exports.parseExpression = parseExpression
|
67
ace-loader/plugin/templater/data.js
Normal file
67
ace-loader/plugin/templater/data.js
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const reg = '{{{((.|\n)+?)}}}|{{((.|\n)+?)}}'
|
||||
const dataReg = new RegExp(reg, 'g')
|
||||
const expressionReg = new RegExp(reg)
|
||||
|
||||
/**
|
||||
* Parse expression in hml text
|
||||
*/
|
||||
function parseData(v) {
|
||||
v.match(dataReg).forEach(element => {
|
||||
const repElement = element.toString().trim().replace(/\n/g, '')
|
||||
v = v.replace(element, repElement)
|
||||
})
|
||||
|
||||
if (!expressionReg.test(v)) {
|
||||
return null
|
||||
}
|
||||
let start
|
||||
let next = 0
|
||||
const res = []
|
||||
dataReg.lastIndex = 0
|
||||
for (let i = next; i < v.length; i++) {
|
||||
let match = dataReg.exec(v)
|
||||
if (!match) {
|
||||
break
|
||||
}
|
||||
start = match.index
|
||||
getValue(next, start, v, res)
|
||||
parseValue(match, res)
|
||||
next = start + match[0].length
|
||||
}
|
||||
getValue(next, v.length, v, res)
|
||||
return res
|
||||
}
|
||||
|
||||
function getValue(begin, end, v, res) {
|
||||
if (begin < end) {
|
||||
res.push({
|
||||
value: v.slice(begin, end)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function parseValue(match, res) {
|
||||
let three= /^{{{.*}}}$/.test(match[0])
|
||||
let v = three ? match[1] : match[3]
|
||||
res.push({
|
||||
tag: true,
|
||||
value: v.trim()
|
||||
})
|
||||
}
|
||||
|
||||
exports.parseText = parseData
|
298
ace-loader/plugin/templater/index.js
Normal file
298
ace-loader/plugin/templater/index.js
Normal file
@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const componentValidator = require('./component_validator')
|
||||
const Parser = require('../parse/parser/index')
|
||||
const path = require('path')
|
||||
let compileResult
|
||||
const EVENT_START_REGEXP = /^(on:|on|@|grab:)/
|
||||
const REGEXP_TEXT = /^#/
|
||||
const REGEXP_DATA = /^data-/
|
||||
|
||||
/**
|
||||
* Compile html file into ast object.
|
||||
* @param {String} source Hml file content.
|
||||
* @param {Function} operate The second number.
|
||||
* @param {String} filePath File resource path.
|
||||
*/
|
||||
function parse(source, operate, filePath) {
|
||||
const pathParse = path.parse(filePath)
|
||||
let relativePath = pathParse.dir.replace(process.env.aceModuleRoot ||
|
||||
process.cwd(), '') + '/' + pathParse.base.replace(pathParse.ext, '')
|
||||
relativePath = replaceAll(path.sep, '/', relativePath).replace('/', '')
|
||||
const result = { jsonTemplate: {}, deps: [], log: [] }
|
||||
compileResult = result
|
||||
const template = hmlParse(source, {
|
||||
sourceCodeLocationInfo: true,
|
||||
})
|
||||
if (checkNullNode(template, operate) || checkRootNode(template, operate, relativePath)) {
|
||||
return
|
||||
}
|
||||
const rootArray = template.childNodes.filter(function(currentValue) {
|
||||
return currentValue.nodeName.indexOf('#') === -1
|
||||
})
|
||||
let rootIndex = 0
|
||||
rootArray.forEach((root, index) => {
|
||||
if(root.tagName !== 'element') {
|
||||
rootIndex = index
|
||||
}
|
||||
})
|
||||
generate(rootArray[rootIndex], filePath, undefined, relativePath)
|
||||
operate(null, compileResult)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use parse5 to get html conversion results.
|
||||
* @param {String} code Hml file content.
|
||||
* @param {Object} config parse5 parseFragment function config.
|
||||
* @return {Object} html conversion results.
|
||||
*/
|
||||
function hmlParse(code, config) {
|
||||
const parse = new Parser({ sourceCodeLocationInfo: true, componentValidator, compileResult })
|
||||
const res = parse.parseFragment(code, config)
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the hml file does not contain nodes.
|
||||
* @param {String} template hml conversion results.
|
||||
* @return {Boolean} Check result.
|
||||
*/
|
||||
function checkNullNode(template, operate) {
|
||||
let errorFlag = false
|
||||
if (template.childNodes.length === 0) {
|
||||
compileResult.log.push({ reason: 'ERROR: parsing hml file failed' })
|
||||
operate(null, compileResult)
|
||||
errorFlag = true
|
||||
}
|
||||
return errorFlag
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the root node is legal.
|
||||
* @param {String} template hml conversion results.
|
||||
* @return {Boolean} Check result.
|
||||
*/
|
||||
function checkRootNode(template, operate, relativePath) {
|
||||
let errorFlag = false
|
||||
const rootArray = template.childNodes.filter(function(currentValue) {
|
||||
return currentValue.nodeName.indexOf('#') === -1
|
||||
})
|
||||
let rootNum = 0
|
||||
rootArray.forEach(root => {
|
||||
if (root.nodeName !== 'element') {
|
||||
rootNum ++
|
||||
} else if (root.attrs && root.attrs.length) {
|
||||
for (let index = 0; index < root.attrs.length; index++) {
|
||||
const element = root.attrs[index];
|
||||
if (element.name === 'name') {
|
||||
componentValidator.elementNames[relativePath] = componentValidator.elementNames[relativePath] || []
|
||||
componentValidator.elementNames[relativePath].push(element.value)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
if (rootNum !== 1) {
|
||||
if (!rootNum) {
|
||||
compileResult.log.push({
|
||||
reason: 'ERROR: need a legal root node',
|
||||
line: 1,
|
||||
column: 1,
|
||||
})
|
||||
}
|
||||
if (rootNum > 1) {
|
||||
compileResult.log.push({
|
||||
reason: 'ERROR: there can only be one root node',
|
||||
line: 1,
|
||||
column: 1,
|
||||
})
|
||||
}
|
||||
operate(null, compileResult)
|
||||
errorFlag = true
|
||||
}
|
||||
return errorFlag
|
||||
}
|
||||
/**
|
||||
* Recursively parse every node.
|
||||
* @param {Object} node Nodes that need to be resolved.
|
||||
* @param {String} filePath File resource path.
|
||||
* @param {Object} preNode the previous node.
|
||||
*/
|
||||
function generate(node, filePath, preNode, relativePath) {
|
||||
componentValidator.validateTagName(node, compileResult, relativePath)
|
||||
if (node.attrs && node.attrs.length !== 0) {
|
||||
checkNodeAttrs(node, filePath, preNode, relativePath)
|
||||
}
|
||||
if (node.childNodes && node.childNodes.length !== 0) {
|
||||
checkNodeChildren(node, filePath, relativePath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse node properties.
|
||||
* @param {Object} node Nodes that need to be resolved.
|
||||
* @param {String} filePath File resource path.
|
||||
* @param {Object} preNode the previous node.
|
||||
*/
|
||||
function checkNodeAttrs(node, filePath, preNode, relativePath) {
|
||||
const attributes = node.attrs
|
||||
const pos = {
|
||||
line: node.sourceCodeLocation.startLine,
|
||||
col: node.sourceCodeLocation.endLine,
|
||||
}
|
||||
attributes.forEach((attr, index) => {
|
||||
const attrName = attr.name
|
||||
const attrValue = attr.value
|
||||
switch (attrName) {
|
||||
case 'style':
|
||||
componentValidator.validateStyle(attrValue, compileResult, pos, relativePath)
|
||||
break
|
||||
case 'class':
|
||||
componentValidator.validateClass(attrValue, compileResult, pos, relativePath)
|
||||
break
|
||||
case 'id':
|
||||
componentValidator.validateId(attrValue, compileResult, pos, relativePath)
|
||||
break
|
||||
case 'for':
|
||||
checkAttrFor(node, attributes, pos);
|
||||
componentValidator.validateFor(attrValue, compileResult, pos, relativePath)
|
||||
break
|
||||
case 'if':
|
||||
componentValidator.validateIf(attrValue, compileResult, false, pos, relativePath)
|
||||
break
|
||||
case 'elif':
|
||||
componentValidator.validateAttrElif(preNode, attrValue, attributes, index,
|
||||
compileResult, pos, relativePath)
|
||||
break
|
||||
case 'else':
|
||||
componentValidator.validateAttrElse(preNode, compileResult, pos, relativePath)
|
||||
break
|
||||
case 'append':
|
||||
componentValidator.validateAppend(attrValue, compileResult, pos, relativePath)
|
||||
break
|
||||
default:
|
||||
if (EVENT_START_REGEXP.test(attrName)) {
|
||||
componentValidator.validateEvent(attrName, attrValue, compileResult, pos, relativePath)
|
||||
} else if (REGEXP_DATA.test(attrName)) {
|
||||
componentValidator.parseDataAttr(attrName, attrValue, compileResult, pos, relativePath)
|
||||
} else {
|
||||
componentValidator.validateAttr(
|
||||
filePath,
|
||||
attrName,
|
||||
attrValue,
|
||||
compileResult,
|
||||
node.tagName,
|
||||
pos,
|
||||
relativePath
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function checkAttrFor(node, attributes, pos) {
|
||||
if (process.env.DEVICE_LEVEL === 'card') {
|
||||
let tidExists = false
|
||||
let ifExists = false
|
||||
attributes.forEach(element => {
|
||||
if(element.name === 'tid') {
|
||||
tidExists = true
|
||||
}
|
||||
if(element.name === 'if' || element.name === 'elif' || element.name === 'else') {
|
||||
ifExists = true
|
||||
}
|
||||
})
|
||||
if (!tidExists) {
|
||||
compileResult.log.push({
|
||||
line: pos.line || 1,
|
||||
column: pos.col || 1,
|
||||
reason: `WARNING: The 'tid' is recommended to use here.`,
|
||||
})
|
||||
}
|
||||
if (ifExists) {
|
||||
compileResult.log.push({
|
||||
line: pos.line || 1,
|
||||
column: pos.col || 1,
|
||||
reason: `ERROR: The 'for' and 'if' cannot be used in the same node.`,
|
||||
})
|
||||
}
|
||||
let isParentFor = false
|
||||
if (node && node.parentNode && node.parentNode.attrs) {
|
||||
node.parentNode.attrs.forEach(element => {
|
||||
if (element.name === 'for') {
|
||||
isParentFor = true
|
||||
}
|
||||
})
|
||||
}
|
||||
if (isParentFor) {
|
||||
compileResult.log.push({
|
||||
line: pos.line || 1,
|
||||
column: pos.col || 1,
|
||||
reason: `ERROR: The nested 'for' is not support.`,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function replaceAll(find, replace, str) {
|
||||
find = find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||
return str.replace(new RegExp(find, 'g'), replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse node children.
|
||||
* @param {Object} node Nodes that need to be resolved.
|
||||
* @param {String} filePath File resource path.
|
||||
* @param {Object} preNode the previous node.
|
||||
*/
|
||||
function checkNodeChildren(node, filePath, relativePath) {
|
||||
const children = node.childNodes.filter((child) => {
|
||||
return (
|
||||
(child.nodeName === '#text' && child.value.trim()) ||
|
||||
!REGEXP_TEXT.test(child.nodeName)
|
||||
)
|
||||
})
|
||||
const temp=compileResult.jsonTemplate
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i]
|
||||
let preNode
|
||||
if (i > 0) {
|
||||
preNode = children[i - 1]
|
||||
}
|
||||
if (!REGEXP_TEXT.test(child.nodeName)) {
|
||||
compileResult.jsonTemplate={}
|
||||
temp.children=temp.children||[]
|
||||
temp.children.push(compileResult.jsonTemplate)
|
||||
generate(child, filePath, preNode, relativePath)
|
||||
} else {
|
||||
const pos = {
|
||||
line: child.sourceCodeLocation.startLine,
|
||||
col: child.sourceCodeLocation.endLine,
|
||||
}
|
||||
if (node.nodeName === 'option') {
|
||||
componentValidator.validateAttr(filePath, 'content', child.value,
|
||||
compileResult, child.tagName, pos, relativePath)
|
||||
continue
|
||||
}
|
||||
componentValidator.validateAttr(filePath, 'value', child.value,
|
||||
compileResult, child.tagName, pos, relativePath)
|
||||
}
|
||||
}
|
||||
compileResult.jsonTemplate=temp
|
||||
}
|
||||
|
||||
module.exports = { parse: parse }
|
385
ace-loader/plugin/templater/lite_component_map.js
Normal file
385
ace-loader/plugin/templater/lite_component_map.js
Normal file
@ -0,0 +1,385 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const isType = require('../lite/lite-utils');
|
||||
const rulePath = process.env.RULE_PATH;
|
||||
const smartvisionTag = {
|
||||
camera: {
|
||||
events: ['error'],
|
||||
},
|
||||
video: {
|
||||
events: [
|
||||
'prepared',
|
||||
'start',
|
||||
'pause',
|
||||
'finish',
|
||||
'error',
|
||||
'seeking',
|
||||
'seeked',
|
||||
'timeupdate',
|
||||
],
|
||||
attrs: {
|
||||
autoplay: {
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
controls: {
|
||||
enum: ['true', 'false'],
|
||||
},
|
||||
muted: {
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
src: { checkPath: true },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const litewearableTag = {
|
||||
'div': {},
|
||||
'canvas': {},
|
||||
'stack': {},
|
||||
'qrcode': {
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
uevents: ['click', 'longpress', 'swipe'],
|
||||
attrs: {
|
||||
value: {
|
||||
required: true,
|
||||
},
|
||||
type: {
|
||||
enum: ['rect', 'circle'],
|
||||
},
|
||||
},
|
||||
},
|
||||
'list': {
|
||||
events: ['scrollend'],
|
||||
children: ['list-item'],
|
||||
},
|
||||
'list-item': {
|
||||
excludeRoot: true,
|
||||
parents: ['list'],
|
||||
},
|
||||
'swiper': {
|
||||
unSupportedChildren: ['list'],
|
||||
events: ['change'],
|
||||
attrs: {
|
||||
index: {
|
||||
checkFunc: 'number',
|
||||
},
|
||||
loop: {
|
||||
enum: ['true', 'false'],
|
||||
},
|
||||
duration: {
|
||||
checkFunc: 'number',
|
||||
},
|
||||
vertical: {
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
},
|
||||
},
|
||||
'tabs': {
|
||||
events: ['change'],
|
||||
children: ['tab-content', 'tab-bar'],
|
||||
},
|
||||
'tab-bar': {
|
||||
parents: ['tabs'],
|
||||
children: ['text'],
|
||||
attrs: {
|
||||
mode: {
|
||||
enum: ['fixed'],
|
||||
},
|
||||
},
|
||||
},
|
||||
'tab-content': {
|
||||
parents: ['tabs'],
|
||||
children: ['div', 'stack'], // to be checked
|
||||
},
|
||||
'image-animator': {
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
events: ['stop'],
|
||||
attrs: {
|
||||
images: {
|
||||
required: true,
|
||||
},
|
||||
iteration: {},
|
||||
reverse: {
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
fixedsize: {
|
||||
enum: ['true', 'false'],
|
||||
},
|
||||
duration: {
|
||||
required: true,
|
||||
},
|
||||
fillmode: {
|
||||
enum: ['none', 'forwards'],
|
||||
},
|
||||
},
|
||||
},
|
||||
'image': {
|
||||
alias: ['img'],
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
attrs: {
|
||||
src: {
|
||||
checkPath: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
'progress': {
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
attrs: {
|
||||
type: {
|
||||
enum: ['horizontal', 'arc'],
|
||||
},
|
||||
percent: {
|
||||
checkFunc: 'number',
|
||||
},
|
||||
},
|
||||
},
|
||||
'text': {
|
||||
atomic: true,
|
||||
textContent: true,
|
||||
attrs: {
|
||||
type: {
|
||||
enum: ['text', 'html'],
|
||||
},
|
||||
value: {},
|
||||
},
|
||||
},
|
||||
'marquee': {
|
||||
atomic: true,
|
||||
attrs: {
|
||||
scrollamount: {
|
||||
def: 6,
|
||||
checkFunc: 'number',
|
||||
},
|
||||
},
|
||||
},
|
||||
'analog-clock': {
|
||||
attrs: {
|
||||
hour: {
|
||||
checkFunc: 'number',
|
||||
},
|
||||
min: {
|
||||
checkFunc: 'number',
|
||||
},
|
||||
sec: {
|
||||
checkFunc: 'number',
|
||||
},
|
||||
},
|
||||
},
|
||||
'clock-hand': {
|
||||
parents: ['analog-clock'],
|
||||
attrs: {
|
||||
type: {
|
||||
enum: ['hour', 'min', 'sec'],
|
||||
},
|
||||
src: {
|
||||
checkPath: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
'chart': {
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
attrs: {
|
||||
type: {
|
||||
enum: ['line', 'bar'],
|
||||
},
|
||||
datasets: {},
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
'input': {
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
events: ['change'],
|
||||
attrs: {
|
||||
checked: {
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
type: {
|
||||
enum: ['button', 'checkbox', 'radio'],
|
||||
},
|
||||
name: {},
|
||||
value: {},
|
||||
},
|
||||
},
|
||||
'slider': {
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
events: ['change'],
|
||||
attrs: {
|
||||
min: {
|
||||
def: 0,
|
||||
checkFunc: 'number',
|
||||
},
|
||||
max: {
|
||||
def: 100,
|
||||
checkFunc: 'number',
|
||||
},
|
||||
value: {
|
||||
def: 0,
|
||||
checkFunc: 'number',
|
||||
},
|
||||
},
|
||||
},
|
||||
'switch': {
|
||||
events: ['change'],
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
attrs: {
|
||||
checked: {
|
||||
enum: ['false', 'true'],
|
||||
},
|
||||
},
|
||||
},
|
||||
'picker-view': {
|
||||
atomic: true,
|
||||
selfClosing: true,
|
||||
uevents: ['change'],
|
||||
attrs: {
|
||||
type: {
|
||||
enum: ['text', 'time'],
|
||||
},
|
||||
range: {},
|
||||
selected: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const liteCommonTag = {
|
||||
events: [
|
||||
'click',
|
||||
'longpress',
|
||||
'touchstart',
|
||||
'touchmove',
|
||||
'touchcancel',
|
||||
'touchend',
|
||||
'key',
|
||||
'swipe',
|
||||
],
|
||||
attrs: {
|
||||
id: {},
|
||||
style: {},
|
||||
class: {},
|
||||
ref: {},
|
||||
if: {
|
||||
excludeRoot: true,
|
||||
def: 'true',
|
||||
},
|
||||
elif: {
|
||||
def: 'true',
|
||||
},
|
||||
else: {
|
||||
excludeRoot: true,
|
||||
},
|
||||
for: {
|
||||
excludeRoot: true,
|
||||
},
|
||||
tid: {},
|
||||
show: {
|
||||
excludeRoot: true,
|
||||
def: 'true',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Rules for adapting to different environments. If it is `liteWearable` device type,
|
||||
* set to this type of verification rule.
|
||||
* @param {String} deviceType device type.
|
||||
* @return {Object} Validation rules.
|
||||
*/
|
||||
function select(deviceType) {
|
||||
tag = {
|
||||
liteWearable: litewearableTag,
|
||||
smartVision: { ...litewearableTag, ...smartvisionTag },
|
||||
};
|
||||
return tag[deviceType];
|
||||
}
|
||||
let liteNativeTag = select(process.env.DEVICE_TYPE);
|
||||
|
||||
/**
|
||||
* Whether the file exists, get customized rules.
|
||||
*/
|
||||
(function checkFile() {
|
||||
if (rulePath) {
|
||||
const customTag = require(rulePath);
|
||||
isExtends(customTag);
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* Get the component types supported by the current verification rule.
|
||||
* @return {Array} Supported component name.
|
||||
*/
|
||||
function getKeys() {
|
||||
const res = [];
|
||||
const keys = Object.keys(liteNativeTag);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
res.push(key);
|
||||
}
|
||||
res.push('attrs');
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* According to user-defined rules, combine into new verification rules.
|
||||
* @param {Object} customTag User-defined rule object.
|
||||
*/
|
||||
function isExtends(customTag) {
|
||||
if (customTag.extends == 'recommended') {
|
||||
const nativekeys = getKeys();
|
||||
merge(liteNativeTag, customTag.rules, nativekeys);
|
||||
} else {
|
||||
liteNativeTag = customTag.rules;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Combine the original rules and user-defined rules.
|
||||
* @param {Object} object Original rules.
|
||||
* @param {Object} source user-defined rules.
|
||||
* @param {Array} nativekeys Supported component name.
|
||||
* @return {Array} Merged object.
|
||||
*/
|
||||
function merge(object, source, nativekeys) {
|
||||
const keys = Object.keys(source);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
const value = source[key];
|
||||
let target = object[key];
|
||||
if (target != null && !nativekeys.includes(key)) {
|
||||
console.error(
|
||||
`\u001b[31mError in .literc.js: \n` +
|
||||
`Attribute '${key}' already exists and cannot be modified\u001b[39m`,
|
||||
);
|
||||
process.exit(1);
|
||||
} else if (isType.isObject(value)) {
|
||||
target = isType.isObject(target) ? target : {};
|
||||
object[key] = merge(target, value, nativekeys);
|
||||
} else if (!(isType.isNull(value) || isType.isUndefined(value))) {
|
||||
object[key] = value;
|
||||
}
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
liteNativeTag: liteNativeTag,
|
||||
liteCommonTag: liteCommonTag,
|
||||
};
|
1638
ace-loader/plugin/templater/rich_component_map.js
Normal file
1638
ace-loader/plugin/templater/rich_component_map.js
Normal file
File diff suppressed because it is too large
Load Diff
452
ace-loader/plugin/theme/customThemeStyles.js
Normal file
452
ace-loader/plugin/theme/customThemeStyles.js
Normal file
@ -0,0 +1,452 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const THEME_PROP_GROUPS = {
|
||||
emui_color_fg: "0",
|
||||
ohos_color_fg: "0",
|
||||
emui_color_fg_inverse: "1",
|
||||
ohos_color_fg_inverse: "1",
|
||||
emui_color_bg: "3",
|
||||
ohos_color_bg: "3",
|
||||
emui_accent: "4",
|
||||
ohos_accent: "4",
|
||||
emui_accent_inverse: "5",
|
||||
ohos_accent_inverse: "5",
|
||||
emui_functional_red: "6",
|
||||
ohos_functional_red: "6",
|
||||
emui_color_warning: "7",
|
||||
ohos_color_warning: "7",
|
||||
emui_color_handup: "8",
|
||||
ohos_color_handup: "8",
|
||||
emui_color_connected: "9",
|
||||
ohos_color_connected: "9",
|
||||
emui_color_control_activated: "50",
|
||||
ohos_color_control_activated: "50",
|
||||
emui_control_normal: "51",
|
||||
ohos_control_normal: "51",
|
||||
emui_color_divider_horizontal: "52",
|
||||
ohos_color_divider_horizontal: "52",
|
||||
emui_color_subheader_divider: "53",
|
||||
ohos_color_subheader_divider: "53",
|
||||
emui_color_click_effect_default: "54",
|
||||
ohos_color_click_effect_default: "54",
|
||||
emui_fab_icon: "124",
|
||||
ohos_fab_icon: "124",
|
||||
emui_fab_bg_normal: "127",
|
||||
ohos_fab_bg_normal: "127",
|
||||
emui_card_bg: "135",
|
||||
ohos_card_bg: "135",
|
||||
emui_color_tooltips_bg: "137",
|
||||
ohos_color_tooltips_bg: "137",
|
||||
emui_activated: "138",
|
||||
ohos_activated: "138",
|
||||
emui_color_primary: "200",
|
||||
ohos_color_primary: "200",
|
||||
emui_primary_inverse: "201",
|
||||
ohos_primary_inverse: "201",
|
||||
emui_color_secondary: "202",
|
||||
ohos_color_secondary: "202",
|
||||
emui_color_tertiary: "203",
|
||||
ohos_color_tertiary: "203",
|
||||
emui_color_text_primary: "250",
|
||||
ohos_color_text_primary: "250",
|
||||
emui_text_primary_inverse: "251",
|
||||
ohos_text_primary_inverse: "251",
|
||||
emui_color_text_secondary: "252",
|
||||
ohos_color_text_secondary: "252",
|
||||
emui_text_secondary_inverse: "253",
|
||||
ohos_text_secondary_inverse: "253",
|
||||
emui_color_text_tertiary: "254",
|
||||
ohos_color_text_tertiary: "254",
|
||||
emui_text_tertiary_inverse: "255",
|
||||
ohos_text_tertiary_inverse: "255",
|
||||
emui_text_color_alert_dialog_list_item: "256",
|
||||
ohos_text_color_alert_dialog_list_item: "256",
|
||||
emui_functional_blue: "257",
|
||||
ohos_functional_blue: "257",
|
||||
emui_text_hint: "258",
|
||||
ohos_text_hint: "258",
|
||||
emui_text_hint_inverse: "259",
|
||||
ohos_text_hint_inverse: "259",
|
||||
emui_functional_blue_inverse: "260",
|
||||
ohos_functional_blue_inverse: "260",
|
||||
emui_color_text_highlight: "261",
|
||||
ohos_color_text_highlight: "261",
|
||||
emui_text_highlight_inverse: "262",
|
||||
ohos_text_highlight_inverse: "262",
|
||||
emui_color_1: "300",
|
||||
ohos_color_1: "300",
|
||||
emui_color_2: "301",
|
||||
ohos_color_2: "301",
|
||||
emui_color_3: "302",
|
||||
ohos_color_3: "302",
|
||||
emui_color_4: "303",
|
||||
ohos_color_4: "303",
|
||||
emui_color_5: "304",
|
||||
ohos_color_5: "304",
|
||||
emui_color_6: "305",
|
||||
ohos_color_6: "305",
|
||||
emui_color_7: "306",
|
||||
ohos_color_7: "306",
|
||||
emui_color_8: "307",
|
||||
ohos_color_8: "307",
|
||||
emui_color_9: "308",
|
||||
ohos_color_9: "308",
|
||||
emui_color_10: "309",
|
||||
ohos_color_10: "309",
|
||||
emui_color_11: "310",
|
||||
ohos_color_11: "310",
|
||||
emui_color_fg_1: "311",
|
||||
ohos_color_fg_1: "311",
|
||||
emui_color_fg_2: "312",
|
||||
ohos_color_fg_2: "312",
|
||||
emui_color_fg_3: "313",
|
||||
ohos_color_fg_3: "313",
|
||||
emui_color_fg_4: "314",
|
||||
ohos_color_fg_4: "314",
|
||||
emui_color_fg_5: "315",
|
||||
ohos_color_fg_5: "315",
|
||||
emui_color_fg_6: "316",
|
||||
ohos_color_fg_6: "316",
|
||||
emui_color_fg_7: "317",
|
||||
ohos_color_fg_7: "317",
|
||||
emui_color_fg_8: "318",
|
||||
ohos_color_fg_8: "318",
|
||||
emui_color_fg_9: "319",
|
||||
ohos_color_fg_9: "319",
|
||||
emui_color_fg_10: "320",
|
||||
ohos_color_fg_10: "320",
|
||||
emui_color_fg_11: "321",
|
||||
ohos_color_fg_11: "321",
|
||||
emui_primary_content_alpha: "400",
|
||||
ohos_primary_content_alpha: "400",
|
||||
emui_secondary_content_alpha: "401",
|
||||
ohos_secondary_content_alpha: "401",
|
||||
emui_tertiary_content_alpha: "402",
|
||||
ohos_tertiary_content_alpha: "402",
|
||||
emui_disabled_alpha: "403",
|
||||
ohos_disabled_alpha: "403",
|
||||
emui_highlight_bg_alpha: "404",
|
||||
ohos_highlight_bg_alpha: "404",
|
||||
emui_normal_bg_alpha: "405",
|
||||
ohos_normal_bg_alpha: "405",
|
||||
emui_tips_bg_alpha: "406",
|
||||
ohos_tips_bg_alpha: "406",
|
||||
emui_divider_alpha: "407",
|
||||
ohos_divider_alpha: "407",
|
||||
emui_text_size_headline1: "500",
|
||||
ohos_text_size_headline1: "500",
|
||||
emui_text_size_headline2: "501",
|
||||
ohos_text_size_headline2: "501",
|
||||
emui_text_size_headline3: "502",
|
||||
ohos_text_size_headline3: "502",
|
||||
emui_text_size_headline4: "503",
|
||||
ohos_text_size_headline4: "503",
|
||||
emui_text_size_headline5: "504",
|
||||
ohos_text_size_headline5: "504",
|
||||
emui_text_size_headline6: "505",
|
||||
ohos_text_size_headline6: "505",
|
||||
emui_text_size_headline7: "506",
|
||||
ohos_text_size_headline7: "506",
|
||||
emui_text_size_headline8: "507",
|
||||
ohos_text_size_headline8: "507",
|
||||
emui_text_size_subtitle1: "508",
|
||||
ohos_text_size_subtitle1: "508",
|
||||
emui_text_size_subtitle2: "509",
|
||||
ohos_text_size_subtitle2: "509",
|
||||
emui_text_size_subtitle3: "510",
|
||||
ohos_text_size_subtitle3: "510",
|
||||
emui_text_size_button1: "511",
|
||||
ohos_text_size_button1: "511",
|
||||
emui_text_size_button2: "512",
|
||||
ohos_text_size_button2: "512",
|
||||
emui_text_size_body1: "513",
|
||||
ohos_text_size_body1: "513",
|
||||
emui_text_size_body2: "514",
|
||||
ohos_text_size_body2: "514",
|
||||
emui_text_size_body3: "515",
|
||||
ohos_text_size_body3: "515",
|
||||
emui_text_size_caption: "516",
|
||||
ohos_text_size_caption: "516",
|
||||
emui_text_size_caption1: "517",
|
||||
ohos_text_size_caption1: "517",
|
||||
emui_text_size_chart1: "518",
|
||||
ohos_text_size_chart1: "518",
|
||||
emui_text_size_chart2: "519",
|
||||
ohos_text_size_chart2: "519",
|
||||
emui_text_size_overline: "520",
|
||||
ohos_text_size_overline: "520",
|
||||
emui_text_font_family_regular: "550",
|
||||
ohos_text_font_family_regular: "550",
|
||||
emui_text_font_family_medium: "551",
|
||||
ohos_text_font_family_medium: "551",
|
||||
emui_corner_radius_notification: "611",
|
||||
ohos_corner_radius_notification: "611",
|
||||
emui_corner_radius_grid: "615",
|
||||
ohos_corner_radius_grid: "615",
|
||||
emui_corner_radius_icon: "619",
|
||||
ohos_corner_radius_icon: "619",
|
||||
emui_corner_radius_large: "650",
|
||||
ohos_corner_radius_large: "650",
|
||||
emui_corner_radius_mediums: "651",
|
||||
ohos_corner_radius_mediums: "651",
|
||||
emui_corner_radius_small: "652",
|
||||
ohos_corner_radius_small: "652",
|
||||
emui_corner_radius_xsmal: "653",
|
||||
ohos_corner_radius_xsmal: "653",
|
||||
emui_dimens_default_start: "700",
|
||||
ohos_dimens_default_start: "700",
|
||||
emui_dimens_max_start: "701",
|
||||
ohos_dimens_max_start: "701",
|
||||
emui_dimens_default_end: "702",
|
||||
ohos_dimens_default_end: "702",
|
||||
emui_dimens_max_end: "703",
|
||||
ohos_dimens_max_end: "703",
|
||||
emui_dimens_default_top: "704",
|
||||
ohos_dimens_default_top: "704",
|
||||
emui_dimens_default_bottom_flexible: "705",
|
||||
ohos_dimens_default_bottom_flexible: "705",
|
||||
emui_dimens_default_bottom_fixed: "706",
|
||||
ohos_dimens_default_bottom_fixed: "706",
|
||||
emui_dimens_card_start: "725",
|
||||
ohos_dimens_card_start: "725",
|
||||
emui_dimens_card_end: "726",
|
||||
ohos_dimens_card_end: "726",
|
||||
emui_dimens_card_middle: "727",
|
||||
ohos_dimens_card_middle: "727",
|
||||
emui_dimens_text_vertical: "740",
|
||||
ohos_dimens_text_vertical: "740",
|
||||
emui_dimens_text_horizontal: "741",
|
||||
ohos_dimens_text_horizontal: "741",
|
||||
emui_dimens_text_margin_primary: "742",
|
||||
ohos_dimens_text_margin_primary: "742",
|
||||
emui_dimens_text_margin_secondary: "743",
|
||||
ohos_dimens_text_margin_secondary: "743",
|
||||
emui_dimens_text_margin_tertiary: "744",
|
||||
ohos_dimens_text_margin_tertiary: "744",
|
||||
emui_dimens_text_margin_fourth: "745",
|
||||
ohos_dimens_text_margin_fourth: "745",
|
||||
emui_dimens_text_margin_fifth: "746",
|
||||
ohos_dimens_text_margin_fifth: "746",
|
||||
emui_dimens_element_vertical_large: "760",
|
||||
ohos_dimens_element_vertical_large: "760",
|
||||
emui_dimens_element_vertical_middle: "761",
|
||||
ohos_dimens_element_vertical_middle: "761",
|
||||
emui_dimens_element_horizontal_large: "762",
|
||||
ohos_dimens_element_horizontal_large: "762",
|
||||
emui_dimens_element_horizontal_middle: "763",
|
||||
ohos_dimens_element_horizontal_middle: "763",
|
||||
emui_text_size_space_short: "780",
|
||||
ohos_text_size_space_short: "780",
|
||||
emui_text_size_space_large: "781",
|
||||
ohos_text_size_space_large: "781",
|
||||
app_background: "900",
|
||||
select_clicked_color: "1000",
|
||||
select_disabled_text_color: "1001",
|
||||
menu_selected_color: "1002",
|
||||
select_font_size: "1003",
|
||||
select_font_color: "1004",
|
||||
select_triangle_icon_size: "1011",
|
||||
menu_background_radius: "1012",
|
||||
menu_min_width: "1015",
|
||||
button_background_color: "1100",
|
||||
button_disabled_color: "1102",
|
||||
button_text_focus_color: "1120",
|
||||
button_text_color: "1121",
|
||||
button_text_disabled_color: "1122",
|
||||
button_text_waiting_color: "1123",
|
||||
button_text_fontsize: "1124",
|
||||
button_text_fontsize_min: "1125",
|
||||
button_text_fontweight: "1126",
|
||||
button_text_max_lines: "1127",
|
||||
button_radius: "1140",
|
||||
button_min_width: "1141",
|
||||
button_height: "1142",
|
||||
button_padding_horizontal: "1143",
|
||||
button_padding_vertical: "1144",
|
||||
checkbox_foreground_color: "1200",
|
||||
checkbox_active_color: "1201",
|
||||
checkbox_inactive_color: "1202",
|
||||
checkbox_size: "1204",
|
||||
checkbox_border_radius: "1206",
|
||||
checkbox_border_width: "1207",
|
||||
checkbox_stroke_width: "1208",
|
||||
radio_foreground_color: "1300",
|
||||
radio_active_color: "1301",
|
||||
radio_inactive_color: "1302",
|
||||
radio_size: "1304",
|
||||
radio_border_width: "1306",
|
||||
switch_foreground_color: "1400",
|
||||
switch_active_color: "1401",
|
||||
switch_inactive_color: "1402",
|
||||
switch_width: "1404",
|
||||
switch_height: "1405",
|
||||
switch_border_width: "1409",
|
||||
marquee_text_color: "1500",
|
||||
marquee_font_size: "1501",
|
||||
progress_color: "1611",
|
||||
progress_secondary_color: "1600",
|
||||
progress_bg_color: "1601",
|
||||
progress_thickness: "1602",
|
||||
progress_loading_color: "1603",
|
||||
progress_scale_length: "1604",
|
||||
progress_scale_width: "1605",
|
||||
progress_scale_number: "1608",
|
||||
rating_width: "1700",
|
||||
rating_height: "1701",
|
||||
rating_indicator_width: "1702",
|
||||
rating_indicator_height: "1703",
|
||||
rating_star_num: "1705",
|
||||
rating_score: "1706",
|
||||
rating_indicator_score: "1707",
|
||||
rating_step_size: "1708",
|
||||
slider_block_color: "1800",
|
||||
slider_track_thickness: "1803",
|
||||
slider_track_selected: "1804",
|
||||
slider_track_bg: "1805",
|
||||
text_size: "1900",
|
||||
dialog_radius: "2000",
|
||||
dialog_background_color: "2001",
|
||||
dialog_title_text_color: "2002",
|
||||
dialog_title_text_fontsize: "2003",
|
||||
dialog_title_text_fontsize_min: "2004",
|
||||
dialog_title_text_fontweight: "2005",
|
||||
dialog_title_text_max_lines: "2006",
|
||||
dialog_content_text_color: "2007",
|
||||
dialog_content_text_fontsize: "2008",
|
||||
dialog_animation_duration_in: "2020",
|
||||
dialog_animation_duration_out: "2021",
|
||||
dialog_content_text_fontsize_min: "2032",
|
||||
popup_padding_horizontal: "2100",
|
||||
popup_padding_vertical: "2101",
|
||||
popup_background_color: "2103",
|
||||
popup_text_color: "2104",
|
||||
popup_text_fontsize: "2105",
|
||||
swiper_indicator_normal_color: "2200",
|
||||
swiper_indicator_selected_color: "2201",
|
||||
swiper_indicator_size: "2202",
|
||||
swiper_indicator_selected_size: "2203",
|
||||
toast_padding_horizontal: "2300",
|
||||
toast_padding_vertical: "2301",
|
||||
toast_background_color: "2304",
|
||||
toast_text_fontweight: "2305",
|
||||
toast_text_color: "2306",
|
||||
toast_text_fontsize: "2307",
|
||||
toast_radius: "2308",
|
||||
textfield_padding_horizontal: "2400",
|
||||
textfield_padding_vertical: "2401",
|
||||
textfield_height: "2402",
|
||||
textfield_font_size: "2403",
|
||||
textfield_font_weight: "2404",
|
||||
textfield_border_radius: "2405",
|
||||
textfield_background_color: "2407",
|
||||
textfield_placeholder_color: "2408",
|
||||
textfield_text_color: "2409",
|
||||
textfield_focus_background_color: "2410",
|
||||
textfield_focus_placeholder_color: "2411",
|
||||
textfield_focus_text_color: "2412",
|
||||
textfield_cursor_color: "2415",
|
||||
textfield_icon_size: "2417",
|
||||
textfield_error_text_color: "2420",
|
||||
textfield_error_border_color: "2424",
|
||||
textfield_text_selected_color: "2425",
|
||||
video_bar_time_text_color: "2615",
|
||||
video_error_text_color: "2616",
|
||||
video_bar_background: "2617",
|
||||
tab_active_indicator_color: "2705",
|
||||
navigation_bar_title_color: "2900",
|
||||
navigation_bar_title_font_size: "2901",
|
||||
navigation_bar_title_font_size_emphasize: "2902",
|
||||
navigation_bar_subtitle_color: "2903",
|
||||
navigation_bar_subtitle_font_size: "2904",
|
||||
navigation_bar_height: "2905",
|
||||
navigation_bar_height_emphasize: "2906",
|
||||
navigation_bar_menu_zone_width: "2909",
|
||||
navigation_bar_menu_icon_width: "2910",
|
||||
navigation_bar_logo_icon_width: "2911",
|
||||
navigation_bar_more_zone_width: "2912",
|
||||
navigation_bar_more_zone_height: "2913",
|
||||
navigation_bar_more_icon_width: "2914",
|
||||
navigation_bar_more_icon_height: "2915",
|
||||
navigation_bar_max_padding_start: "2920",
|
||||
navigation_bar_max_padding_end: "2921",
|
||||
navigation_bar_default_padding_start: "2922",
|
||||
navigation_bar_default_padding_end: "2923",
|
||||
picker_popup_radius: "3002",
|
||||
picker_popup_padding: "3003",
|
||||
picker_button_font_size: "3019",
|
||||
picker_button_text_color: "3020",
|
||||
picker_select_option_font_size: "3021",
|
||||
picker_select_option_text_color: "3022",
|
||||
picker_normal_option_font_size: "3025",
|
||||
picker_normal_option_font_color: "3026",
|
||||
picker_title_font_size: "3028",
|
||||
picker_title_text_color: "3029",
|
||||
scroll_bar_background_color: "3304",
|
||||
scroll_bar_foreground_color: "3305",
|
||||
refresh_default_progress_diameter: "3404",
|
||||
search_icon_size: "3600",
|
||||
search_text_field_padding_left: "3602",
|
||||
search_text_field_radius: "3603",
|
||||
search_text_color: "3605",
|
||||
search_placeholder_color: "3606",
|
||||
search_close_icon_size: "3607",
|
||||
search_font_size: "3610",
|
||||
search_font_weight: "3611",
|
||||
search_focus_text_color: "3613",
|
||||
text_overlay_handle_color: "3718",
|
||||
text_overlay_handle_diameter: "3719",
|
||||
calendar_week_font_size: "3500",
|
||||
calendar_day_font_size : "3501",
|
||||
calendar_lunar_font_size: "3502",
|
||||
calendar_week_color: "3503",
|
||||
calendar_day_color: "3504",
|
||||
calendar_lunar_color: "3505",
|
||||
calendar_weekend_day_color: "3506",
|
||||
calendar_weekend_lunar_color: "3507",
|
||||
calendar_today_day_color: "3508",
|
||||
calendar_today_lunar_color: "3509",
|
||||
calendar_non_current_month_day_color: "3510",
|
||||
calendar_non_current_month_lunar_color: "3511",
|
||||
calendar_work_day_mark_font_size: "3512",
|
||||
calendar_off_day_mark_font_size: "3513",
|
||||
calendar_work_day_mark_color: "3514",
|
||||
calendar_off_day_mark_color: "3515",
|
||||
calendar_not_current_month_work_day_mark_color: "3516",
|
||||
calendar_not_current_month_off_day_mark_color: "3517",
|
||||
calendar_focused_day_color: "3518",
|
||||
calendar_focused_lunar_color: "3519",
|
||||
calendar_focused_area_radius: "3520",
|
||||
calendar_focused_area_background_color: "3521",
|
||||
calendar_top_padding: "3522",
|
||||
calendar_blur_area_background_color : "3523",
|
||||
calendar_col_space: "3524",
|
||||
calendar_week_height: "3525",
|
||||
calendar_day_height: "3526",
|
||||
calendar_week_width: "3527",
|
||||
calendar_day_width: "3528",
|
||||
calendar_week_and_day_row_space: "3529",
|
||||
calendar_daily_five_row_space: "3530",
|
||||
calendar_daily_six_row_space: "3531",
|
||||
calendar_gregorian_calendar_height: "3532",
|
||||
calendar_work_state_width: "3533",
|
||||
theme_calendar_day_font_wight: "3534",
|
||||
theme_calendar_lunar_day_font_wight: "3535",
|
||||
theme_calendar_work_state_font_wight: "3536",
|
||||
theme_calendar_work_state_horizontal_moving_distance: "3566",
|
||||
theme_calendar_work_state_vertical_moving_distance: "3567"
|
||||
};
|
||||
|
||||
module.exports = THEME_PROP_GROUPS;
|
684
ace-loader/plugin/theme/ohosStyles.js
Normal file
684
ace-loader/plugin/theme/ohosStyles.js
Normal file
@ -0,0 +1,684 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const OHOS_THEME_STYLES = {
|
||||
ic_app: '0',
|
||||
request_location_reminder_title: '1',
|
||||
request_location_reminder_content: '2',
|
||||
theme_light: '3',
|
||||
theme_dark: '4',
|
||||
theme_transparent: '5',
|
||||
id_color_foreground: '6',
|
||||
id_color_foreground_dark: '7',
|
||||
id_color_foreground_transparent: '8',
|
||||
id_color_foreground_contrary: '9',
|
||||
id_color_foreground_contrary_dark: '10',
|
||||
id_color_foreground_contrary_transparent: '11',
|
||||
id_color_foreground_contrary_disable: '12',
|
||||
id_color_foreground_contrary_disable_dark: '13',
|
||||
id_color_foreground_contrary_disable_transparent: '14',
|
||||
id_color_background: '15',
|
||||
id_color_background_dark: '16',
|
||||
id_color_background_transparent: '17',
|
||||
id_color_sub_background: '18',
|
||||
id_color_sub_background_dark: '19',
|
||||
id_color_sub_background_transparent: '20',
|
||||
id_color_emphasize: '21',
|
||||
id_color_emphasize_dark: '22',
|
||||
id_color_emphasize_transparent: '23',
|
||||
id_color_emphasize_contrary: '24',
|
||||
id_color_emphasize_contrary_dark: '25',
|
||||
id_color_emphasize_contrary_transparent: '26',
|
||||
id_color_alert: '27',
|
||||
id_color_alert_dark: '28',
|
||||
id_color_alert_transparent: '29',
|
||||
id_color_warning: '30',
|
||||
id_color_warning_dark: '31',
|
||||
id_color_warning_transparent: '32',
|
||||
id_color_handup: '33',
|
||||
id_color_handup_dark: '34',
|
||||
id_color_handup_transparent: '35',
|
||||
id_color_connected: '36',
|
||||
id_color_connected_dark: '37',
|
||||
id_color_connected_transparent: '38',
|
||||
id_color_component_activated: '39',
|
||||
id_color_component_activated_dark: '40',
|
||||
id_color_component_activated_transparent: '41',
|
||||
id_color_component_normal: '42',
|
||||
id_color_component_normal_dark: '43',
|
||||
id_color_component_normal_transparent: '44',
|
||||
id_color_list_separator: '45',
|
||||
id_color_list_separator_dark: '46',
|
||||
id_color_list_separator_transparent: '47',
|
||||
id_color_subheading_separator: '48',
|
||||
id_color_subheading_separator_dark: '49',
|
||||
id_color_subheading_separator_transparent: '50',
|
||||
id_color_click_effect: '51',
|
||||
id_color_click_effect_dark: '52',
|
||||
id_color_click_effect_transparent: '53',
|
||||
id_color_hover: '54',
|
||||
id_color_hover_dark: '55',
|
||||
id_color_hover_transparent: '56',
|
||||
id_color_focused_content_primary: '57',
|
||||
id_color_focused_content_primary_dark: '58',
|
||||
id_color_focused_content_primary_transparent: '59',
|
||||
id_color_focused_content_second: '60',
|
||||
id_color_focused_content_second_dark: '61',
|
||||
id_color_focused_content_second_transparent: '62',
|
||||
id_color_focused_content_tertiary: '63',
|
||||
id_color_focused_content_tertiary_dark: '64',
|
||||
id_color_focused_content_tertiary_transparent: '65',
|
||||
id_color_focused_outline: '66',
|
||||
id_color_focused_outline_dark: '67',
|
||||
id_color_focused_outline_transparent: '68',
|
||||
id_color_focused_bg: '69',
|
||||
id_color_focused_bg_dark: '70',
|
||||
id_color_focused_bg_transparent: '71',
|
||||
id_color_primary: '72',
|
||||
id_color_primary_dark: '73',
|
||||
id_color_primary_transparent: '74',
|
||||
id_color_primary_contrary: '75',
|
||||
id_color_primary_contrary_dark: '76',
|
||||
id_color_primary_contrary_transparent: '77',
|
||||
id_color_secondary: '78',
|
||||
id_color_secondary_dark: '79',
|
||||
id_color_secondary_transparent: '80',
|
||||
id_color_tertiary: '81',
|
||||
id_color_tertiary_dark: '82',
|
||||
id_color_tertiary_transparent: '83',
|
||||
id_color_fourth: '84',
|
||||
id_color_fourth_dark: '85',
|
||||
id_color_fourth_transparent: '86',
|
||||
id_color_activated: '87',
|
||||
id_color_activated_dark: '88',
|
||||
id_color_activated_transparent: '89',
|
||||
id_color_activated_start: '90',
|
||||
id_color_activated_start_dark: '91',
|
||||
id_color_activated_start_transparent: '92',
|
||||
id_color_activated_end: '93',
|
||||
id_color_activated_end_dark: '94',
|
||||
id_color_activated_end_transparent: '95',
|
||||
id_color_text_primary: '96',
|
||||
id_color_text_primary_dark: '97',
|
||||
id_color_text_primary_transparent: '98',
|
||||
id_color_text_primary_contrary: '99',
|
||||
id_color_text_primary_contrary_dark: '100',
|
||||
id_color_text_primary_contrary_transparent: '101',
|
||||
id_color_text_secondary: '102',
|
||||
id_color_text_secondary_dark: '103',
|
||||
id_color_text_secondary_transparent: '104',
|
||||
id_color_text_secondary_contrary: '105',
|
||||
id_color_text_secondary_contrary_dark: '106',
|
||||
id_color_text_secondary_contrary_transparent: '107',
|
||||
id_color_text_tertiary: '108',
|
||||
id_color_text_tertiary_dark: '109',
|
||||
id_color_text_tertiary_transparent: '110',
|
||||
id_color_text_tertiary_contrary: '111',
|
||||
id_color_text_tertiary_contrary_dark: '112',
|
||||
id_color_text_tertiary_contrary_transparent: '113',
|
||||
id_color_text_primary_activated: '114',
|
||||
id_color_text_primary_activated_dark: '115',
|
||||
id_color_text_primary_activated_transparent: '116',
|
||||
id_color_text_secondary_activated: '117',
|
||||
id_color_text_secondary_activated_dark: '118',
|
||||
id_color_text_secondary_activated_transparent: '119',
|
||||
id_color_text_search_url: '120',
|
||||
id_color_text_search_url_dark: '121',
|
||||
id_color_text_search_url_transparent: '122',
|
||||
id_color_text_hint: '123',
|
||||
id_color_text_hint_dark: '124',
|
||||
id_color_text_hint_transparent: '125',
|
||||
id_color_text_hint_contrary: '126',
|
||||
id_color_text_hint_contrary_dark: '127',
|
||||
id_color_text_hint_contrary_transparent: '128',
|
||||
id_color_text_hyperlink: '129',
|
||||
id_color_text_hyperlink_dark: '130',
|
||||
id_color_text_hyperlink_transparent: '131',
|
||||
id_color_text_hyperlink_contrary: '132',
|
||||
id_color_text_hyperlink_contrary_dark: '133',
|
||||
id_color_text_hyperlink_contrary_transparent: '134',
|
||||
id_color_text_highlight_bg: '135',
|
||||
id_color_text_highlight_bg_dark: '136',
|
||||
id_color_text_highlight_bg_transparent: '137',
|
||||
id_color_text_highlight_bg_contrary: '138',
|
||||
id_color_text_highlight_bg_contrary_dark: '139',
|
||||
id_color_text_highlight_bg_contrary_transparent: '140',
|
||||
id_color_palette1: '141',
|
||||
id_color_palette1_dark: '142',
|
||||
id_color_palette1_transparent: '143',
|
||||
id_color_palette2: '144',
|
||||
id_color_palette2_dark: '145',
|
||||
id_color_palette2_transparent: '146',
|
||||
id_color_palette3: '147',
|
||||
id_color_palette3_dark: '148',
|
||||
id_color_palette3_transparent: '149',
|
||||
id_color_palette4: '150',
|
||||
id_color_palette4_dark: '151',
|
||||
id_color_palette4_transparent: '152',
|
||||
id_color_palette5: '153',
|
||||
id_color_palette5_dark: '154',
|
||||
id_color_palette5_transparent: '155',
|
||||
id_color_palette6: '156',
|
||||
id_color_palette6_dark: '157',
|
||||
id_color_palette6_transparent: '158',
|
||||
id_color_palette7: '159',
|
||||
id_color_palette7_dark: '160',
|
||||
id_color_palette7_transparent: '161',
|
||||
id_color_palette8: '162',
|
||||
id_color_palette8_dark: '163',
|
||||
id_color_palette8_transparent: '164',
|
||||
id_color_palette9: '165',
|
||||
id_color_palette9_dark: '166',
|
||||
id_color_palette9_transparent: '167',
|
||||
id_color_palette10: '168',
|
||||
id_color_palette10_dark: '169',
|
||||
id_color_palette10_transparent: '170',
|
||||
id_color_palette11: '171',
|
||||
id_color_palette11_dark: '172',
|
||||
id_color_palette11_transparent: '173',
|
||||
id_color_palette_aux1: '174',
|
||||
id_color_palette_aux1_dark: '175',
|
||||
id_color_palette_aux1_transparent: '176',
|
||||
id_color_palette_aux2: '177',
|
||||
id_color_palette_aux2_dark: '178',
|
||||
id_color_palette_aux2_transparent: '179',
|
||||
id_color_palette_aux3: '180',
|
||||
id_color_palette_aux3_dark: '181',
|
||||
id_color_palette_aux3_transparent: '182',
|
||||
id_color_palette_aux4: '183',
|
||||
id_color_palette_aux4_dark: '184',
|
||||
id_color_palette_aux4_transparent: '185',
|
||||
id_color_palette_aux5: '186',
|
||||
id_color_palette_aux5_dark: '187',
|
||||
id_color_palette_aux5_transparent: '188',
|
||||
id_color_palette_aux6: '189',
|
||||
id_color_palette_aux6_dark: '190',
|
||||
id_color_palette_aux6_transparent: '191',
|
||||
id_color_palette_aux7: '192',
|
||||
id_color_palette_aux7_dark: '193',
|
||||
id_color_palette_aux7_transparent: '194',
|
||||
id_color_palette_aux8: '195',
|
||||
id_color_palette_aux8_dark: '196',
|
||||
id_color_palette_aux8_transparent: '197',
|
||||
id_color_palette_aux9: '198',
|
||||
id_color_palette_aux9_dark: '199',
|
||||
id_color_palette_aux9_transparent: '200',
|
||||
id_color_palette_aux10: '201',
|
||||
id_color_palette_aux10_dark: '202',
|
||||
id_color_palette_aux10_transparent: '203',
|
||||
id_color_palette_aux11: '204',
|
||||
id_color_palette_aux11_dark: '205',
|
||||
id_color_palette_aux11_transparent: '206',
|
||||
id_color_special1: '207',
|
||||
id_color_special1_dark: '208',
|
||||
id_color_special1_transparent: '209',
|
||||
id_color_special2: '210',
|
||||
id_color_special2_dark: '211',
|
||||
id_color_special2_transparent: '212',
|
||||
id_color_special3: '213',
|
||||
id_color_special3_dark: '214',
|
||||
id_color_special3_transparent: '215',
|
||||
id_color_special4: '216',
|
||||
id_color_special4_dark: '217',
|
||||
id_color_special4_transparent: '218',
|
||||
id_color_special5: '219',
|
||||
id_color_special5_dark: '220',
|
||||
id_color_special5_transparent: '221',
|
||||
id_color_special6: '222',
|
||||
id_color_special6_dark: '223',
|
||||
id_color_special6_transparent: '224',
|
||||
id_color_special7: '225',
|
||||
id_color_special7_dark: '226',
|
||||
id_color_special7_transparent: '227',
|
||||
id_color_special8: '228',
|
||||
id_color_special8_dark: '229',
|
||||
id_color_special8_transparent: '230',
|
||||
id_color_special9: '231',
|
||||
id_color_special9_dark: '232',
|
||||
id_color_special9_transparent: '233',
|
||||
id_color_special10: '234',
|
||||
id_color_special10_dark: '235',
|
||||
id_color_special10_transparent: '236',
|
||||
id_color_special11: '237',
|
||||
id_color_special11_dark: '238',
|
||||
id_color_special11_transparent: '239',
|
||||
id_color_mask_thin: '240',
|
||||
id_color_mask_thin_dark: '241',
|
||||
id_color_mask_thin_transparent: '242',
|
||||
id_color_mask_light: '243',
|
||||
id_color_mask_light_dark: '244',
|
||||
id_color_mask_light_transparent: '245',
|
||||
id_color_mask_regular: '246',
|
||||
id_color_mask_regular_dark: '247',
|
||||
id_color_mask_regular_transparent: '248',
|
||||
id_color_mask_thick: '249',
|
||||
id_color_mask_thick_dark: '250',
|
||||
id_color_mask_thick_transparent: '251',
|
||||
id_alpha_content_primary: '252',
|
||||
id_alpha_content_primary_dark: '253',
|
||||
id_alpha_content_primary_transparent: '254',
|
||||
id_alpha_content_secondary: '255',
|
||||
id_alpha_content_secondary_dark: '256',
|
||||
id_alpha_content_secondary_transparent: '257',
|
||||
id_alpha_content_tertiary: '258',
|
||||
id_alpha_content_tertiary_dark: '259',
|
||||
id_alpha_content_tertiary_transparent: '260',
|
||||
id_alpha_content_fourth: '261',
|
||||
id_alpha_content_fourth_dark: '262',
|
||||
id_alpha_content_fourth_transparent: '263',
|
||||
id_alpha_disabled: '264',
|
||||
id_alpha_disabled_dark: '265',
|
||||
id_alpha_disabled_transparent: '266',
|
||||
id_alpha_highlight_bg: '267',
|
||||
id_alpha_highlight_bg_dark: '268',
|
||||
id_alpha_highlight_bg_transparent: '269',
|
||||
id_alpha_normal_bg: '270',
|
||||
id_alpha_normal_bg_dark: '271',
|
||||
id_alpha_normal_bg_transparent: '272',
|
||||
id_alpha_inapptip_bg: '273',
|
||||
id_alpha_inapptip_bg_dark: '274',
|
||||
id_alpha_inapptip_bg_transparent: '275',
|
||||
id_alpha_separator_line: '276',
|
||||
id_alpha_separator_line_dark: '277',
|
||||
id_alpha_separator_line_transparent: '278',
|
||||
id_color_statusbar_bg: '279',
|
||||
id_color_statusbar_bg_dark: '280',
|
||||
id_color_statusbar_bg_transparent: '281',
|
||||
id_color_navigationbar_bg: '282',
|
||||
id_color_navigationbar_bg_dark: '283',
|
||||
id_color_navigationbar_bg_transparent: '284',
|
||||
id_color_titlebar_icon: '285',
|
||||
id_color_titlebar_icon_dark: '286',
|
||||
id_color_titlebar_icon_transparent: '287',
|
||||
id_color_titlebar_icon_pressed: '288',
|
||||
id_color_titlebar_icon_pressed_dark: '289',
|
||||
id_color_titlebar_icon_pressed_transparent: '290',
|
||||
id_color_titlebar_text: '291',
|
||||
id_color_titlebar_text_dark: '292',
|
||||
id_color_titlebar_text_transparent: '293',
|
||||
id_color_titlebar_text_off: '294',
|
||||
id_color_titlebar_text_off_dark: '295',
|
||||
id_color_titlebar_text_off_transparent: '296',
|
||||
id_color_titlebar_subtitle_text: '297',
|
||||
id_color_titlebar_subtitle_text_dark: '298',
|
||||
id_color_titlebar_subtitle_text_transparent: '299',
|
||||
id_color_titlebar_bg: '300',
|
||||
id_color_titlebar_bg_dark: '301',
|
||||
id_color_titlebar_bg_transparent: '302',
|
||||
id_color_titlebar_sub_bg: '303',
|
||||
id_color_titlebar_sub_bg_dark: '304',
|
||||
id_color_titlebar_sub_bg_transparent: '305',
|
||||
id_color_bottom_tab_icon: '306',
|
||||
id_color_bottom_tab_icon_dark: '307',
|
||||
id_color_bottom_tab_icon_transparent: '308',
|
||||
id_color_bottom_tab_icon_off: '309',
|
||||
id_color_bottom_tab_icon_off_dark: '310',
|
||||
id_color_bottom_tab_icon_off_transparent: '311',
|
||||
id_color_bottom_tab_icon_auxcolor01: '312',
|
||||
id_color_bottom_tab_icon_auxcolor01_dark: '313',
|
||||
id_color_bottom_tab_icon_auxcolor01_transparent: '314',
|
||||
id_color_bottom_tab_icon_auxcolor_off01: '315',
|
||||
id_color_bottom_tab_icon_auxcolor_off01_dark: '316',
|
||||
id_color_bottom_tab_icon_auxcolor_off01_transparent: '317',
|
||||
id_color_bottom_tab_icon_auxcolor02: '318',
|
||||
id_color_bottom_tab_icon_auxcolor02_dark: '319',
|
||||
id_color_bottom_tab_icon_auxcolor02_transparent: '320',
|
||||
id_color_bottom_tab_icon_auxcolor_off02: '321',
|
||||
id_color_bottom_tab_icon_auxcolor_off02_dark: '322',
|
||||
id_color_bottom_tab_icon_auxcolor_off02_transparent: '323',
|
||||
id_color_bottom_tab_text_on: '324',
|
||||
id_color_bottom_tab_text_on_dark: '325',
|
||||
id_color_bottom_tab_text_on_transparent: '326',
|
||||
id_color_bottom_tab_text_off: '327',
|
||||
id_color_bottom_tab_text_off_dark: '328',
|
||||
id_color_bottom_tab_text_off_transparent: '329',
|
||||
id_color_bottom_tab_bg: '330',
|
||||
id_color_bottom_tab_bg_dark: '331',
|
||||
id_color_bottom_tab_bg_transparent: '332',
|
||||
id_color_bottom_tab_bg_blur: '333',
|
||||
id_color_bottom_tab_bg_blur_dark: '334',
|
||||
id_color_bottom_tab_bg_blur_transparent: '335',
|
||||
id_color_bottom_tab_sub_bg: '336',
|
||||
id_color_bottom_tab_sub_bg_dark: '337',
|
||||
id_color_bottom_tab_sub_bg_transparent: '338',
|
||||
id_color_bottom_tab_sub_bg_blur: '339',
|
||||
id_color_bottom_tab_sub_bg_blur_dark: '340',
|
||||
id_color_bottom_tab_sub_bg_blur_transparent: '341',
|
||||
id_color_subtab_text_on: '342',
|
||||
id_color_subtab_text_on_dark: '343',
|
||||
id_color_subtab_text_on_transparent: '344',
|
||||
id_color_subtab_text_off: '345',
|
||||
id_color_subtab_text_off_dark: '346',
|
||||
id_color_subtab_text_off_transparent: '347',
|
||||
id_color_subtab_line_on: '348',
|
||||
id_color_subtab_line_on_dark: '349',
|
||||
id_color_subtab_line_on_transparent: '350',
|
||||
id_color_subtab_bg: '351',
|
||||
id_color_subtab_bg_dark: '352',
|
||||
id_color_subtab_bg_transparent: '353',
|
||||
id_color_toolbar_icon: '354',
|
||||
id_color_toolbar_icon_dark: '355',
|
||||
id_color_toolbar_icon_transparent: '356',
|
||||
id_color_toolbar_icon_actived: '357',
|
||||
id_color_toolbar_icon_actived_dark: '358',
|
||||
id_color_toolbar_icon_actived_transparent: '359',
|
||||
id_color_toolbar_text: '360',
|
||||
id_color_toolbar_text_dark: '361',
|
||||
id_color_toolbar_text_transparent: '362',
|
||||
id_color_toolbar_text_actived: '363',
|
||||
id_color_toolbar_text_actived_dark: '364',
|
||||
id_color_toolbar_text_actived_transparent: '365',
|
||||
id_color_toolbar_bg: '366',
|
||||
id_color_toolbar_bg_dark: '367',
|
||||
id_color_toolbar_bg_transparent: '368',
|
||||
id_color_toolbar_sub_bg: '369',
|
||||
id_color_toolbar_sub_bg_dark: '370',
|
||||
id_color_toolbar_sub_bg_transparent: '371',
|
||||
id_color_text_field_bg: '372',
|
||||
id_color_text_field_bg_dark: '373',
|
||||
id_color_text_field_bg_transparent: '374',
|
||||
id_color_text_field_sub_bg: '375',
|
||||
id_color_text_field_sub_bg_dark: '376',
|
||||
id_color_text_field_sub_bg_transparent: '377',
|
||||
id_color_progress: '378',
|
||||
id_color_progress_dark: '379',
|
||||
id_color_progress_transparent: '380',
|
||||
id_color_spinner_icon: '381',
|
||||
id_color_spinner_icon_dark: '382',
|
||||
id_color_spinner_icon_transparent: '383',
|
||||
id_color_badge: '384',
|
||||
id_color_badge_dark: '385',
|
||||
id_color_badge_transparent: '386',
|
||||
id_color_badge_red: '387',
|
||||
id_color_badge_red_dark: '388',
|
||||
id_color_badge_red_transparent: '389',
|
||||
id_color_dialog_bg: '390',
|
||||
id_color_dialog_bg_dark: '391',
|
||||
id_color_dialog_bg_transparent: '392',
|
||||
id_color_button_normal: '393',
|
||||
id_color_button_normal_dark: '394',
|
||||
id_color_button_normal_transparent: '395',
|
||||
id_color_switch_outline_off: '396',
|
||||
id_color_switch_outline_off_dark: '397',
|
||||
id_color_switch_outline_off_transparent: '398',
|
||||
id_color_switch_bg_off: '399',
|
||||
id_color_switch_bg_off_dark: '400',
|
||||
id_color_switch_bg_off_transparent: '401',
|
||||
id_color_floating_button_icon: '402',
|
||||
id_color_floating_button_icon_dark: '403',
|
||||
id_color_floating_button_icon_transparent: '404',
|
||||
id_color_floating_button_icon_start: '405',
|
||||
id_color_floating_button_icon_start_dark: '406',
|
||||
id_color_floating_button_icon_start_transparent: '407',
|
||||
id_color_floating_button_icon_end: '408',
|
||||
id_color_floating_button_icon_end_dark: '409',
|
||||
id_color_floating_button_icon_end_transparent: '410',
|
||||
id_color_floating_button_bg_normal: '411',
|
||||
id_color_floating_button_bg_normal_dark: '412',
|
||||
id_color_floating_button_bg_normal_transparent: '413',
|
||||
id_color_floating_button_start: '414',
|
||||
id_color_floating_button_start_dark: '415',
|
||||
id_color_floating_button_start_transparent: '416',
|
||||
id_color_floating_button_center: '417',
|
||||
id_color_floating_button_center_dark: '418',
|
||||
id_color_floating_button_center_transparent: '419',
|
||||
id_color_floating_button_end: '420',
|
||||
id_color_floating_button_end_dark: '421',
|
||||
id_color_floating_button_end_transparent: '422',
|
||||
id_color_floating_button_shadow_start: '423',
|
||||
id_color_floating_button_shadow_start_dark: '424',
|
||||
id_color_floating_button_shadow_start_transparent: '425',
|
||||
id_color_floating_button_shadow_end: '426',
|
||||
id_color_floating_button_shadow_end_dark: '427',
|
||||
id_color_floating_button_shadow_end_transparent: '428',
|
||||
id_color_floating_button_bg_pressed: '429',
|
||||
id_color_floating_button_bg_pressed_dark: '430',
|
||||
id_color_floating_button_bg_pressed_transparent: '431',
|
||||
id_color_instant_tip_bg: '432',
|
||||
id_color_instant_tip_bg_dark: '433',
|
||||
id_color_instant_tip_bg_transparent: '434',
|
||||
id_color_panel_bg: '435',
|
||||
id_color_panel_bg_dark: '436',
|
||||
id_color_panel_bg_transparent: '437',
|
||||
id_color_card_bg: '438',
|
||||
id_color_card_bg_dark: '439',
|
||||
id_color_card_bg_transparent: '440',
|
||||
id_color_list_card_bg: '441',
|
||||
id_color_list_card_bg_dark: '442',
|
||||
id_color_list_card_bg_transparent: '443',
|
||||
id_color_tooltip_foreground: '444',
|
||||
id_color_tooltip_foreground_dark: '445',
|
||||
id_color_tooltip_foreground_transparent: '446',
|
||||
id_color_tooltip_background: '447',
|
||||
id_color_tooltip_background_dark: '448',
|
||||
id_color_tooltip_background_transparent: '449',
|
||||
id_color_help_tip_bg: '450',
|
||||
id_color_help_tip_bg_dark: '451',
|
||||
id_color_help_tip_bg_transparent: '452',
|
||||
id_text_size_headline1: '453',
|
||||
id_text_size_headline2: '454',
|
||||
id_text_size_headline3: '455',
|
||||
id_text_size_headline4: '456',
|
||||
id_text_size_headline5: '457',
|
||||
id_text_size_headline6: '458',
|
||||
id_text_size_headline7: '459',
|
||||
id_text_size_headline8: '460',
|
||||
id_text_size_headline9: '461',
|
||||
id_text_size_sub_title1: '462',
|
||||
id_text_size_sub_title2: '463',
|
||||
id_text_size_sub_title3: '464',
|
||||
id_text_size_button1: '465',
|
||||
id_text_size_button2: '466',
|
||||
id_text_size_button3: '467',
|
||||
id_text_size_body1: '468',
|
||||
id_text_size_body2: '469',
|
||||
id_text_size_body3: '470',
|
||||
id_text_size_caption: '471',
|
||||
id_text_size_caption1: '472',
|
||||
id_text_size_chart1: '473',
|
||||
id_text_size_chart2: '474',
|
||||
id_text_size_over_line: '475',
|
||||
id_text_font_family_regular: '476',
|
||||
id_text_font_family_medium: '477',
|
||||
id_corner_radius_tips_toast: '478',
|
||||
id_corner_radius_tips_badge: '479',
|
||||
id_corner_radius_tips_tips: '480',
|
||||
id_corner_radius_toggle_button: '481',
|
||||
id_corner_radius_switch: '482',
|
||||
id_corner_radius_piece: '483',
|
||||
id_corner_radius_button: '484',
|
||||
id_corner_radius_small_button: '485',
|
||||
id_corner_radius_mark: '486',
|
||||
id_corner_radius_subtab: '487',
|
||||
id_corner_radius_clicked: '488',
|
||||
id_corner_radius_panel: '489',
|
||||
id_corner_radius_notification: '490',
|
||||
id_corner_radius_card: '491',
|
||||
id_corner_radius_progress_bar: '492',
|
||||
id_corner_radius_dialog: '493',
|
||||
id_corner_radius_grid: '494',
|
||||
id_corner_radius_check_box: '495',
|
||||
id_corner_radius_menu: '496',
|
||||
id_corner_radius_banner: '497',
|
||||
id_corner_radius_icon: '498',
|
||||
id_corner_radius_text_field: '499',
|
||||
id_corner_radius_default_xl: '500',
|
||||
id_corner_radius_default_l: '501',
|
||||
id_corner_radius_default_m: '502',
|
||||
id_corner_radius_default_s: '503',
|
||||
id_corner_radius_default_xs: '504',
|
||||
id_default_padding_start: '505',
|
||||
id_max_padding_start: '506',
|
||||
id_default_padding_end: '507',
|
||||
id_max_padding_end: '508',
|
||||
id_default_padding_top: '509',
|
||||
id_default_padding_bottom_flexible: '510',
|
||||
id_default_padding_bottom_fixed: '511',
|
||||
id_dialog_margin_start: '512',
|
||||
id_dialog_margin_end: '513',
|
||||
id_dialog_margin_bottom: '514',
|
||||
id_notification_margin_start: '515',
|
||||
id_notification_margin_end: '516',
|
||||
id_card_margin_start: '517',
|
||||
id_card_margin_end: '518',
|
||||
id_card_margin_middle: '519',
|
||||
id_text_margin_vertical: '520',
|
||||
id_text_margin_horizontal: '521',
|
||||
id_text_paragraph_margin_xl: '522',
|
||||
id_text_paragraph_margin_l: '523',
|
||||
id_text_paragraph_margin_m: '524',
|
||||
id_text_paragraph_margin_s: '525',
|
||||
id_text_paragraph_margin_xs: '526',
|
||||
id_elements_margin_vertical_l: '527',
|
||||
id_elements_margin_vertical_m: '528',
|
||||
id_elements_margin_horizontal_l: '529',
|
||||
id_elements_margin_horizontal_m: '530',
|
||||
id_text_line_space_s: '531',
|
||||
id_text_line_space_l: '532',
|
||||
button_pattern_light: '533',
|
||||
button_pattern_dark: '534',
|
||||
button_pattern_transparent: '535',
|
||||
button_bg_light: '536',
|
||||
button_bg_dark: '537',
|
||||
button_bg_transparent: '538',
|
||||
button_radius: '539',
|
||||
checkbox_pattern_light: '540',
|
||||
checkbox_pattern_dark: '541',
|
||||
checkbox_pattern_transparent: '542',
|
||||
radio_pattern_light: '543',
|
||||
radio_pattern_dark: '544',
|
||||
radio_pattern_transparent: '545',
|
||||
switch_pattern_light: '546',
|
||||
switch_pattern_dark: '547',
|
||||
switch_pattern_transparent: '548',
|
||||
swiper_pattern_light: '549',
|
||||
swiper_pattern_dark: '550',
|
||||
swiper_pattern_transparent: '551',
|
||||
data_panel_pattern_light: '552',
|
||||
data_panel_pattern_dark: '553',
|
||||
data_panel_pattern_transparent: '554',
|
||||
toolbar_pattern_light: '555',
|
||||
toolbar_pattern_dark: '556',
|
||||
toolbar_pattern_transparent: '557',
|
||||
toggle_pattern_light: '558',
|
||||
toggle_pattern_dark: '559',
|
||||
toggle_pattern_transparent: '560',
|
||||
theme_hide_title_bar: '561',
|
||||
emergency_number: '562',
|
||||
fa_foreground: '563',
|
||||
fa_foreground_dark: '564',
|
||||
fa_foreground_contrary: '565',
|
||||
fa_foreground_contrary_dark: '566',
|
||||
fa_emphasize: '567',
|
||||
fa_emphasize_dark: '568',
|
||||
fa_emphasize_outline: '569',
|
||||
fa_emphasize_outline_dark: '570',
|
||||
fa_alert: '571',
|
||||
fa_alert_dark: '572',
|
||||
fa_warning: '573',
|
||||
fa_warning_dark: '574',
|
||||
fa_handup: '575',
|
||||
fa_handup_dark: '576',
|
||||
fa_connected: '577',
|
||||
fa_connected_dark: '578',
|
||||
fa_component_normal: '579',
|
||||
fa_component_normal_dark: '580',
|
||||
fa_click_effect: '581',
|
||||
fa_click_effect_dark: '582',
|
||||
fa_list_separator: '583',
|
||||
fa_list_separator_dark: '584',
|
||||
fa_list_card_bg_blur: '585',
|
||||
fa_list_card_bg_blur_dark: '586',
|
||||
fa_list_card_bg: '587',
|
||||
fa_list_card_bg_dark: '588',
|
||||
fa_background_blur: '589',
|
||||
fa_background_blur_dark: '590',
|
||||
fa_background: '591',
|
||||
fa_background_dark: '592',
|
||||
fa_sub_background: '593',
|
||||
fa_sub_background_dark: '594',
|
||||
fa_text_primary: '595',
|
||||
fa_text_primary_dark: '596',
|
||||
fa_text_secondary: '597',
|
||||
fa_text_secondary_dark: '598',
|
||||
fa_text_tertiary: '599',
|
||||
fa_text_tertiary_dark: '600',
|
||||
fa_text_fourth: '601',
|
||||
fa_text_fourth_dark: '602',
|
||||
fa_text_contrary: '603',
|
||||
fa_text_contrary_dark: '604',
|
||||
fa_text_activated: '605',
|
||||
fa_text_activated_dark: '606',
|
||||
fa_icon_primary: '607',
|
||||
fa_icon_primary_dark: '608',
|
||||
fa_icon_secondary: '609',
|
||||
fa_icon_secondary_dark: '610',
|
||||
fa_icon_tertiary: '611',
|
||||
fa_icon_tertiary_dark: '612',
|
||||
fa_icon_fourth: '613',
|
||||
fa_icon_fourth_dark: '614',
|
||||
fa_icon_contrary: '615',
|
||||
fa_icon_contrary_dark: '616',
|
||||
fa_activated: '617',
|
||||
fa_activated_dark: '618',
|
||||
fa_palette1: '619',
|
||||
fa_palette1_dark: '620',
|
||||
fa_palette2: '621',
|
||||
fa_palette2_dark: '622',
|
||||
fa_palette3: '623',
|
||||
fa_palette3_dark: '624',
|
||||
fa_palette4: '625',
|
||||
fa_palette4_dark: '626',
|
||||
fa_palette5: '627',
|
||||
fa_palette5_dark: '628',
|
||||
fa_palette6: '629',
|
||||
fa_palette6_dark: '630',
|
||||
fa_palette7: '631',
|
||||
fa_palette7_dark: '632',
|
||||
fa_palette8: '633',
|
||||
fa_palette8_dark: '634',
|
||||
fa_palette9: '635',
|
||||
fa_palette9_dark: '636',
|
||||
fa_palette10: '637',
|
||||
fa_palette10_dark: '638',
|
||||
fa_palette11: '639',
|
||||
fa_palette11_dark: '640',
|
||||
fa_palette12: '641',
|
||||
fa_palette12_dark: '642',
|
||||
fa_alpha_content_primary: '643',
|
||||
fa_alpha_content_primary_dark: '644',
|
||||
fa_alpha_content_secondary: '645',
|
||||
fa_alpha_content_secondary_dark: '646',
|
||||
fa_alpha_content_tertiary: '647',
|
||||
fa_alpha_content_tertiary_dark: '648',
|
||||
fa_alpha_content_fourth: '649',
|
||||
fa_alpha_content_fourth_dark: '650',
|
||||
fa_alpha_disabled: '651',
|
||||
fa_alpha_disabled_dark: '652',
|
||||
fa_alpha_highlight_bg: '653',
|
||||
fa_alpha_highlight_bg_dark: '654',
|
||||
fa_corner_radius_card: '655',
|
||||
fa_corner_radius_list_card_bg: '656',
|
||||
fa_corner_radius_default_s: '657',
|
||||
fa_corner_radius_default_xs: '658',
|
||||
fa_card_background: '659',
|
||||
fa_card_background_dark: '660',
|
||||
fa_card_border: '661',
|
||||
fa_card_border_dark: '662',
|
||||
fa_card_icon_mask: '663',
|
||||
id_text_size_dialog_tittle: '664',
|
||||
};
|
||||
|
||||
module.exports = OHOS_THEME_STYLES;
|
86
ace-loader/router/findDev.js
Normal file
86
ace-loader/router/findDev.js
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const os = require("os")
|
||||
const http = require("http");
|
||||
const crypto = require('crypto');
|
||||
|
||||
const localHost = '127.0.0.1'
|
||||
const uri = '/api/system/deviceinfo'
|
||||
const timeout = 300
|
||||
const IPv4 = 'IPv4'
|
||||
const SHA256 = 'SHA256'
|
||||
const hex = 'hex'
|
||||
|
||||
function fliterAlias(alias) {
|
||||
return alias.family === IPv4 && alias.address !== localHost && !alias.internal
|
||||
}
|
||||
|
||||
function getIP() {
|
||||
let IPAdress = [];
|
||||
Object.values(os.networkInterfaces()).forEach(
|
||||
iface => iface.filter(fliterAlias).forEach(
|
||||
alias => {
|
||||
ip = alias.address.replace(/\.\d+$/, '.1')
|
||||
!IPAdress.includes(ip) && IPAdress.push(ip)
|
||||
}
|
||||
)
|
||||
);
|
||||
return IPAdress;
|
||||
}
|
||||
|
||||
async function getName(ip) {
|
||||
return await new Promise(resolve => {
|
||||
let req = http.get(`http://${ip}${uri}`, { timeout: timeout }, resp => {
|
||||
if (resp.statusCode != 200) {
|
||||
req.destroy();
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
|
||||
resp.setEncoding('utf8');
|
||||
let ret = "";
|
||||
resp.on('data', chunk => ret += chunk);
|
||||
resp.on('end', () => {
|
||||
try {
|
||||
const parsedData = JSON.parse(ret)
|
||||
resolve({ ip, name: parsedData.FriendlyName, udid: crypto.createHash(SHA256).update(parsedData.uuid).digest(hex) });
|
||||
} catch (error) {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
req.on("error", () => {
|
||||
req.destroy();
|
||||
resolve(null);
|
||||
}).on("timeout", () => {
|
||||
req.destroy();
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
let ipArr = getIP();
|
||||
let ret = [];
|
||||
for (let i = 0; i < ipArr.length; i++) {
|
||||
let route = await getName(ipArr[i]);
|
||||
route && ret.push(route)
|
||||
}
|
||||
console.info("resp : 200");
|
||||
console.info(JSON.stringify(ret));
|
||||
}
|
||||
|
||||
main();
|
57
ace-loader/router/main.product.router.js
Normal file
57
ace-loader/router/main.product.router.js
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
let aceModuleRoot = process.env.aceModuleRoot;
|
||||
const buildPath = process.env.aceModuleBuild;
|
||||
|
||||
const config = path.join(aceModuleRoot, "../../config.json");
|
||||
const appJSPath = path.join(aceModuleRoot, "app.js");
|
||||
let pluginInfo = {};
|
||||
|
||||
loadEntryObj();
|
||||
|
||||
function loadEntryObj() {
|
||||
const red = "\u001b[31m";
|
||||
const reset = "\u001b[39m";
|
||||
|
||||
if (!fs.existsSync(config)) {
|
||||
throw Error(red + "ERROR: missing config" + reset).message;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(appJSPath)) {
|
||||
throw Error(red + "ERROR: missing app.js" + reset).message;
|
||||
}
|
||||
|
||||
pluginInfo = JSON.parse(fs.readFileSync(config, {
|
||||
encoding: "utf-8"
|
||||
}));
|
||||
|
||||
if (!(pluginInfo && pluginInfo.app && pluginInfo.app.bundleName && pluginInfo.app.version.name)) {
|
||||
throw Error(red + "ERROR: mainfest context invalid" + JSON.stringify(pluginInfo)).message;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
appJSPath,
|
||||
pluginInfo,
|
||||
buildPath: buildPath,
|
||||
projectPath: aceModuleRoot,
|
||||
manifestFilePath: config,
|
||||
pkgName: pluginInfo.app.bundleName,
|
||||
hapName: pluginInfo.app.bundleName + "-" + pluginInfo.app.version.name + "_unsigned",
|
||||
};
|
24
ace-loader/router/module-scipt-router.js
Normal file
24
ace-loader/router/module-scipt-router.js
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module.exports = function (context) {
|
||||
if (this.query == undefined || this.query.pkgName == undefined) {
|
||||
throw Error("custom loader haven't recv the pkgName");
|
||||
}
|
||||
return context.replace(
|
||||
/import (\w+) from [\'\"]{1}@system\.(\w+)[\'\"]{1}/g,
|
||||
`var $1 = requireNative('${this.query.pkgName}','$2')`
|
||||
);
|
||||
};
|
206
ace-loader/router/push.js
Normal file
206
ace-loader/router/push.js
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const crypto = require("crypto");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const http = require("http");
|
||||
const os = require("os");
|
||||
const { login, GET, POST, decryptStr2Str } = require("./pushHelper");
|
||||
|
||||
let localIp = undefined;
|
||||
let argv = getArgv();
|
||||
|
||||
checkArgv();
|
||||
|
||||
let pwd = decryptStr2Str(argv.metePath, argv.session);
|
||||
if (pwd == undefined) {
|
||||
finish(12, "incorrect password.");
|
||||
}
|
||||
|
||||
function constainsKey(array, key) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i].pkgName === key) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
let cnt = 0;
|
||||
function getErr(data) {
|
||||
if (cnt == 20) {
|
||||
POST(`http://${argv.ip}/api/system/user_logout`);
|
||||
finish(41, "install timeout");
|
||||
}
|
||||
cnt++;
|
||||
|
||||
GET(`http://${argv.ip}/api/hap/all_infos`).then(
|
||||
allInfos => {
|
||||
if (constainsKey(allInfos.installedHap, data.pkgName)) {
|
||||
POST(`http://${argv.ip}/api/system/user_logout`);
|
||||
finish(31, "install success.");
|
||||
}
|
||||
if (constainsKey(allInfos.installingHap, data.pkgName)) {
|
||||
return;
|
||||
}
|
||||
return POST(`http://${argv.ip}/api/acelite/get_err`, data);
|
||||
}
|
||||
).then(
|
||||
errInfo => {
|
||||
POST(`http://${argv.ip}/api/system/user_logout`);
|
||||
if (errInfo.errCode == 404) {
|
||||
finish(30, "no interface.");
|
||||
}
|
||||
finish(errInfo.errCode, "install fail");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
login(argv.ip, pwd).then(res => {
|
||||
if (res == undefined) {
|
||||
finish(10, "internal error.");
|
||||
};
|
||||
|
||||
if (res.err == 0) {
|
||||
let port = createListen(argv.file);
|
||||
if (port == null) {
|
||||
finish(8, "create the file server failed.");
|
||||
}
|
||||
|
||||
let data = {
|
||||
pkgName: argv.pkgName,
|
||||
name: argv.name,
|
||||
versionName: argv.versionName || "1.0.0",
|
||||
versionCode: parseInt(argv.versionCode) || 1,
|
||||
appId: argv.appId || "C" + new Date().getTime(),
|
||||
downloadUrl: `http://${localIp}:${port}/signed.hap`,
|
||||
iconUrl: "https://appimg.dbankcdn.com/application/icon144/a02cb676dfdf49ccad87471b421a5276.png",
|
||||
isDebug: 1,
|
||||
};
|
||||
|
||||
POST(`http://${argv.ip}/api/acelite/hap_delete`, data).then(
|
||||
() => {
|
||||
return POST(`http://${argv.ip}/api/acelite/hap_debug`, data);
|
||||
}
|
||||
).then(
|
||||
res => {
|
||||
if (res.errcode != 0) {
|
||||
finish(14, "push fail.");
|
||||
}
|
||||
setInterval(()=>getErr(data), 3000);
|
||||
}
|
||||
);
|
||||
} else if ((res.err == 4784230 || res.err == 4784231) && res.waitTime) {
|
||||
finish(13, "too many errors. Please try again later.");
|
||||
} else {
|
||||
finish(9, "login failed.");
|
||||
}
|
||||
}).catch(err => {
|
||||
finish(10, "internal error.");
|
||||
});
|
||||
|
||||
if (!argv.file) {
|
||||
finish(2, "Path is null")
|
||||
}
|
||||
|
||||
function checkArgv() {
|
||||
if (!argv.ip || !(localIp = getLocalIp(argv.ip))) {
|
||||
finish(1, "ip error")
|
||||
}
|
||||
if (!argv.file || !fs.existsSync(argv.file)) {
|
||||
finish(2, "file error.")
|
||||
}
|
||||
if (!argv.metePath || !fs.statSync(argv.metePath).isDirectory()) {
|
||||
finish(3, "metePath error.")
|
||||
}
|
||||
if (!argv.session) {
|
||||
finish(4, "session error.")
|
||||
}
|
||||
if (!argv.pkgName) {
|
||||
finish(5, "pkgName error.")
|
||||
}
|
||||
if (!argv.name) {
|
||||
finish(6, "name error.")
|
||||
}
|
||||
}
|
||||
|
||||
function finish(code, msg) {
|
||||
process.exit(code)
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen to external download requirements on random port from 9000 to 9100.
|
||||
* @param {String} hapPath hap file path.
|
||||
* @return {Number} service port.
|
||||
*/
|
||||
function createListen(hapPath) {
|
||||
/* Generate a random number 9000~9100. randomBytes() return number is 0~255. */
|
||||
let port = 9000 + Math.round(new Uint8Array(crypto.randomBytes(1))[0] * 100 / 255);
|
||||
|
||||
let server = http.createServer(function (req, res) {
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'Content-Disposition': 'attachment; filename=' + path.basename(hapPath),
|
||||
"Content-Length": fs.statSync(hapPath).size
|
||||
});
|
||||
fs.createReadStream(hapPath).pipe(res);
|
||||
server.close();
|
||||
}).listen(port);
|
||||
|
||||
server.on("error", () => {
|
||||
finish(8, "create the file server failed.");
|
||||
})
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parameter from command.
|
||||
* @return {Object} Object of parameter
|
||||
*/
|
||||
function getArgv() {
|
||||
let ret = {};
|
||||
process.argv.splice(2).forEach((value, index, array) => {
|
||||
if (/^--[a-zA-Z]+/.test(value)) {
|
||||
if (index < array.length - 1 && /[^-]+/.test(array[index + 1])) {
|
||||
ret[value.substr(2)] = array[index + 1];
|
||||
} else {
|
||||
ret[value.substr(2)] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getLocalIp(ip) {
|
||||
let localIp = undefined;
|
||||
Object.values(os.networkInterfaces()).forEach(
|
||||
iface => {
|
||||
iface.forEach(
|
||||
alias => {
|
||||
if (alias.address.replace(/\.\d+$/, '.1') == ip) {
|
||||
localIp = alias.address;
|
||||
return;
|
||||
}
|
||||
}
|
||||
);
|
||||
if (localIp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
);
|
||||
return localIp;
|
||||
}
|
320
ace-loader/router/pushHelper.js
Normal file
320
ace-loader/router/pushHelper.js
Normal file
@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var http = require("http");
|
||||
const crypto = require("crypto");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
let ip = undefined;
|
||||
let pwd = undefined;
|
||||
let csrf = {};
|
||||
let globalCookie = '';
|
||||
|
||||
const defaultHeader = {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
Accept: 'application/json, text/javascript, */*; q=0.01',
|
||||
'Content-Type': 'application/json; charset=utf-8'
|
||||
}
|
||||
|
||||
module.exports = { decryptStr2Str, login, GET, POST };
|
||||
|
||||
function login(ipParam, pwdParam) {
|
||||
return new Promise(async resolve => {
|
||||
if (!ipParam || pwdParam == undefined) {
|
||||
resolve();
|
||||
}
|
||||
ip = ipParam;
|
||||
pwd = pwdParam;
|
||||
|
||||
await GET(`http://${ip}/api/system/deviceinfo`);
|
||||
|
||||
let count = 0;
|
||||
let proofData = undefined;
|
||||
do {
|
||||
let firstNonce = crypto.createHash('sha256').update(crypto.randomBytes(8)).digest("hex");
|
||||
let res = await POST(`http://${ip}/api/system/user_login_nonce`, { username: 'admin', firstnonce: firstNonce })
|
||||
|
||||
if (res.err != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
proofData = getProofData(res, firstNonce);
|
||||
} while (!proofData && ++count < 5);
|
||||
|
||||
if (proofData == undefined) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
res = await POST(`http://${ip}/api/system/user_login_proof`, proofData)
|
||||
resolve(res);
|
||||
});
|
||||
};
|
||||
|
||||
function getProofData(res, firstNonce) {
|
||||
if (!res || res.err != 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let iter = res.iterations;
|
||||
let finalNonce = res.servernonce;
|
||||
let salt = res.salt;
|
||||
if (!iter || !finalNonce || !salt) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let authMsg = firstNonce + "," + finalNonce + "," + finalNonce;
|
||||
let saltPwd = crypto.pbkdf2Sync(Buffer.from(stringToByte(pwd)), hexStringToByte(salt), iter, 32, "sha256");
|
||||
let clientKey = crypto.createHmac("sha256", "Client Key").update(saltPwd).digest();
|
||||
let storekey = crypto.createHash("sha256").update(clientKey).digest();
|
||||
let clientsignature = crypto.createHmac("sha256", authMsg).update(storekey).digest();
|
||||
let len = clientKey.byteLength;
|
||||
let clientproof = Buffer.alloc(len);
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
clientproof.writeUInt8(clientKey.readUInt8(i) ^ clientsignature.readUInt8(i), i);
|
||||
}
|
||||
|
||||
clientproof = clientproof.toString("hex")
|
||||
|
||||
return {
|
||||
clientproof: clientproof,
|
||||
finalnonce: finalNonce
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function refreshSession(header, ret) {
|
||||
let cookie = header && header["set-cookie"] && header["set-cookie"][0];
|
||||
|
||||
cookie && (globalCookie = (cookie.substring(0, cookie.indexOf(";"))));
|
||||
ret.csrf_param && (csrf.csrf_param = ret.csrf_param);
|
||||
ret.csrf_token && (csrf.csrf_token = ret.csrf_token);
|
||||
}
|
||||
|
||||
function POST(url, data) {
|
||||
return new Promise(resolve => {
|
||||
let req = http.request(url, {
|
||||
method: "post",
|
||||
timeout: 300,
|
||||
headers: {
|
||||
...defaultHeader,
|
||||
Cookie: globalCookie
|
||||
}
|
||||
}, resp => {
|
||||
if (resp.statusCode != 200) {
|
||||
resolve({errCode: 404});
|
||||
return;
|
||||
}
|
||||
|
||||
let ret = "";
|
||||
resp.on('data', chunk => ret += chunk);
|
||||
resp.on('end', () => {
|
||||
try{
|
||||
ret = JSON.parse(ret);
|
||||
}catch(err) {
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
refreshSession(resp.headers, ret);
|
||||
resolve(ret);
|
||||
});
|
||||
});
|
||||
|
||||
req.write(JSON.stringify({
|
||||
data,
|
||||
csrf,
|
||||
}));
|
||||
req.end();
|
||||
|
||||
req.on("error", () => {
|
||||
req.destroy();
|
||||
resolve(null);
|
||||
}).on("timeout", () => {
|
||||
req.destroy();
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function GET(url) {
|
||||
return new Promise(resolve => {
|
||||
let req = http.get(url, {
|
||||
timeout: 300, headers: {
|
||||
...defaultHeader,
|
||||
Cookie: globalCookie
|
||||
}
|
||||
}, resp => {
|
||||
let ret = "";
|
||||
resp.on('data', chunk => ret += chunk);
|
||||
resp.on('end', () => {
|
||||
ret = JSON.parse(ret);
|
||||
refreshSession(resp.headers, ret);
|
||||
resolve(ret);
|
||||
});
|
||||
});
|
||||
|
||||
req.on("error", () => {
|
||||
req.destroy();
|
||||
resolve(null);
|
||||
}).on("timeout", () => {
|
||||
req.destroy();
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fd Root key component directory.
|
||||
* ac Directory for storing the salt used to generate the final root key in iteration mode.
|
||||
* ce work key material directory
|
||||
*/
|
||||
const comDirs = ["fd", "ac", "ce"];
|
||||
|
||||
/**
|
||||
* Root path of key materials. All materials are stored in this path.
|
||||
*/
|
||||
const meteDir = "material";
|
||||
|
||||
/**
|
||||
* A part of the root key component. It must work with other components to form a root key.
|
||||
* For details, see the Key Management Security Specifications V1.3.
|
||||
*/
|
||||
let COMPONENT = Array.from(new Int8Array([
|
||||
0x31, 0xf3, 0x09, 0x73, 0xd6, 0xaf, 0x5b, 0xb8,
|
||||
0xd3, 0xbe, 0xb1, 0x58, 0x65, 0x83, 0xc0, 0x77
|
||||
]));
|
||||
|
||||
function decryptStr2Str(rootPath, input) {
|
||||
let metePath = path.resolve(rootPath, meteDir);
|
||||
let components = readComponents(metePath);
|
||||
let saltDir = path.resolve(metePath, comDirs[1]);
|
||||
let salt = readDirBytes(saltDir);
|
||||
let rootKey = deriveRootKey(components, salt);
|
||||
let workMeteDir = path.resolve(metePath, comDirs[2]);
|
||||
let workMete = readDirBytes(workMeteDir);
|
||||
let key = decrypt(rootKey, workMete);
|
||||
let bts = hexStringToByte(input);
|
||||
|
||||
let output = decrypt(key, bts);
|
||||
return (Buffer.from(output).toString("utf-8"));
|
||||
}
|
||||
|
||||
function hexStringToByte(str) {
|
||||
if (!str) {
|
||||
return new Uint8Array();
|
||||
}
|
||||
|
||||
var a = [];
|
||||
for (var i = 0, len = str.length; i < len; i += 2) {
|
||||
a.push(parseInt(str.substr(i, 2), 16));
|
||||
}
|
||||
|
||||
return new Int8Array(a);
|
||||
}
|
||||
|
||||
function decrypt(rootKey, workMete) {
|
||||
if (workMete.length < 32) {
|
||||
return null;
|
||||
}
|
||||
let bodyLength = ((workMete[0] & 0xFF) << 24) | ((workMete[1] & 0xFF) << 16) | ((workMete[2] & 0xFF) <<
|
||||
8) | ((workMete[3] & 0xFF));
|
||||
|
||||
let iv = workMete.slice(4, workMete.length - bodyLength);
|
||||
|
||||
let cipher = crypto.createCipheriv("aes-128-gcm", new Int8Array(rootKey), new Int8Array(iv), {
|
||||
authTagLength: 16
|
||||
});
|
||||
let encrypted = cipher.update(new Int8Array(workMete.slice(workMete.length - bodyLength)))
|
||||
cipher.final();
|
||||
return new Int8Array(encrypted).slice(0, bodyLength - 16);
|
||||
|
||||
}
|
||||
|
||||
function deriveRootKey(components, salt) {
|
||||
let fullComponents = components;
|
||||
fullComponents.push(COMPONENT);
|
||||
let finalComponent = sortFullComponent(fullComponents);
|
||||
let key = Array.from(new Int8Array(crypto.pbkdf2Sync(finalComponent, new Int8Array(salt), 10000, 16, "sha256")));
|
||||
return key;
|
||||
}
|
||||
|
||||
function sortFullComponent(fullComponents) {
|
||||
let ret = fullComponents[0];
|
||||
for (let i = 1; i < fullComponents.length; i++) {
|
||||
ret = xor(ret, fullComponents[i]);
|
||||
}
|
||||
return new Int8Array(stringToByte(Buffer.from(ret).toString("utf-8")));
|
||||
}
|
||||
|
||||
function stringToByte(str) {
|
||||
var bytes = new Array();
|
||||
var len, c;
|
||||
len = str.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
c = str.charCodeAt(i);
|
||||
if (c >= 0x010000 && c <= 0x10FFFF) {
|
||||
bytes.push(((c >> 18) & 0x07) | 0xF0);
|
||||
bytes.push(((c >> 12) & 0x3F) | 0x80);
|
||||
bytes.push(((c >> 6) & 0x3F) | 0x80);
|
||||
bytes.push((c & 0x3F) | 0x80);
|
||||
} else if (c >= 0x000800 && c <= 0x00FFFF) {
|
||||
bytes.push(((c >> 12) & 0x0F) | 0xE0);
|
||||
bytes.push(((c >> 6) & 0x3F) | 0x80);
|
||||
bytes.push((c & 0x3F) | 0x80);
|
||||
} else if (c >= 0x000080 && c <= 0x0007FF) {
|
||||
bytes.push(((c >> 6) & 0x1F) | 0xC0);
|
||||
bytes.push((c & 0x3F) | 0x80);
|
||||
} else {
|
||||
bytes.push(c & 0xFF);
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
function xor(arr1, arr2) {
|
||||
if (!arr1 || !arr2 || arr1.length != arr2.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let ret = [];
|
||||
for (let i = 0; i < arr1.length; i++) {
|
||||
ret.push(arr1[i] ^ arr2[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function readDirBytes(dir) {
|
||||
let files = fs.readdirSync(dir);
|
||||
if (files.length != 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Array.from(new Int8Array(fs.readFileSync(path.resolve(dir, files[0]))));
|
||||
}
|
||||
|
||||
function readComponents(dir) {
|
||||
let files = fs.readdirSync(path.resolve(dir, comDirs[0]));
|
||||
if (files == null || files.length != 3) {
|
||||
return null;
|
||||
}
|
||||
let ret = [];
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
ret.push(readDirBytes(path.resolve(dir, comDirs[0], files[i])));
|
||||
}
|
||||
return ret;
|
||||
}
|
5
ace-loader/sample/card/i18n/en.json
Normal file
5
ace-loader/sample/card/i18n/en.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"message":{
|
||||
"hello": "hello world"
|
||||
}
|
||||
}
|
5
ace-loader/sample/card/i18n/zh.json
Normal file
5
ace-loader/sample/card/i18n/zh.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"message": {
|
||||
"hello": "你好世界"
|
||||
}
|
||||
}
|
15
ace-loader/sample/card/manifest.json
Normal file
15
ace-loader/sample/card/manifest.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"appID": "com.example.ace.helloworld",
|
||||
"appName": "HelloAce",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": 1,
|
||||
"minPlatformVersion": "1.0.1",
|
||||
"pages": [
|
||||
"pages/index/index"
|
||||
],
|
||||
"window": {
|
||||
"designWidth": 720,
|
||||
"autoDesignWidth": false
|
||||
},
|
||||
"type": "form"
|
||||
}
|
23
ace-loader/sample/card/pages/index/index.css
Normal file
23
ace-loader/sample/card/pages/index/index.css
Normal file
@ -0,0 +1,23 @@
|
||||
.container {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
.button-div {
|
||||
padding-top: 50px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.text-div {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
font-size: 30px;
|
||||
}
|
8
ace-loader/sample/card/pages/index/index.hml
Normal file
8
ace-loader/sample/card/pages/index/index.hml
Normal file
@ -0,0 +1,8 @@
|
||||
<div class="container">
|
||||
<div class="text-div">
|
||||
<text class="title">This is the index page.</text>
|
||||
</div>
|
||||
<div class="button-div">
|
||||
<button value="Go to the second page" class="button" onclick="router"/>
|
||||
</div>
|
||||
</div>
|
19
ace-loader/sample/card/pages/index/index.json
Normal file
19
ace-loader/sample/card/pages/index/index.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"data": {
|
||||
"show": true,
|
||||
"display": false,
|
||||
"card_name": "weather",
|
||||
"temperature": "35°",
|
||||
"city": "SH",
|
||||
"date": "2020.09.04",
|
||||
"weather_info": "cloud",
|
||||
"image_src":"../../common/clouds.png"
|
||||
},
|
||||
"actions": {
|
||||
"router": {
|
||||
"action": "router",
|
||||
"bundleName": "com.example.helloworld",
|
||||
"bundleAbility": "com.example.helloworld.MainAbility"
|
||||
}
|
||||
}
|
||||
}
|
8
ace-loader/sample/lite/app.js
Normal file
8
ace-loader/sample/lite/app.js
Normal file
@ -0,0 +1,8 @@
|
||||
export default {
|
||||
onCreate() {
|
||||
console.info("AceApplication onCreate");
|
||||
},
|
||||
onDestroy() {
|
||||
console.info("AceApplication onDestroy");
|
||||
}
|
||||
};
|
11
ace-loader/sample/lite/manifest.json
Normal file
11
ace-loader/sample/lite/manifest.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"appID": "com.example.ace.helloworld",
|
||||
"appName": "HelloAce",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": 1,
|
||||
"minPlatformVersion": "zsdk 1.0.0",
|
||||
"pages": [
|
||||
"pages/index/index",
|
||||
"pages/detail/detail"
|
||||
]
|
||||
}
|
11
ace-loader/sample/lite/pages/detail/detail.css
Normal file
11
ace-loader/sample/lite/pages/detail/detail.css
Normal file
@ -0,0 +1,11 @@
|
||||
.commonStyle {
|
||||
left: 95px;
|
||||
top: 95px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin: 10px;
|
||||
padding: 30px;
|
||||
border-width: 1px;
|
||||
border-radius: 10px;
|
||||
background-color: #ff0000;
|
||||
}
|
11
ace-loader/sample/lite/pages/detail/detail.hml
Normal file
11
ace-loader/sample/lite/pages/detail/detail.hml
Normal file
@ -0,0 +1,11 @@
|
||||
<stack
|
||||
style="width: 444px;height: 444px;margin: 20px;border-width: 5px;border-color: #00ff00;border-radius: 10px;opacity: 0.5"
|
||||
>
|
||||
<text style="left:140px;top:50px;width:300px;height:40px">common style</text>
|
||||
<div class="commonStyle"></div>
|
||||
<image
|
||||
src="common/nextRow.bin"
|
||||
style="left:390px;top:227px;width:30px;height:42px"
|
||||
onclick="nextPage"
|
||||
/>
|
||||
</stack>
|
19
ace-loader/sample/lite/pages/detail/detail.js
Normal file
19
ace-loader/sample/lite/pages/detail/detail.js
Normal file
@ -0,0 +1,19 @@
|
||||
var router = require('@system.router')
|
||||
export default {
|
||||
data: {},
|
||||
nextPage () {
|
||||
router.replace({ uri: 'pages/chart/index' })
|
||||
},
|
||||
onInit () {
|
||||
console.log('onInit called...')
|
||||
},
|
||||
onReady () {
|
||||
console.log('onReady called...')
|
||||
},
|
||||
onShow () {
|
||||
console.log('onShow called...')
|
||||
},
|
||||
onDestroy () {
|
||||
console.log('onDestroy called...')
|
||||
}
|
||||
}
|
23
ace-loader/sample/lite/pages/index/index.css
Normal file
23
ace-loader/sample/lite/pages/index/index.css
Normal file
@ -0,0 +1,23 @@
|
||||
.btn .table {
|
||||
color: #ff0000;
|
||||
}
|
||||
.btn {
|
||||
height: 33px;
|
||||
}
|
||||
.table {
|
||||
width: 444px;
|
||||
}
|
||||
.container {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
width: 454px;
|
||||
height: 454px;
|
||||
}
|
||||
.title {
|
||||
font-size: 30px;
|
||||
text-align: center;
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
}
|
5
ace-loader/sample/lite/pages/index/index.hml
Normal file
5
ace-loader/sample/lite/pages/index/index.hml
Normal file
@ -0,0 +1,5 @@
|
||||
<div class="container">
|
||||
<text class="title">
|
||||
Hello {{title}}
|
||||
</text>
|
||||
</div>
|
5
ace-loader/sample/lite/pages/index/index.js
Normal file
5
ace-loader/sample/lite/pages/index/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
export default {
|
||||
data: {
|
||||
title: 'World'
|
||||
}
|
||||
}
|
8
ace-loader/sample/rich/app.js
Normal file
8
ace-loader/sample/rich/app.js
Normal file
@ -0,0 +1,8 @@
|
||||
export default {
|
||||
onCreate() {
|
||||
console.info('AceApplication onCreate');
|
||||
},
|
||||
onDestroy() {
|
||||
console.info('AceApplication onDestroy');
|
||||
}
|
||||
}
|
5
ace-loader/sample/rich/i18n/en.json
Normal file
5
ace-loader/sample/rich/i18n/en.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"message":{
|
||||
"hello": "hello world"
|
||||
}
|
||||
}
|
5
ace-loader/sample/rich/i18n/zh.json
Normal file
5
ace-loader/sample/rich/i18n/zh.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"message": {
|
||||
"hello": "你好世界"
|
||||
}
|
||||
}
|
15
ace-loader/sample/rich/manifest.json
Normal file
15
ace-loader/sample/rich/manifest.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"appID": "com.example.ace.helloworld",
|
||||
"appName": "HelloAce",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": 1,
|
||||
"minPlatformVersion": "1.0.1",
|
||||
"pages": [
|
||||
"pages/index/index",
|
||||
"pages/detail/detail"
|
||||
],
|
||||
"window": {
|
||||
"designWidth": 750,
|
||||
"autoDesignWidth": false
|
||||
}
|
||||
}
|
23
ace-loader/sample/rich/pages/detail/detail.css
Normal file
23
ace-loader/sample/rich/pages/detail/detail.css
Normal file
@ -0,0 +1,23 @@
|
||||
.container {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
.button-div {
|
||||
padding-top: 50px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.text-div {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
font-size: 30px;
|
||||
}
|
8
ace-loader/sample/rich/pages/detail/detail.hml
Normal file
8
ace-loader/sample/rich/pages/detail/detail.hml
Normal file
@ -0,0 +1,8 @@
|
||||
<div class="container">
|
||||
<div class="text-div">
|
||||
<text class="title">This is the detail page.</text>
|
||||
</div>
|
||||
<div class="button-div">
|
||||
<input type="button" value="Go back" class="button" onclick="launch"/>
|
||||
</div>
|
||||
</div>
|
11
ace-loader/sample/rich/pages/detail/detail.js
Normal file
11
ace-loader/sample/rich/pages/detail/detail.js
Normal file
@ -0,0 +1,11 @@
|
||||
import router from '@system.router'
|
||||
|
||||
export default {
|
||||
data: {
|
||||
},
|
||||
launch: function() {
|
||||
router.push ({
|
||||
uri:'pages/index/index',
|
||||
})
|
||||
}
|
||||
}
|
23
ace-loader/sample/rich/pages/index/index.css
Normal file
23
ace-loader/sample/rich/pages/index/index.css
Normal file
@ -0,0 +1,23 @@
|
||||
.container {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
.button-div {
|
||||
padding-top: 50px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.text-div {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
font-size: 30px;
|
||||
}
|
8
ace-loader/sample/rich/pages/index/index.hml
Normal file
8
ace-loader/sample/rich/pages/index/index.hml
Normal file
@ -0,0 +1,8 @@
|
||||
<div class="container">
|
||||
<div class="text-div">
|
||||
<text class="title">This is the index page.</text>
|
||||
</div>
|
||||
<div class="button-div">
|
||||
<input type="button" value="Go to the second page" class="button" onclick="launch"/>
|
||||
</div>
|
||||
</div>
|
11
ace-loader/sample/rich/pages/index/index.js
Normal file
11
ace-loader/sample/rich/pages/index/index.js
Normal file
@ -0,0 +1,11 @@
|
||||
import router from '@system.router';
|
||||
|
||||
export default {
|
||||
data: {
|
||||
},
|
||||
launch: function() {
|
||||
router.push ({
|
||||
uri:'pages/detail/detail',
|
||||
})
|
||||
}
|
||||
}
|
149
ace-loader/src/card-loader.js
Normal file
149
ace-loader/src/card-loader.js
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import {
|
||||
getRequireString,
|
||||
jsonLoaders,
|
||||
logWarn
|
||||
}
|
||||
from './util'
|
||||
import { parseFragment } from './parser'
|
||||
|
||||
function loader(source) {
|
||||
this.cacheable && this.cacheable()
|
||||
const options = {
|
||||
lang: {
|
||||
sass:['sass-loader'],
|
||||
scss:['sass-loader'],
|
||||
less:['less-loader']
|
||||
}
|
||||
}
|
||||
const customLang = options.lang || {}
|
||||
const resourcePath = this.resourcePath
|
||||
const fileName = resourcePath.replace(path.extname(resourcePath).toString(), '')
|
||||
let output = ''
|
||||
output = getRequireString(this, jsonLoaders('template'), resourcePath)
|
||||
const styleInfo = findStyleFile(fileName)
|
||||
if (styleInfo.extStyle == true) {
|
||||
output += getRequireString(this, jsonLoaders('style', customLang[styleInfo.type]), styleInfo.styleFileName)
|
||||
}
|
||||
output = addJson(this, output, fileName, '')
|
||||
|
||||
const frag = parseFragment(source)
|
||||
const nameSet = new Set()
|
||||
if (frag.element) {
|
||||
frag.element.forEach(item => {
|
||||
let customElementName
|
||||
if (!item.src) {
|
||||
logWarn(this, [{
|
||||
reason: `ERROR: The attribute 'src' must be set in the custom element.`,
|
||||
line: item.node.__location.line,
|
||||
column: item.node.__location.col
|
||||
}])
|
||||
return
|
||||
}
|
||||
if (!item.src.match(/\.hml$/)) {
|
||||
item.src = item.src.concat('.hml')
|
||||
}
|
||||
const compResourcepath = path.join(resourcePath, '..', item.src)
|
||||
if (!fs.existsSync(compResourcepath)) {
|
||||
logWarn(this, [{
|
||||
reason: `ERROR: The custom element '${compResourcepath}' can not be found.`,
|
||||
line: item.node.__location.line,
|
||||
column: item.node.__location.col
|
||||
}])
|
||||
return
|
||||
}
|
||||
if (!item.name) {
|
||||
customElementName = path.parse(item.src).name.toLowerCase()
|
||||
} else {
|
||||
customElementName = item.name.toLowerCase()
|
||||
}
|
||||
if (nameSet.has(customElementName)) {
|
||||
logWarn(this, [{
|
||||
reason: `ERROR: The custom elements cannot have the same attribute 'name' or file name (case insensitive).`,
|
||||
line: item.node.__location.line,
|
||||
column: item.node.__location.col
|
||||
}])
|
||||
return
|
||||
} else {
|
||||
nameSet.add(customElementName)
|
||||
}
|
||||
const compFileName = compResourcepath.replace(path.extname(compResourcepath).toString(), '')
|
||||
output += getRequireString(this, jsonLoaders('template'),
|
||||
compResourcepath + `?${customElementName}#${fileName}`)
|
||||
const compStyleInfo = findStyleFile(compFileName)
|
||||
if (compStyleInfo.extStyle == true) {
|
||||
output += getRequireString(this, jsonLoaders('style', customLang[compStyleInfo.type]),
|
||||
compStyleInfo.styleFileName + `?${customElementName}#${fileName}`)
|
||||
}
|
||||
output = addJson(this, output, compFileName, `?${customElementName}#${fileName}`)
|
||||
})
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
function findStyleFile (fileName) {
|
||||
let extStyle = false
|
||||
let styleFileName = fileName + '.css'
|
||||
let type = 'css'
|
||||
if (fs.existsSync(styleFileName)) {
|
||||
extStyle = true
|
||||
type = 'css'
|
||||
} else {
|
||||
styleFileName = fileName + '.less'
|
||||
if (fs.existsSync(styleFileName)) {
|
||||
extStyle = true
|
||||
type = 'less'
|
||||
} else {
|
||||
styleFileName = fileName + '.sass'
|
||||
if (fs.existsSync(styleFileName)) {
|
||||
extStyle = true
|
||||
type = 'sass'
|
||||
} else {
|
||||
styleFileName = fileName + '.scss'
|
||||
if (fs.existsSync(styleFileName)) {
|
||||
extStyle = true
|
||||
type = 'sass'
|
||||
} else {
|
||||
extStyle = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {extStyle: extStyle, styleFileName: styleFileName, type: type}
|
||||
}
|
||||
|
||||
function addJson(_this, output, fileName, query) {
|
||||
if (fs.existsSync(fileName + '.json') && !fs.existsSync(fileName + '.js')) {
|
||||
output += getRequireString(_this, jsonLoaders('json'), fileName + '.json' + query)
|
||||
} else if (fs.existsSync(fileName + '.js') && !fs.existsSync(fileName + '.json')) {
|
||||
logWarn(_this, [{
|
||||
reason: `WARNING: The JS file '${fileName}.js' will be discarded in future version, ` +
|
||||
`use the JSON file '${fileName}.json' instead.`,
|
||||
}])
|
||||
output += getRequireString(_this, jsonLoaders('json'), fileName + '.js' + query)
|
||||
} else if (fs.existsSync(fileName + '.json') && fs.existsSync(fileName + '.js')) {
|
||||
logWarn(_this, [{
|
||||
reason: `WARNING: '${fileName}' cannot have the same name files '.json' and '.js', otherwise '.json' in default.`,
|
||||
}])
|
||||
output += getRequireString(_this, jsonLoaders('json'), fileName + '.json' + query)
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
module.exports = loader
|
83
ace-loader/src/cardJson-plugin.js
Normal file
83
ace-loader/src/cardJson-plugin.js
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
let output = ''
|
||||
const initIndexJSONObject = { "template": {}, "styles": {}, "actions": {},"data":{} }
|
||||
|
||||
function compileJson(compiler, type, filePath, content, contentType, elementType) {
|
||||
compiler.hooks.done.tap(type + contentType, () => {
|
||||
if (type === 'init') {
|
||||
writeFileSync(filePath, initIndexJSONObject)
|
||||
} else {
|
||||
writeFileSync(filePath, content, contentType, elementType)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function writeFileSync(filePath, content, contentType, elementType) {
|
||||
if (!fs.existsSync(filePath)) {
|
||||
fs.writeFileSync(filePath, stringify(content))
|
||||
} else {
|
||||
const fileContent = fs.readFileSync(filePath, {encoding:'utf-8'})
|
||||
try {
|
||||
const jsonContent = JSON.parse(fileContent)
|
||||
if (contentType && !elementType) {
|
||||
jsonContent[contentType] = content ? content : {}
|
||||
fs.writeFileSync(filePath, stringify(jsonContent))
|
||||
} else if (contentType && elementType) {
|
||||
if (!jsonContent[contentType]) {
|
||||
jsonContent[contentType] = {}
|
||||
}
|
||||
jsonContent[contentType][elementType] = content ? content : {}
|
||||
fs.writeFileSync(filePath, stringify(jsonContent))
|
||||
}
|
||||
} catch (e) {
|
||||
fs.writeFileSync(filePath, stringify(initIndexJSONObject))
|
||||
writeFileSync(filePath, content, contentType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function stringify (jsonObect) {
|
||||
return JSON.stringify(jsonObect, null, 2)
|
||||
}
|
||||
|
||||
class AfterEmitPlugin {
|
||||
constructor(output_) {
|
||||
output = output_
|
||||
}
|
||||
|
||||
apply(compiler) {
|
||||
compiler.hooks.afterEmit.tap('delete', (compilation) => {
|
||||
const assets = compilation.assets
|
||||
const keys = Object.keys(assets)
|
||||
keys.forEach(key => {
|
||||
if (fs.existsSync(path.resolve(output, key))) {
|
||||
if (key.indexOf('i18n') !== 0) {
|
||||
fs.unlinkSync(path.resolve(output, key))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
compileJson: compileJson,
|
||||
AfterEmitPlugin: AfterEmitPlugin
|
||||
}
|
159
ace-loader/src/compile-plugin.js
Normal file
159
ace-loader/src/compile-plugin.js
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const Stats = require('webpack/lib/Stats');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { DEVICE_LEVEL } = require('./lite/lite-enum');
|
||||
|
||||
const REG = /\([^\)]+\)/;
|
||||
let mStats;
|
||||
let mErrorCount = 0;
|
||||
let mWarningCount = 0;
|
||||
let isShowError = true;
|
||||
let isShowWarning = true;
|
||||
let isShowNote = true;
|
||||
let warningCount = 0;
|
||||
let noteCount = 0;
|
||||
let errorCount = 0;
|
||||
|
||||
class ResultStates {
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
apply(compiler) {
|
||||
const buildPath = this.options.build;
|
||||
compiler.hooks.done.tap('Result States', (stats) => {
|
||||
mStats = stats;
|
||||
warningCount = 0;
|
||||
noteCount = 0;
|
||||
errorCount = 0;
|
||||
if (mStats.compilation.errors) {
|
||||
mErrorCount = mStats.compilation.errors.length;
|
||||
}
|
||||
if (mStats.compilation.warnings) {
|
||||
mWarningCount = mStats.compilation.warnings.length;
|
||||
}
|
||||
if (process.env.error === 'false') {
|
||||
isShowError = false;
|
||||
}
|
||||
if (process.env.warning === 'false') {
|
||||
isShowWarning = false;
|
||||
}
|
||||
if (process.env.note === 'false') {
|
||||
isShowNote = false;
|
||||
}
|
||||
printResult(buildPath);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const red = '\u001b[31m';
|
||||
const yellow = '\u001b[33m';
|
||||
const blue = '\u001b[34m';
|
||||
const reset = '\u001b[39m';
|
||||
|
||||
const writeError = (buildPath, content) => {
|
||||
fs.writeFile(path.resolve(buildPath, 'compile_error.log'), content, (err) => {
|
||||
if (err) {
|
||||
return console.error(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function printResult(buildPath) {
|
||||
printWarning();
|
||||
printError(buildPath);
|
||||
if (errorCount + warningCount + noteCount > 0) {
|
||||
let result;
|
||||
const resultInfo = {};
|
||||
if (errorCount > 0) {
|
||||
resultInfo.ERROR = errorCount;
|
||||
result = 'FAIL ';
|
||||
} else {
|
||||
result = 'SUCCESS ';
|
||||
}
|
||||
if (warningCount > 0) {
|
||||
resultInfo.WARN = warningCount;
|
||||
}
|
||||
|
||||
if (noteCount > 0) {
|
||||
resultInfo.NOTE = noteCount;
|
||||
}
|
||||
console.log(blue, 'COMPILE RESULT:' + result + JSON.stringify(resultInfo), reset);
|
||||
} else {
|
||||
console.log(blue, 'COMPILE RESULT:SUCCESS ', reset);
|
||||
}
|
||||
}
|
||||
|
||||
function printWarning() {
|
||||
if (mWarningCount > 0) {
|
||||
const warnings = mStats.compilation.warnings;
|
||||
const length = warnings.length;
|
||||
for (let index = 0; index < length; index++) {
|
||||
let message = warnings[index].message
|
||||
if (message.match(/noteStart(([\s\S])*)noteEnd/) !== null) {
|
||||
noteCount++;
|
||||
if (isShowNote) {
|
||||
console.info(' ' + message.match(/noteStart(([\s\S])*)noteEnd/)[1].trim(), reset, '\n')
|
||||
}
|
||||
} else if (message.match(/warnStart(([\s\S])*)warnEnd/) !== null) {
|
||||
warningCount++;
|
||||
if (isShowWarning) {
|
||||
console.warn(yellow, message.match(/warnStart(([\s\S])*)warnEnd/)[1].trim(), reset, '\n')
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mWarningCount > length) {
|
||||
warningCount = warningCount + mWarningCount - length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function printError(buildPath) {
|
||||
if (mErrorCount > 0) {
|
||||
const errors = mStats.compilation.errors;
|
||||
const length = errors.length;
|
||||
if (isShowError) {
|
||||
let errorContent = '';
|
||||
for (let index = 0; index < length; index++) {
|
||||
if (errors[index]) {
|
||||
let message = errors[index].message
|
||||
if (message) {
|
||||
if (message.match(/errorStart(([\s\S])*)errorEnd/) !== null) {
|
||||
const errorMessage = message.match(/errorStart(([\s\S])*)errorEnd/)[1];
|
||||
console.error(red, errorMessage.trim(), reset, '\n');
|
||||
} else {
|
||||
const messageArrary = message.split('\n')
|
||||
let logContent = ''
|
||||
messageArrary.forEach(element => {
|
||||
if (!(/^at/.test(element.trim()))) {
|
||||
logContent = logContent + element + '\n'
|
||||
}
|
||||
});
|
||||
console.error(red, logContent, reset, '\n');
|
||||
}
|
||||
errorCount ++;
|
||||
errorContent += message
|
||||
}
|
||||
}
|
||||
}
|
||||
writeError(buildPath, errorContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ResultStates;
|
38
ace-loader/src/extgen.js
Normal file
38
ace-loader/src/extgen.js
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import loaderUtils from 'loader-utils'
|
||||
const codegen = require("./codegen/index.js");
|
||||
|
||||
module.exports = function (source, map) {
|
||||
this.cacheable && this.cacheable()
|
||||
const callback = this.async()
|
||||
|
||||
const hmlCss = codegen.genHmlAndCss(source);
|
||||
const loaderQuery = loaderUtils.getOptions(this) || {}
|
||||
if (hmlCss.errorType && hmlCss.errorType !== '' && loaderQuery.type === 'template') {
|
||||
callback(hmlCss.errorType + ' : ' + hmlCss.errorMessage, '')
|
||||
} else {
|
||||
if(loaderQuery.type === 'template') {
|
||||
callback(null, hmlCss.hmlCss.hml, map)
|
||||
} else {
|
||||
callback(null, hmlCss.hmlCss.css, map)
|
||||
}
|
||||
}
|
||||
}
|
136
ace-loader/src/genAbc-plugin.js
Normal file
136
ace-loader/src/genAbc-plugin.js
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const process = require('child_process')
|
||||
const js2abc = path.join(__dirname, '..', 'bin', 'panda', 'build', 'src', 'index.js')
|
||||
const js2abc_win = path.join(__dirname, '..', 'bin', 'panda', 'build-win', 'src', 'index.js')
|
||||
const js2abc_mac = path.join(__dirname, '..', 'bin', 'panda', 'build-mac', 'src', 'index.js')
|
||||
const libraryPath = path.join(__dirname, '..', 'bin', 'panda', 'build', 'panda', 'lib')
|
||||
const libraryJsonPath = path.join(__dirname, '..', 'bin', 'panda', 'build','lib')
|
||||
|
||||
const forward = '(global.___mainEntry___ = function (globalObjects) {' + '\n' +
|
||||
' var define = globalObjects.define;' + '\n' +
|
||||
' var require = globalObjects.require;' + '\n' +
|
||||
' var bootstrap = globalObjects.bootstrap;' + '\n' +
|
||||
' var register = globalObjects.register;' + '\n' +
|
||||
' var render = globalObjects.render;' + '\n' +
|
||||
' var $app_define$ = globalObjects.$app_define$;' + '\n' +
|
||||
' var $app_bootstrap$ = globalObjects.$app_bootstrap$;' + '\n' +
|
||||
' var $app_require$ = globalObjects.$app_require$;' + '\n' +
|
||||
' var history = globalObjects.history;' + '\n' +
|
||||
' var Image = globalObjects.Image;' + '\n' +
|
||||
' var OffscreenCanvas = globalObjects.OffscreenCanvas;' + '\n' +
|
||||
' (function(global) {' + '\n' +
|
||||
' "use strict";' + '\n'
|
||||
const last = '\n' + '})(this.__appProto__);' + '\n' + '})'
|
||||
const firstFileEXT = '_.js'
|
||||
let output
|
||||
let webpackPath
|
||||
let isWin = false
|
||||
let isMac = false
|
||||
let isDebug = false
|
||||
|
||||
class GenAbcPlugin {
|
||||
constructor(output_, webpackPath_, isDebug_) {
|
||||
output = output_
|
||||
webpackPath = webpackPath_
|
||||
isDebug = isDebug_
|
||||
}
|
||||
apply(compiler) {
|
||||
if (fs.existsSync(path.resolve(webpackPath, 'panda/build-win'))) {
|
||||
isWin = true
|
||||
} else {
|
||||
if (fs.existsSync(path.resolve(webpackPath, 'panda/build-mac'))) {
|
||||
isMac = true
|
||||
} else {
|
||||
if (!fs.existsSync(path.resolve(webpackPath, 'panda/build'))) {
|
||||
console.error('\u001b[31m', `find build fail`, '\u001b[39m')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compiler.hooks.emit.tap('GenAbcPlugin', (compilation) => {
|
||||
const assets = compilation.assets
|
||||
const keys = Object.keys(assets)
|
||||
keys.forEach(key => {
|
||||
// choice *.js
|
||||
if (output && webpackPath && path.extname(key) === '.js') {
|
||||
const newContent = forward + assets[key].source() + last
|
||||
const keyPath = key.replace(/\.js$/, firstFileEXT)
|
||||
writeFileSync(newContent, path.resolve(output, keyPath), key)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function writeFileSync(inputString, output, jsBundleFile) {
|
||||
const parent = path.join(output, '..')
|
||||
if (!(fs.existsSync(parent) && fs.statSync(parent).isDirectory())) {
|
||||
mkDir(parent)
|
||||
}
|
||||
fs.writeFileSync(output, inputString)
|
||||
if (fs.existsSync(output)){
|
||||
qjscFirst(output)
|
||||
} else {
|
||||
console.error('\u001b[31m', `Failed to convert file ${jsBundleFile} to bin. ${output} is lost`, '\u001b[39m')
|
||||
}
|
||||
}
|
||||
|
||||
function mkDir(path_) {
|
||||
const parent = path.join(path_, '..')
|
||||
if (!(fs.existsSync(parent) && !fs.statSync(parent).isFile())) {
|
||||
mkDir(parent)
|
||||
}
|
||||
fs.mkdirSync(path_)
|
||||
}
|
||||
|
||||
function qjscFirst(inputPath) {
|
||||
let param = '-r'
|
||||
if (isDebug) {
|
||||
param += ' --debug'
|
||||
}
|
||||
let cmd
|
||||
if (isWin) {
|
||||
cmd = `node --expose-gc "${js2abc_win}" "${inputPath}" ${param}`
|
||||
} else if (isMac){
|
||||
cmd = `node --expose-gc "${js2abc_mac}" "${inputPath}" ${param}`
|
||||
} else {
|
||||
cmd = `export LD_LIBRARY_PATH="${libraryPath}":"${libraryJsonPath}":$LD_LIBRARY_PATH;node --expose-gc "${js2abc}" "${inputPath}" ${param}`
|
||||
}
|
||||
try {
|
||||
process.execSync(cmd)
|
||||
console.info(cmd)
|
||||
} catch (e) {
|
||||
console.error('\u001b[31m', `Failed to convert file ${inputPath} to abc`, '\u001b[39m')
|
||||
}
|
||||
if (fs.existsSync(inputPath)) {
|
||||
fs.unlinkSync(inputPath)
|
||||
} else {
|
||||
console.error('\u001b[31m', `Failed to convert file ${inputPath} to abc. ${inputPath} is lost`, '\u001b[39m')
|
||||
}
|
||||
let abcFile = inputPath.replace(/\.js$/, '.abc');
|
||||
if (fs.existsSync(abcFile)) {
|
||||
let abcFileNew = abcFile.replace(/\_.abc$/, '.abc');
|
||||
fs.renameSync(abcFile, abcFileNew)
|
||||
} else {
|
||||
console.error('\u001b[31m', `${abcFile} is lost`, '\u001b[39m')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GenAbcPlugin
|
127
ace-loader/src/genBin-plugin.js
Normal file
127
ace-loader/src/genBin-plugin.js
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const process = require('child_process')
|
||||
const qjsc = path.join(__dirname, '..', 'bin', 'qjsc')
|
||||
|
||||
const forward = '(global.___mainEntry___ = function (globalObjects) {' + '\n' +
|
||||
' const define = globalObjects.define;' + '\n' +
|
||||
' const require = globalObjects.require;' + '\n' +
|
||||
' const bootstrap = globalObjects.bootstrap;' + '\n' +
|
||||
' const register = globalObjects.register;' + '\n' +
|
||||
' const render = globalObjects.render;' + '\n' +
|
||||
' const $app_define$ = globalObjects.$app_define$;' + '\n' +
|
||||
' const $app_bootstrap$ = globalObjects.$app_bootstrap$;' + '\n' +
|
||||
' const $app_require$ = globalObjects.$app_require$;' + '\n' +
|
||||
' const history = globalObjects.history;' + '\n' +
|
||||
' const Image = globalObjects.Image;' + '\n' +
|
||||
' const OffscreenCanvas = globalObjects.OffscreenCanvas;' + '\n' +
|
||||
' (function(global) {' + '\n' +
|
||||
' "use strict";' + '\n'
|
||||
const last = '\n' + '})(this.__appProto__);' + '\n' + '})'
|
||||
const firstFileEXT = '.jtc'
|
||||
const sencondFileEXT = '.c'
|
||||
const lastFileEXT = '.bin'
|
||||
let output
|
||||
let webpackPath
|
||||
|
||||
class GenBinPlugin {
|
||||
constructor(output_, webpackPath_) {
|
||||
output = output_
|
||||
webpackPath = webpackPath_
|
||||
}
|
||||
apply(compiler) {
|
||||
if (!fs.existsSync(path.resolve(webpackPath, 'qjsc.exe')) && !fs.existsSync(path.resolve(webpackPath, 'qjsc'))) {
|
||||
return
|
||||
}
|
||||
compiler.hooks.emit.tap('GenBinPlugin', (compilation) => {
|
||||
const assets = compilation.assets
|
||||
const keys = Object.keys(assets)
|
||||
keys.forEach(key => {
|
||||
// choice *.js
|
||||
if (output && webpackPath && path.extname(key) === '.js') {
|
||||
const newContent = forward + assets[key].source() + last
|
||||
const keyPath = key.replace(/\.js$/, firstFileEXT)
|
||||
writeFileSync(newContent, path.resolve(output, keyPath), key)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function writeFileSync(inputString, output, jsBundleFile) {
|
||||
const parent = path.join(output, '..')
|
||||
if (!(fs.existsSync(parent) && fs.statSync(parent).isDirectory())) {
|
||||
mkDir(parent)
|
||||
}
|
||||
fs.writeFileSync(output, inputString)
|
||||
if (fs.existsSync(output)){
|
||||
qjscFirst(output, output.replace(/\.jtc$/, sencondFileEXT))
|
||||
} else {
|
||||
console.error('\u001b[31m', `Failed to convert file ${jsBundleFile} to bin. ${output} is lost`, '\u001b[39m')
|
||||
}
|
||||
}
|
||||
|
||||
function mkDir(path_) {
|
||||
const parent = path.join(path_, '..')
|
||||
if (!(fs.existsSync(parent) && !fs.statSync(parent).isFile())) {
|
||||
mkDir(parent)
|
||||
}
|
||||
fs.mkdirSync(path_)
|
||||
}
|
||||
|
||||
function qjscFirst(inputPath, outputPath) {
|
||||
const cmd = `"${qjsc}" -o "${outputPath}" -N buf -c "${inputPath}"`
|
||||
try {
|
||||
process.execSync(cmd)
|
||||
} catch (e) {
|
||||
console.error('\u001b[31m', `Failed to convert file ${inputPath} to bin`, '\u001b[39m')
|
||||
}
|
||||
if (fs.existsSync(inputPath)) {
|
||||
fs.unlinkSync(inputPath)
|
||||
qjscSecond(outputPath)
|
||||
} else {
|
||||
console.error('\u001b[31m', `Failed to convert file ${inputPath} to bin. ${inputPath} is lost`, '\u001b[39m')
|
||||
}
|
||||
}
|
||||
|
||||
function qjscSecond(filePath) {
|
||||
let data = fs.readFileSync(filePath, 'utf8')
|
||||
data = data.substr(data.indexOf('{') + 1, data.indexOf('}') - data.indexOf('{') - 1).trim()
|
||||
const lastFilePath = filePath.replace(/\.c$/, lastFileEXT)
|
||||
const parent = path.join(lastFilePath, '..')
|
||||
if (!(fs.existsSync(parent) && fs.statSync(parent).isDirectory())) {
|
||||
mkDir(parent)
|
||||
}
|
||||
fs.writeFileSync(lastFilePath, toBuffer(data))
|
||||
if (fs.existsSync(filePath)) {
|
||||
fs.unlinkSync(filePath)
|
||||
} else {
|
||||
console.error('\u001b[31m', `Failed to clean file ${filePath}.`, '\u001b[39m')
|
||||
}
|
||||
}
|
||||
|
||||
function toBuffer(str) {
|
||||
const bytes = str.split(',')
|
||||
const b = Buffer.alloc(bytes.length)
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
b[i] = bytes[i]
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
module.exports = GenBinPlugin
|
87
ace-loader/src/lite/lite-customize.js
Normal file
87
ace-loader/src/lite/lite-customize.js
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const isType = require('./lite-utils');
|
||||
/**
|
||||
* Check if the custom file exists.If it does not exist, follow the normal process.
|
||||
* If it exists, get the file content.
|
||||
*/
|
||||
function checkFilePath() {
|
||||
const rulePath = path.resolve(os.userInfo().homedir, '.literc.js');
|
||||
if (fs.existsSync(rulePath)) {
|
||||
process.env.RULE_PATH = rulePath;
|
||||
const customTag = require(rulePath);
|
||||
checkContent(customTag);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check if the object thrown by the file is correct.
|
||||
* @param {Object} customTag User defined custom file content.
|
||||
*/
|
||||
function checkContent(customTag) {
|
||||
throwError(
|
||||
!isType.isObject(customTag),
|
||||
`The configuration in the '.literc.js' file is incorrect.(it should be an object.)`,
|
||||
);
|
||||
throwError(
|
||||
isType.isUndefined(customTag.rules),
|
||||
`You must write the 'rules' attribute in '.literc.js' file`,
|
||||
);
|
||||
throwError(
|
||||
!isType.isObject(customTag.rules),
|
||||
`The value of 'rules' in '.literc.js' file is incorrect.(it should be an object)`,
|
||||
);
|
||||
if (customTag.extends == 'recommended') {
|
||||
validatorCustomTag(customTag.rules);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the user-defined rules are correct.
|
||||
* @param {Object} rules User defined custom file content.
|
||||
*/
|
||||
function validatorCustomTag(rules) {
|
||||
const keys = Object.keys(rules);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
const value = rules[key];
|
||||
throwError(
|
||||
!isType.isObject(value),
|
||||
`The value of '${key}' is incorrect, it should be an object.`,
|
||||
);
|
||||
const childs = Object.keys(value);
|
||||
for (let j = 0; j < childs.length; j++) {
|
||||
const child = childs[j];
|
||||
throwError(
|
||||
child != 'attrs',
|
||||
`'${key}' object can only contain 'attrs' attributes`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Tool method, if the condition is true, throw an exception.
|
||||
* @param {Boolean} condition Analyzing conditions.
|
||||
* @param {String} reason Output wrong information.
|
||||
*/
|
||||
function throwError(condition, reason) {
|
||||
if (condition) {
|
||||
throw Error(`\u001b[31mError: ${reason} \u001b[39m`).message;
|
||||
}
|
||||
}
|
||||
exports.checkFilePath = checkFilePath;
|
63
ace-loader/src/lite/lite-enum.js
Normal file
63
ace-loader/src/lite/lite-enum.js
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const SPECIAL_STYLE = {
|
||||
OPACITY: 'opacity',
|
||||
BORDEROPACITY: 'borderOpacity',
|
||||
ANIMATION_DELAY: 'animationDelay',
|
||||
ANIMATION_DURATION: 'animationDuration',
|
||||
ANIMATION_ITERATION_COUNT: 'animationIterationCount',
|
||||
BACKGROUND_IMAGE: 'backgroundImage',
|
||||
BACKGROUND_IMAGE_ACTIVE: 'backgroundImage:active',
|
||||
BACKGROUND_IMAGE_CHECKED: 'backgroundImage:checked',
|
||||
};
|
||||
const DEVICE_LEVEL = {
|
||||
RICH: 'rich',
|
||||
LITE: 'lite',
|
||||
CARD: 'card',
|
||||
};
|
||||
const DEVICE_TYPE = {
|
||||
LITEWEARABLE: 'liteWearable',
|
||||
SMARTVISION: 'smartVision',
|
||||
};
|
||||
|
||||
const PLATFORM = {
|
||||
VERSION3: 'Version3',
|
||||
VERSION4: 'Version4',
|
||||
VERSION5: 'Version5',
|
||||
VERSION6: 'Version6',
|
||||
};
|
||||
|
||||
const REGEXP_NUMBER_PX = /^[-+]?[0-9]*\.?[0-9]+(px|cm|em|deg|rad)?$/;
|
||||
const REGEXP_COLOR = /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/;
|
||||
const REGEXP_UNIT = /px|cm|em|deg|rad/;
|
||||
const REGEXP_PNG = /(\.png|\.jpg|\.bmp|\.jpeg|\.BMP|\.JPG|\.PNG|\.JPEG)$/;
|
||||
const REGXP_QUOTES = /"|'/g;
|
||||
const REGXP_LANGUAGE = /\$t/;
|
||||
const REGXP_LANGUAGE_KEY = /_vm\.\$t\([^()]+?\)/g;
|
||||
const REGXP_FUNC_RETURN = /return(.*)}/g;
|
||||
|
||||
exports.SPECIAL_STYLE = SPECIAL_STYLE;
|
||||
exports.REGEXP_NUMBER_PX = REGEXP_NUMBER_PX;
|
||||
exports.REGEXP_COLOR = REGEXP_COLOR;
|
||||
exports.REGEXP_UNIT = REGEXP_UNIT;
|
||||
exports.DEVICE_LEVEL = DEVICE_LEVEL;
|
||||
exports.REGEXP_PNG = REGEXP_PNG;
|
||||
exports.REGXP_QUOTES = REGXP_QUOTES;
|
||||
exports.DEVICE_TYPE = DEVICE_TYPE;
|
||||
exports.REGXP_LANGUAGE = REGXP_LANGUAGE;
|
||||
exports.REGXP_LANGUAGE_KEY = REGXP_LANGUAGE_KEY;
|
||||
exports.REGXP_FUNC_RETURN = REGXP_FUNC_RETURN;
|
||||
exports.PLATFORM = PLATFORM;
|
85
ace-loader/src/lite/lite-image-coverter-plugin.js
Normal file
85
ace-loader/src/lite/lite-image-coverter-plugin.js
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const _path = require('path');
|
||||
const fs = require('fs');
|
||||
const registerRequireContextHook = require('babel-plugin-require-context-hook/register');
|
||||
const { REGEXP_PNG } = require('./lite-enum');
|
||||
const iconPath = process.env.iconPath || '';
|
||||
const img2bin = require('./lite-image2bin');
|
||||
|
||||
registerRequireContextHook();
|
||||
/**
|
||||
* Convert picture to bin format.
|
||||
*/
|
||||
class ImageCoverterPlugin {
|
||||
/**
|
||||
* constructor of the ImageCoverterPlugin class.
|
||||
* @param {String} options The object of build folder.
|
||||
*/
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
/**
|
||||
* Find all image paths in png、jpg、bmp、jpeg format in the directory.
|
||||
* @param {String} buildPath The path of build folder.
|
||||
* @return {Array} Image path array.
|
||||
*/
|
||||
getDir(buildPath) {
|
||||
const pngPath = global.__requireContext('', buildPath, true, REGEXP_PNG);
|
||||
const pathArray = pngPath.keys().map((element) => {
|
||||
return _path.join(buildPath, element);
|
||||
});
|
||||
return pathArray;
|
||||
}
|
||||
/**
|
||||
* Convert image format asynchronously, return code 0 successfully, otherwise return 1.
|
||||
* @param {Object} compiler API specification, all configuration information of Webpack environment.
|
||||
*/
|
||||
apply(compiler) {
|
||||
const buildPath = this.options.build;
|
||||
const getDir = this.getDir;
|
||||
compiler.hooks.done.tap('image coverter', function(compilation, callback) {
|
||||
const pathArray = getDir(buildPath);
|
||||
const writeResult = (content) => {
|
||||
fs.writeFile(_path.resolve(buildPath, 'image_convert_result.txt'), content, (err) => {
|
||||
if (err) {
|
||||
return console.error(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
const totalImageCount = pathArray.length;
|
||||
if (totalImageCount > 0) {
|
||||
const promiseArray = pathArray.map((path) => {
|
||||
return img2bin(path);
|
||||
});
|
||||
Promise.all(promiseArray).then(() => {
|
||||
writeResult('{exitCode:0}');
|
||||
}).catch(() => {
|
||||
writeResult('{exitCode:1}');
|
||||
});
|
||||
} else {
|
||||
writeResult('{exitCode:0}');
|
||||
}
|
||||
if (iconPath !== '') {
|
||||
const iconArray = getDir(iconPath);
|
||||
iconArray.forEach((path) => {
|
||||
img2bin(path);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
module.exports = ImageCoverterPlugin;
|
76
ace-loader/src/lite/lite-image2bin.js
Normal file
76
ace-loader/src/lite/lite-image2bin.js
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const Jimp = require('jimp');
|
||||
const fs = require('fs');
|
||||
const _path = require('path');
|
||||
/**
|
||||
* Find all image paths in png、jpg、bmp、jpeg format in the directory.
|
||||
* @param {String} imgPath The path of build folder.
|
||||
* @return {Array} Image path array.
|
||||
*/
|
||||
async function img2bin(imgPath) {
|
||||
try {
|
||||
const image = await Jimp.read(imgPath);
|
||||
const HEAD_SIZE = 8;
|
||||
const PIXEL_SIZE = 4;// BRGA
|
||||
const DATA_SIZE = image.bitmap.width * image.bitmap.height * PIXEL_SIZE;
|
||||
const binSize = HEAD_SIZE + DATA_SIZE;
|
||||
const binBuffer = new ArrayBuffer(binSize);
|
||||
const binView = new DataView(binBuffer);
|
||||
|
||||
const COLOR_MODE = 1 << 8 + 0;
|
||||
const WIDTH_BIT_OFFSET = 0;
|
||||
const HEIGHT_BIT_OFFSET = 16;
|
||||
const header = (image.bitmap.width << WIDTH_BIT_OFFSET) +
|
||||
(image.bitmap.height << HEIGHT_BIT_OFFSET);
|
||||
|
||||
let binFileOffset = 0;
|
||||
binView.setUint32(binFileOffset, COLOR_MODE, true);
|
||||
binFileOffset += 4;
|
||||
binView.setUint32(binFileOffset, header, true);
|
||||
binFileOffset += 4;
|
||||
|
||||
image.scan(0, 0, image.bitmap.width, image.bitmap.height, function(x, y, idx) {
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
const blue = this.bitmap.data[idx + 2];
|
||||
binView.setUint8(binFileOffset, blue, true);
|
||||
binFileOffset += 1;
|
||||
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
const green = this.bitmap.data[idx + 1];
|
||||
binView.setUint8(binFileOffset, green, true);
|
||||
binFileOffset += 1;
|
||||
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
const red = this.bitmap.data[idx + 0];
|
||||
binView.setUint8(binFileOffset, red, true);
|
||||
binFileOffset += 1;
|
||||
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
const alpha = this.bitmap.data[idx + 3];
|
||||
binView.setUint8(binFileOffset, alpha, true);
|
||||
binFileOffset += 1;
|
||||
});
|
||||
const binPath = imgPath.replace(/(\.png|\.jpg|\.bmp|\.jpeg|\.BMP|\.JPG|\.PNG|\.JPEG)$/, '.bin');
|
||||
fs.writeFileSync(binPath, Buffer.from(binBuffer));
|
||||
} catch (err) {
|
||||
const imageName = _path.basename(imgPath);
|
||||
console.error('\u001b[31m', `Failed to convert image ${imageName}.`, '\u001b[39m');
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = img2bin;
|
45
ace-loader/src/lite/lite-return-exports-plugin.js
Normal file
45
ace-loader/src/lite/lite-return-exports-plugin.js
Normal file
@ -0,0 +1,45 @@
|
||||
const pluginName = 'LiteReturnExportsPlugin';
|
||||
|
||||
/**
|
||||
* LiteReturnExportsPlugin
|
||||
*/
|
||||
class LiteReturnExportsPlugin {
|
||||
/**
|
||||
* return exports from runtime
|
||||
* @param {Object} compiler API specification, all configuration information of Webpack environment.
|
||||
*/
|
||||
apply(compiler) {
|
||||
compiler.hooks.compilation.tap('SourcemapFixer', compilation => {
|
||||
compilation.hooks.afterProcessAssets.tap('SourcemapFixer', assets => {
|
||||
Reflect.ownKeys(assets).forEach(key => {
|
||||
if (key.toString().includes('.map') && assets[key] && assets[key]._value) {
|
||||
const sourceMapSources = JSON.parse(assets[key]._value).sources;
|
||||
sourceMapSources.forEach((sourceMapSource, index) => {
|
||||
sourceMapSource = sourceMapSource.replace(/\\/g,"/")
|
||||
.replace(/webpack:\/\/\/[A-Z]:/g, function(a){return a.toLowerCase();});
|
||||
sourceMapSources[index] = sourceMapSource;
|
||||
});
|
||||
const REG_SOURCES = new RegExp(/"sources":\[.*?\]/);
|
||||
assets[key]._value = assets[key]._value.toString().replace(REG_SOURCES,
|
||||
'"sources":' + JSON.stringify(sourceMapSources));
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const { returnExportsFromRuntime } = compiler.webpack.RuntimeGlobals;
|
||||
|
||||
compiler.hooks.compilation.tap(pluginName, () => {
|
||||
compiler.webpack.RuntimeGlobals.returnExportsFromRuntime = '__webpack_exports__';
|
||||
});
|
||||
|
||||
compiler.hooks.afterCompile.tapAsync(pluginName, (_, callback) => {
|
||||
compiler.webpack.RuntimeGlobals.returnExportsFromRuntime = returnExportsFromRuntime;
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = LiteReturnExportsPlugin;
|
||||
|
68
ace-loader/src/lite/lite-snapshot-plugin.js
Normal file
68
ace-loader/src/lite/lite-snapshot-plugin.js
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const _require = require('child_process');
|
||||
const exec = _require.exec;
|
||||
const _path = require('path');
|
||||
const snapshot = _path.join(__dirname, '..', '..', 'bin', 'jerry-snapshot');
|
||||
const registerRequireContextHook = require('babel-plugin-require-context-hook/register');
|
||||
registerRequireContextHook();
|
||||
/**
|
||||
* Convert Javascript file to snapshot.
|
||||
*/
|
||||
class SnapshotPlugin {
|
||||
/**
|
||||
* constructor of the SnapshotPlugin class.
|
||||
* @param {String} options The object of build folder.
|
||||
*/
|
||||
constructor(options) {
|
||||
this.options = options;
|
||||
}
|
||||
/**
|
||||
* Find all javacript file paths in the directory.
|
||||
* @param {Object} assets the object of javacript file path.
|
||||
* @param {String} buildPath The path of build folder.
|
||||
* @return {Array} Image path array.
|
||||
*/
|
||||
getDir(assets, buildPath) {
|
||||
const pathArray = [];
|
||||
Object.keys(assets).map((item) => {
|
||||
if (/.js$/.test(item)) {
|
||||
pathArray.push(_path.join(buildPath, item));
|
||||
}
|
||||
});
|
||||
return pathArray;
|
||||
};
|
||||
/**
|
||||
* Convert javacript file asynchronously. If an error occurs, print an error message.
|
||||
* @param {Object} compiler API specification, all configuration information of Webpack environment.
|
||||
*/
|
||||
apply(compiler) {
|
||||
const buildPath = this.options.build;
|
||||
compiler.hooks.done.tap('snapshot coverter', (stats) => {
|
||||
const pathArray = this.getDir(stats.compilation.assets, buildPath);
|
||||
pathArray.forEach((element) => {
|
||||
const bcPath = element.replace('.js', '.bc');
|
||||
const fileName = _path.basename(element);
|
||||
exec(`"${snapshot}" generate -o "${bcPath}" "${element}"`, (error) => {
|
||||
if (error) {
|
||||
console.error('\u001b[31m', `Failed to convert the ${fileName} file to a snapshot.`, '\u001b[39m');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
module.exports = SnapshotPlugin;
|
179
ace-loader/src/lite/lite-transform-style.js
Normal file
179
ace-loader/src/lite/lite-transform-style.js
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Customize the compiled style code into a styleSheet object, styleSheet object is divided into two parts, idSelectors
|
||||
* and classSelectors. There are some detailed rules to explain:
|
||||
* 1. Remove the "." And "#" symbols in front of the class selector and id selector;
|
||||
* 2. Convert all numeric strings to numbers, such as:"32px" convert to number 32; "11" convert to number 11;
|
||||
* 3. Convert all hex color to decimal number;
|
||||
* 4. Convert all boolean strings to boolean type;
|
||||
*/
|
||||
const { SPECIAL_STYLE, REGEXP_NUMBER_PX, REGEXP_COLOR, REGEXP_UNIT, REGXP_QUOTES } = require('./lite-enum');
|
||||
|
||||
/**
|
||||
* Split style into id Selectors and classSelectors.
|
||||
* @param {Obejct} value Preliminary compilation results of css files.
|
||||
* @return {String} String result stylesheet.
|
||||
*/
|
||||
function transformStyle(value) {
|
||||
const style = Function(`return ${value}`)();
|
||||
const idSelectors = {};
|
||||
const classSelectors = {};
|
||||
const styleSheet = {};
|
||||
let res = '';
|
||||
const KEYFRAMES = '@KEYFRAMES';
|
||||
const keys = Object.keys(style);
|
||||
for (const key of keys) {
|
||||
if (key.charAt(0) === '.') {
|
||||
classSelectors[key.slice(1)] = styleFormat(style[key]);
|
||||
} else if (key.charAt(0) === '#') {
|
||||
idSelectors[key.slice(1)] = styleFormat(style[key]);
|
||||
} else if (key === KEYFRAMES) {
|
||||
styleSheet['@keyframes'] = keyFrameFormat(style[key]);
|
||||
} else {
|
||||
// todo: Label style
|
||||
}
|
||||
}
|
||||
if (style != null && keys.length !== 0) {
|
||||
if (Object.keys(idSelectors).length !== 0) {
|
||||
styleSheet['idSelectors'] = idSelectors;
|
||||
}
|
||||
if (Object.keys(classSelectors).length !== 0) {
|
||||
styleSheet['classSelectors'] = classSelectors;
|
||||
}
|
||||
}
|
||||
res = JSON.stringify(styleSheet);
|
||||
return res;
|
||||
}
|
||||
/**
|
||||
* keyFrame style special compilation.
|
||||
* @param {Obejct} obj Preliminary compilation results of keyFrame style.
|
||||
* @return {Obejct} keyFrame style obejct.
|
||||
*/
|
||||
function keyFrameFormat(obj) {
|
||||
for (const key of Object.keys(obj)) {
|
||||
const value = obj[key];
|
||||
for (const styleValue of value) {
|
||||
for (const styleKey of Object.keys(styleValue)) {
|
||||
const innerValue = styleValue[styleKey];
|
||||
if (REGEXP_COLOR.test(innerValue)) {
|
||||
styleValue[styleKey] = parseInt(innerValue.slice(1), 16);
|
||||
}
|
||||
try {
|
||||
styleValue[styleKey] = JSON.parse(styleValue[styleKey]);
|
||||
} catch (e) {
|
||||
// Values cannot be converted to objects are not processed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
const rules = [
|
||||
{
|
||||
match: function(key, value) {
|
||||
return key === SPECIAL_STYLE.ANIMATION_DELAY || key === SPECIAL_STYLE.ANIMATION_DURATION;
|
||||
},
|
||||
action: function(obj, key, value) {
|
||||
obj[key] = value;
|
||||
},
|
||||
},
|
||||
{
|
||||
match: function(key, value) {
|
||||
return key === SPECIAL_STYLE.ANIMATION_ITERATION_COUNT;
|
||||
},
|
||||
action: function(obj, key, value) {
|
||||
if (value === -1) {
|
||||
value = 'infinite';
|
||||
}
|
||||
obj[key] = value.toString();
|
||||
},
|
||||
},
|
||||
{
|
||||
match: function(key, value) {
|
||||
return [
|
||||
SPECIAL_STYLE.BACKGROUND_IMAGE,
|
||||
SPECIAL_STYLE.BACKGROUND_IMAGE_ACTIVE,
|
||||
SPECIAL_STYLE.BACKGROUND_IMAGE_CHECKED,
|
||||
].includes(key);
|
||||
},
|
||||
action: function(obj, key, value) {
|
||||
obj[key] = value.replace(REGXP_QUOTES, '');
|
||||
},
|
||||
},
|
||||
{
|
||||
match: function(key, value) {
|
||||
return !isNaN(Number(value));
|
||||
},
|
||||
action: function(obj, key, value) {
|
||||
obj[key] = Number(value);
|
||||
},
|
||||
},
|
||||
{
|
||||
match: function(key, value) {
|
||||
return REGEXP_NUMBER_PX.test(value);
|
||||
},
|
||||
action: function(obj, key, value) {
|
||||
obj[key] = parseInt(value.replace(REGEXP_UNIT, ''), 10);
|
||||
},
|
||||
},
|
||||
{
|
||||
match: function(key, value) {
|
||||
return REGEXP_COLOR.test(value);
|
||||
},
|
||||
action: function(obj, key, value) {
|
||||
obj[key] = parseInt(value.slice(1), 16);
|
||||
},
|
||||
},
|
||||
{
|
||||
match: function(key, value) {
|
||||
return value === 'true';
|
||||
},
|
||||
action: function(obj, key, value) {
|
||||
obj[key] = true;
|
||||
},
|
||||
},
|
||||
{
|
||||
match: function(key, value) {
|
||||
return value === 'false';
|
||||
},
|
||||
action: function(obj, key, value) {
|
||||
obj[key] = false;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Loop and format style, There are two rules defined here, types of number+px and color convert to number 16777215.
|
||||
* @param {Obejct} obj Preliminary compilation results of style object.
|
||||
* @return {Obejct} style obejct.
|
||||
*/
|
||||
function styleFormat(obj) {
|
||||
let value = '';
|
||||
for (const key of Object.keys(obj)) {
|
||||
value = obj[key];
|
||||
for (let i = 0; i < rules.length; i++) {
|
||||
if (rules[i].match(key, value)) {
|
||||
rules[i].action(obj, key, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
exports.transformStyle = transformStyle;
|
557
ace-loader/src/lite/lite-transform-template.js
Normal file
557
ace-loader/src/lite/lite-transform-template.js
Normal file
@ -0,0 +1,557 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Customize the compiled template code into a render function. There are some detailed rules to explain:
|
||||
* 1. Convert all numeric strings to numbers, such as:"32px" convert to number 32; "11" convert to number 11;
|
||||
* 2. Convert all hex color to decimal number;
|
||||
* 3. Convert all boolean strings to boolean type;
|
||||
* 4. compile events, the value of event Cannot be enclosed in double quotes;
|
||||
*/
|
||||
const { isFunction, isObject, isUndefined } = require('./lite-utils');
|
||||
const {
|
||||
SPECIAL_STYLE,
|
||||
REGEXP_NUMBER_PX,
|
||||
REGEXP_COLOR,
|
||||
REGEXP_UNIT,
|
||||
REGXP_QUOTES,
|
||||
REGXP_LANGUAGE,
|
||||
REGXP_LANGUAGE_KEY,
|
||||
REGXP_FUNC_RETURN,
|
||||
} = require('./lite-enum');
|
||||
const parameterArray = [];
|
||||
let parameter1 = '';
|
||||
let parameter2 = '';
|
||||
let i18nMapping = {};
|
||||
const ATTRBUTES = 'attrs';
|
||||
const EVENTS_ON_FUNC = 'on';
|
||||
const KEY = 'key';
|
||||
const AST_KEY = {
|
||||
ATTR: 'attr',
|
||||
CLASSLIST: 'classList',
|
||||
STYLE: 'style',
|
||||
EVENTS: 'events',
|
||||
TYPE: 'type',
|
||||
CHILDREN: 'children',
|
||||
KEY: 'key',
|
||||
};
|
||||
const EVENT_KEY = [
|
||||
'onBubbleEvents',
|
||||
'catchBubbleEvents',
|
||||
'onCaptureEvents',
|
||||
'catchCaptureEvents',
|
||||
];
|
||||
|
||||
const optionRules = {
|
||||
[AST_KEY.ATTR]: function(dataContent, node, key) {
|
||||
if (Object.keys(node.attr).length !== 0) {
|
||||
dataContent += `'${ATTRBUTES}' : ${transformProps(node.attr)},`;
|
||||
}
|
||||
return dataContent;
|
||||
},
|
||||
[AST_KEY.CLASSLIST]: function(dataContent, node, key) {
|
||||
dataContent += sortClass(node[key]);
|
||||
return dataContent;
|
||||
},
|
||||
[AST_KEY.STYLE]: function(dataContent, node, key) {
|
||||
dataContent += sortStyle(node[key]);
|
||||
return dataContent;
|
||||
},
|
||||
[AST_KEY.EVENTS]: function(dataContent, node, key) {
|
||||
dataContent += `'${EVENTS_ON_FUNC}' : ${transformEvents(node.events)},`;
|
||||
return dataContent;
|
||||
},
|
||||
[AST_KEY.KEY]: function(dataContent, node, key) {
|
||||
dataContent += `'${KEY}' : ${node.key},`;
|
||||
return dataContent;
|
||||
},
|
||||
};
|
||||
|
||||
const styleRules = [
|
||||
{
|
||||
match: function(key, value) {
|
||||
return key === SPECIAL_STYLE.ANIMATION_DELAY || key === SPECIAL_STYLE.ANIMATION_DURATION;
|
||||
},
|
||||
action: function(staticStyle, key, value) {
|
||||
staticStyle += `'${key}' : ${JSON.stringify(value)},`;
|
||||
return staticStyle;
|
||||
},
|
||||
},
|
||||
{
|
||||
match: function(key, value) {
|
||||
return key === SPECIAL_STYLE.ANIMATION_ITERATION_COUNT;
|
||||
},
|
||||
action: function(staticStyle, key, value) {
|
||||
if (value === -1) {
|
||||
value = 'infinite';
|
||||
}
|
||||
staticStyle += `'${key}' : ${JSON.stringify(value)},`;
|
||||
return staticStyle;
|
||||
},
|
||||
},
|
||||
{
|
||||
match: function(key, value) {
|
||||
return key === SPECIAL_STYLE.BACKGROUND_IMAGE;
|
||||
},
|
||||
action: function(staticStyle, key, value) {
|
||||
staticStyle += `'${key}' : ${checkType(value.replace(REGXP_QUOTES, ''))},`;
|
||||
return staticStyle;
|
||||
},
|
||||
},
|
||||
{
|
||||
match: function(key, value) {
|
||||
return true;
|
||||
},
|
||||
action: function(staticStyle, key, value) {
|
||||
staticStyle += `'${key}' : ${checkType(value)},`;
|
||||
return staticStyle;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
(function() {
|
||||
EVENT_KEY.map(function(event) {
|
||||
optionRules[event] = function(dataContent, node, key) {
|
||||
dataContent += `'${event}' : ${transformEvents(node[event])},`;
|
||||
return dataContent;
|
||||
};
|
||||
});
|
||||
})();
|
||||
|
||||
/**
|
||||
* Compile the ast object into an executable function.
|
||||
* @param {Obejct} value template object compiled ast.
|
||||
* @return {String} template string.
|
||||
*/
|
||||
function transformTemplate(value) {
|
||||
const ast = Function(`return ${value}`)();
|
||||
let template = isObject(ast) ? transformNode(ast) : `_c('div')`;
|
||||
template = template.replace(/,$/, '');
|
||||
const cachedI18nPushStrings = Object.values(i18nMapping);
|
||||
const I18nContect = cachedI18nPushStrings.length === 0 ? '' : ` var i18ns = []; ${cachedI18nPushStrings.join(';')};`;
|
||||
const res = `function (vm) { var _vm = vm || this;${I18nContect} return ${template} }`;
|
||||
i18nMapping = {};
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divided into if\for\ordinary three kinds node transform.
|
||||
* @param {Obejct} node template object compiled ast.
|
||||
* @return {String} template string.
|
||||
*/
|
||||
function transformNode(node) {
|
||||
if (node.repeat && !node.forCompiled) {
|
||||
return transformFor(node);
|
||||
} else if (node.shown && !node.ifCompiled) {
|
||||
return transformIf(node);
|
||||
} else {
|
||||
return transformNodeDetail(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide node into type/child/data three parts and compiled separately.
|
||||
* @param {Obejct} node ordinary node.
|
||||
* @return {String} ordinary node string.
|
||||
*/
|
||||
function transformNodeDetail(node) {
|
||||
const type = node.type;
|
||||
const options = transformOptions(node);
|
||||
const children = transformChildren(node);
|
||||
const render = `_c('${type}'${options ? `, ${options} ` : ``}${children ? `, ${children} ` : ``}),`;
|
||||
return render;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile node all key-value datas.
|
||||
* @param {Obejct} node ordinary node.
|
||||
* @return {String} ordinary node attributes string.
|
||||
*/
|
||||
function transformOptions(node) {
|
||||
let dataContent = '';
|
||||
parameter2 = parameterArray[parameterArray.length - 1];
|
||||
if (node.attr && node.attr.tid && parameter2 !== '') {
|
||||
node['key'] = `${parameter2}.${node.attr['tid']}`;
|
||||
delete node.attr.tid;
|
||||
}
|
||||
for (const key of Object.keys(node)) {
|
||||
if (key !== AST_KEY.TYPE && key !== AST_KEY.CHILDREN) {
|
||||
if (optionRules[key]) {
|
||||
dataContent = optionRules[key](dataContent, node, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dataContent === '') {
|
||||
return null;
|
||||
}
|
||||
dataContent = '{' + dataContent.replace(/,$/, '') + '}';
|
||||
return dataContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile node classList, divided into dynamicClass and staticClass.
|
||||
* @param {Function|String} classList the object of class list.
|
||||
* @return {String} class list string.
|
||||
*/
|
||||
function sortClass(classList) {
|
||||
let classStr = '';
|
||||
const DYNAMIC_CLASS = 'dynamicClass';
|
||||
const STATIC_CLASS = 'staticClass';
|
||||
const value = checkType(classList);
|
||||
// Divid into two parts dynamicClass and staticClass depending on whether it is a method type
|
||||
if ((isFunction(classList) || isUndefined(classList)) && !REGXP_LANGUAGE.test(classList)) {
|
||||
classStr += `'${DYNAMIC_CLASS}' : ${formatForFunc(value)},`;
|
||||
} else {
|
||||
classStr += `'${STATIC_CLASS}' : ${value},`;
|
||||
}
|
||||
return classStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile node style, divided into staticStyle and staticStyle.
|
||||
* @param {Object} props the object of style.
|
||||
* @return {String} style list string.
|
||||
*/
|
||||
function sortStyle(props) {
|
||||
let staticStyle = '';
|
||||
let dynamicStyle = '';
|
||||
const STASTIC_STYLE = 'staticStyle';
|
||||
const DYNAMIC_STYLE = 'dynamicStyle';
|
||||
for (const key of Object.keys(props)) {
|
||||
const value = props[key];
|
||||
// Divid into two parts staticStyle and dynamicStyle depending on whether it is a method type
|
||||
if (isFunction(value) && !REGXP_LANGUAGE.test(value)) {
|
||||
dynamicStyle += `'${key}' : ${formatForFunc(value)},`;
|
||||
} else {
|
||||
for (let i = 0; i < styleRules.length; i++) {
|
||||
if (styleRules[i].match(key, value)) {
|
||||
staticStyle = styleRules[i].action(staticStyle, key, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (staticStyle !== '') {
|
||||
staticStyle = `'${STASTIC_STYLE}' : {${staticStyle.replace(/,$/, '')}}, `;
|
||||
}
|
||||
if (dynamicStyle !== '') {
|
||||
dynamicStyle = `'${DYNAMIC_STYLE}' :{${dynamicStyle.replace(/,$/, '')}},`;
|
||||
}
|
||||
return staticStyle + dynamicStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* general method ,judge type and compile, There are some special rules defined here,
|
||||
* such as:"32px" convert to number 32; "11" convert to number 11; "#ffffff" convert to number 16777215.
|
||||
* @param {*} value Value to be formatted.
|
||||
* @return {*} Formatted value.
|
||||
*/
|
||||
function checkType(value) {
|
||||
if (isFunction(value) || isUndefined(value)) {
|
||||
return formatForFunc(value);
|
||||
// Use recursive conversion of object type values
|
||||
} else if (isObject(value)) {
|
||||
return transformProps(value);
|
||||
// Convert all numeric strings to numbers
|
||||
} else if (!isNaN(Number(value))) {
|
||||
return Number(value);
|
||||
} else if (REGEXP_NUMBER_PX.test(value)) {
|
||||
return parseInt(value.replace(REGEXP_UNIT, ''), 10);
|
||||
// Convert all colors to numbers
|
||||
} else if (REGEXP_COLOR.test(value)) {
|
||||
return parseInt(value.slice(1), 16);
|
||||
// Convert all boolean strings to boolean type
|
||||
} else if (value === 'true') {
|
||||
return true;
|
||||
} else if (value === 'false') {
|
||||
return false;
|
||||
} else {
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* general method, compile data of object type, and compile node attributes.
|
||||
* apart from The case where key is "value".
|
||||
* @param {Object} props Value to be formatted.
|
||||
* @return {String} Formatted value.
|
||||
*/
|
||||
function transformProps(props) {
|
||||
let propContent = '';
|
||||
const VALUE = 'value';
|
||||
for (const key of Object.keys(props)) {
|
||||
const propValue = props[key];
|
||||
// value is used to display, except for method types, no conversion is required
|
||||
if (key === VALUE) {
|
||||
if (isFunction(propValue) || isUndefined(propValue)) {
|
||||
propContent += `'${key}' : ${formatForFunc(props[key])},`;
|
||||
} else {
|
||||
propContent += `'${key}' : ${JSON.stringify(props[key])},`;
|
||||
}
|
||||
} else {
|
||||
propContent += `'${key}' : ${checkType(props[key])},`;
|
||||
}
|
||||
}
|
||||
propContent = `{${propContent.replace(/,$/, '')}}`;
|
||||
return propContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* compile events, divided into two types of conversion methods and string types.
|
||||
* @param {Object} props Value of events to be formatted.
|
||||
* @return {String} Formatted Value of events.
|
||||
*/
|
||||
function transformEvents(props) {
|
||||
let eventContent = '';
|
||||
for (const key of Object.keys(props)) {
|
||||
if (isFunction(props[key])) {
|
||||
/**
|
||||
* Method contains parameters and will be compiled into a method.
|
||||
* such as: onclick = "test(value)" => "click": function(evt){this.test(this.value, evt)}
|
||||
*/
|
||||
eventContent += `'${key}' : ${formatForFunc(props[key])},`;
|
||||
} else {
|
||||
/**
|
||||
* The method contains no parameters and will be compiled into a string.
|
||||
* such as: onclick = "test" => "click": "test"
|
||||
*/
|
||||
eventContent += `'${key}' : ${formatForString(props[key])},`;
|
||||
}
|
||||
}
|
||||
eventContent = `{${eventContent.replace(/,$/, '')}}`;
|
||||
return eventContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile events of type string, add `_vm.` in front of ordinary events, such as: onclick="test" => "click": "_vm.test"
|
||||
* do nothing for the data in the `for` loop, such as: onclick="{{$item.click}}" => "click": "$item.click"
|
||||
* @param {Object} value string type of events to be formatted.
|
||||
* @return {String} Formatted Value of events.
|
||||
*/
|
||||
function formatForString(value) {
|
||||
let forCompiled = false;
|
||||
for (const parameter of parameterArray) {
|
||||
// '$' Needs to be escaped in regular expressions. The parameter in the for instruction may be '$idx' and '$item'
|
||||
const escape = parameter.charAt(0) === '$' ? '\\' : '';
|
||||
const itRE = new RegExp(escape + parameter);
|
||||
// Match the variable name in the stack, to determine whether it is ordinary event or an event in the for
|
||||
if (itRE.test(value)) {
|
||||
forCompiled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const res = forCompiled ? value : '_vm.' + value;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* compile "for" direct, return the _l function.
|
||||
* @param {Object} node node obejct with "for" directive.
|
||||
* @return {String} string of _l function.
|
||||
*/
|
||||
function transformFor(node) {
|
||||
let exp = node.repeat.exp ? node.repeat.exp : node.repeat;
|
||||
parameterArray.push(node.repeat.key ? node.repeat.key : '$idx');
|
||||
parameterArray.push(node.repeat.value ? node.repeat.value : '$item');
|
||||
node.forCompiled = true;
|
||||
// Set context and stack to convert "this.index" to "index" in the for function
|
||||
exp = formatForFunc(exp);
|
||||
const children = transformNode(node).replace(/,$/, '');
|
||||
parameter2 = parameterArray[parameterArray.length - 1];
|
||||
parameter1 = parameterArray[parameterArray.length - 2];
|
||||
const comma = parameter1 !== '' && parameter2 !== '' ? ',' : '';
|
||||
parameterArray.pop();
|
||||
parameterArray.pop();
|
||||
return '_l' + '((' + exp + '),' + 'function(' + parameter2 + comma + parameter1 + '){' + 'return ' + children + '}),';
|
||||
}
|
||||
|
||||
/**
|
||||
* compile "if" direct, return the _i function.
|
||||
* @param {Object} node node obejct with "if" directive.
|
||||
* @return {String} string of _i function.
|
||||
*/
|
||||
function transformIf(node) {
|
||||
node.ifCompiled = true;
|
||||
const children = transformNode(node).replace(/,$/, '');
|
||||
return '_i' + '((' + formatForFunc(node.shown) + '),' + 'function(){return ' + children + '}),';
|
||||
}
|
||||
|
||||
/**
|
||||
* convert "this.index" to "index" in the for function. if the element is not in the for function,
|
||||
* there will be no value in parameterArray
|
||||
* @param {Object} value Value of function to be formatted.
|
||||
* @return {String} Formatted Value of events.
|
||||
*/
|
||||
function formatForFunc(value) {
|
||||
let func = value.toString();
|
||||
for (const parameter of parameterArray) {
|
||||
// '$' Needs to be escaped in regular expressions. The parameter in the for instruction may be '$idx' and '$item'
|
||||
const escape = parameter.charAt(0) === '$' ? '\\' : '';
|
||||
const itRE = new RegExp('this.' + escape + parameter + '\\b', 'g');
|
||||
/**
|
||||
* If it is a parameter in the for instruction, remove 'this'.
|
||||
* such as: {"value": function () {return this.$item.name}} => {"value": function () {return $item.name}}
|
||||
*/
|
||||
func = func.replace(itRE, parameter);
|
||||
}
|
||||
// Replace all "this" to "_vm"
|
||||
func = func.replace(/this\./g, '_vm.');
|
||||
// Internationalization performance optimization
|
||||
func = cacheI18nTranslation(func);
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* There is only one $t internationalizations in the processing function.
|
||||
* @param {String} i18nExpression match the value of $t in the internationalization method.
|
||||
* @param {Array} cachedI18nExpressions all keys of i18n Mapping object.
|
||||
* @return {String} treated internationalization method.
|
||||
*/
|
||||
function handleLangSingle(i18nExpression, cachedI18nExpressions) {
|
||||
let res = '';
|
||||
if (cachedI18nExpressions.includes(i18nExpression)) {
|
||||
// The i18nExpression already exists in cachedI18nExpressions
|
||||
const cachedI18nPushStrings = Object.values(i18nMapping);
|
||||
const cachedI18nPushString = i18nMapping[i18nExpression];
|
||||
res = `i18ns[${cachedI18nPushStrings.lastIndexOf(cachedI18nPushString)}]`;
|
||||
} else {
|
||||
// The i18nExpression does not exist in cachedI18nExpressions
|
||||
i18nMapping[
|
||||
i18nExpression
|
||||
] = `i18ns.push( ${i18nExpression} )`;
|
||||
res = `i18ns[${Object.keys(i18nMapping).length - 1}]`;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* There are multiple $t internationalizations in the processing function..
|
||||
* @param {Array} i18nExpressions match the value of $t in the internationalization method.
|
||||
* @param {Array} cachedI18nExpressions all keys of i18n Mapping object.
|
||||
* @param {String} funcExpression return value in the internationalization method.
|
||||
* @param {String} func internationalization method.
|
||||
* @return {String} treated internationalization method.
|
||||
*/
|
||||
function handleLangMulti(i18nExpressions, cachedI18nExpressions, funcExpression, func) {
|
||||
let res = func;
|
||||
// The funcExpression already exists in cachedI18nExpressions
|
||||
if (cachedI18nExpressions.includes(funcExpression)) {
|
||||
const cachedI18nPushStrings = Object.values(i18nMapping);
|
||||
const cachedI18nPushString = i18nMapping[funcExpression];
|
||||
res = `i18ns[${cachedI18nPushStrings.lastIndexOf(cachedI18nPushString)}]`;
|
||||
// The funcExpression does not exist in cachedI18nExpressions
|
||||
} else {
|
||||
for (let i = 0; i < i18nExpressions.length; i++) {
|
||||
const i18nExpression = i18nExpressions[i];
|
||||
// The i18nExpression already exists in cachedI18nExpressions
|
||||
if (cachedI18nExpressions.includes(i18nExpression)) {
|
||||
const cachedI18nPushStrings = Object.values(i18nMapping);
|
||||
const cachedI18nPushString = i18nMapping[i18nExpression];
|
||||
res = res.replace(
|
||||
i18nExpression,
|
||||
`i18ns[${cachedI18nPushStrings.lastIndexOf(cachedI18nPushString)}]`,
|
||||
);
|
||||
// The i18nExpression does not exists in cachedI18nExpressions
|
||||
} else {
|
||||
i18nMapping[
|
||||
i18nExpression
|
||||
] = `i18ns.push( ${i18nExpression} )`;
|
||||
res = res.replace(
|
||||
i18nExpression,
|
||||
`i18ns[${Object.keys(i18nMapping).length - 1}]`,
|
||||
);
|
||||
}
|
||||
// For the last $t, replace the func value
|
||||
if (i === i18nExpressions.length - 1 && !res.includes('_vm.')) {
|
||||
const funcReturnMatches = REGXP_FUNC_RETURN.exec(res);
|
||||
REGXP_FUNC_RETURN.lastIndex = 0;
|
||||
const funcReturnMatch = funcReturnMatches[1].trim();
|
||||
i18nMapping[funcExpression] = `i18ns.push( ${funcReturnMatch} )`;
|
||||
res = `i18ns[${Object.keys(i18nMapping).length - 1}]`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internationalization performance optimization operation.
|
||||
* @param {String} func string for globalization method.
|
||||
* @return {String} Whether to use the parameters in 'for' instruction.
|
||||
*/
|
||||
function cacheI18nTranslation(func) {
|
||||
if (!REGXP_LANGUAGE.test(func)) {
|
||||
return func;
|
||||
}
|
||||
const i18nExpressions = func.match(REGXP_LANGUAGE_KEY);
|
||||
const cachedI18nExpressions = Object.keys(i18nMapping);
|
||||
const funcExpressions = REGXP_FUNC_RETURN.exec(func);
|
||||
REGXP_FUNC_RETURN.lastIndex = 0;
|
||||
const funcExpression = funcExpressions[1].trim();
|
||||
// If the 'for' parameter is used in $t, nothing will be done
|
||||
if (isUseForInstrucParam(funcExpression)) {
|
||||
return func;
|
||||
}
|
||||
// There is only one $t internationalization in the function.
|
||||
// such as:function () { return ( _vm.$t('i18n.text.value1')) }
|
||||
if (i18nExpressions.length === 1 && i18nExpressions[0] === funcExpression) {
|
||||
const i18nExpression = i18nExpressions[0];
|
||||
func = handleLangSingle(i18nExpression, cachedI18nExpressions);
|
||||
// There are multiple $t internationalization in the function.
|
||||
// such as: function () { return ( _vm.$t('i18n.text.value1') - _vm.$t('i18n.text.value2')); }
|
||||
} else {
|
||||
func = handleLangMulti(i18nExpressions, cachedI18nExpressions, funcExpression, func);
|
||||
}
|
||||
return func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the parameters in the 'for' instruction are used in the globalization method.
|
||||
* @param {String} value string for globalization method.
|
||||
* @return {Blooean} Whether to use the parameters in 'for' instruction.
|
||||
*/
|
||||
function isUseForInstrucParam(value) {
|
||||
let isUseParam = false;
|
||||
for (const parameter of parameterArray) {
|
||||
const escape = parameter.charAt(0) === '$' ? '\\' : '';
|
||||
const itRE = new RegExp(escape + parameter);
|
||||
// Match the variable name in the stack, to determine whether it is ordinary event or an event in the for
|
||||
if (itRE.test(value)) {
|
||||
isUseParam = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isUseParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* compile node children.
|
||||
* @param {Object} node ordinary node.
|
||||
* @return {String} ordinary node children string.
|
||||
*/
|
||||
function transformChildren(node) {
|
||||
const children = node.children;
|
||||
if (!children) {
|
||||
return null;
|
||||
}
|
||||
let childContent = '';
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
childContent += transformNode(children[i]);
|
||||
}
|
||||
childContent = '[' + childContent.replace(/,$/, '') + ']';
|
||||
return childContent;
|
||||
}
|
||||
|
||||
exports.transformTemplate = transformTemplate;
|
24
ace-loader/src/lite/lite-utils.js
Normal file
24
ace-loader/src/lite/lite-utils.js
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const is = (type) => {
|
||||
return (source) => Object.prototype.toString.call(source) === `[object ${type}]`;
|
||||
};
|
||||
|
||||
exports.isFunction = is('Function');
|
||||
exports.isUndefined = is('Undefined');
|
||||
exports.isObject = is('Object');
|
||||
exports.isArray = is('Array');
|
||||
exports.isNull = is('Null');
|
226
ace-loader/src/loader-gen.js
Normal file
226
ace-loader/src/loader-gen.js
Normal file
@ -0,0 +1,226 @@
|
||||
/**
|
||||
* Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
|
||||
*/
|
||||
import loaderUtils from 'loader-utils'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
|
||||
import * as legacy from './legacy'
|
||||
import {
|
||||
parseFragment
|
||||
}
|
||||
from './parser'
|
||||
import {
|
||||
getNameByPath,
|
||||
getRequireString,
|
||||
stringifyLoaders,
|
||||
logWarn,
|
||||
loadBabelModule
|
||||
}
|
||||
from './util'
|
||||
import { isReservedTag } from './templater/component_validator'
|
||||
import loader from 'sass-loader'
|
||||
|
||||
const { DEVICE_LEVEL } = require('./lite/lite-enum')
|
||||
const loaderPath = __dirname
|
||||
const defaultLoaders = {
|
||||
none: '',
|
||||
main: path.resolve(loaderPath, 'loader.js'),
|
||||
template: path.resolve(loaderPath, 'template.js'),
|
||||
style: path.resolve(loaderPath, 'style.js'),
|
||||
script: path.resolve(loaderPath, 'script.js'),
|
||||
json: path.resolve(loaderPath, 'json.js'),
|
||||
babel: loadBabelModule('babel-loader'),
|
||||
manifest: path.resolve(loaderPath, 'manifest-loader.js'),
|
||||
extgen: path.resolve(loaderPath, 'extgen.js')
|
||||
}
|
||||
|
||||
function getLoaderString (type, config) {
|
||||
config = config || {}
|
||||
const customLoader = loadCustomLoader(config)
|
||||
let loaders
|
||||
switch (type) {
|
||||
case 'main':
|
||||
return mainLoaderString(loaders)
|
||||
case 'element':
|
||||
return elementLoaderString(loaders, config)
|
||||
case 'template':
|
||||
return templateLoaderString(loaders, config, customLoader)
|
||||
case 'style':
|
||||
return styleLoaderString(loaders, config, customLoader)
|
||||
case 'script':
|
||||
return scriptLoaderString(loaders, config, customLoader)
|
||||
case 'config':
|
||||
return configLoaderString(loaders, config)
|
||||
case 'data':
|
||||
return dataLoaderString(loaders, config)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function loadCustomLoader (config) {
|
||||
if (config.lang && config.customLang[config.lang]) {
|
||||
return loadBabelModule(config.customLang[config.lang][0])
|
||||
}
|
||||
}
|
||||
|
||||
function mainLoaderString (loaders) {
|
||||
loaders = [{
|
||||
name: defaultLoaders.main
|
||||
}]
|
||||
return stringifyLoaders(loaders)
|
||||
}
|
||||
|
||||
function elementLoaderString (loaders, config) {
|
||||
loaders = [{
|
||||
name: defaultLoaders.main,
|
||||
query: {
|
||||
element: config.source ? undefined : true
|
||||
}
|
||||
}]
|
||||
return stringifyLoaders(loaders)
|
||||
}
|
||||
|
||||
function templateLoaderString (loaders, config, customLoader) {
|
||||
loaders = [{
|
||||
name: defaultLoaders.json
|
||||
}, {
|
||||
name: defaultLoaders.template
|
||||
}]
|
||||
if (customLoader) {
|
||||
loaders = loaders.concat(customLoader)
|
||||
}
|
||||
loaders.push({
|
||||
name: defaultLoaders.extgen,
|
||||
query: {
|
||||
type: 'template'
|
||||
}
|
||||
})
|
||||
|
||||
return stringifyLoaders(loaders)
|
||||
}
|
||||
|
||||
function styleLoaderString (loaders, config, customLoader) {
|
||||
loaders = [{
|
||||
name: defaultLoaders.json
|
||||
}, {
|
||||
name: defaultLoaders.style
|
||||
}]
|
||||
if (customLoader) {
|
||||
loaders = loaders.concat(customLoader)
|
||||
}
|
||||
loaders.push({
|
||||
name: defaultLoaders.extgen,
|
||||
query: {
|
||||
type: 'style'
|
||||
}
|
||||
})
|
||||
return stringifyLoaders(loaders)
|
||||
}
|
||||
|
||||
function scriptLoaderString (loaders, config, customLoader) {
|
||||
loaders = [{
|
||||
name: defaultLoaders.script
|
||||
}]
|
||||
if (customLoader) {
|
||||
loaders = loaders.concat(customLoader)
|
||||
}
|
||||
else {
|
||||
loaders.push({
|
||||
name: defaultLoaders.babel,
|
||||
query: {
|
||||
presets: [loadBabelModule('@babel/preset-env')],
|
||||
plugins: [loadBabelModule('@babel/plugin-transform-modules-commonjs')],
|
||||
comments: 'false'
|
||||
}
|
||||
})
|
||||
}
|
||||
if (config.app) {
|
||||
loaders.push({
|
||||
name: defaultLoaders.manifest,
|
||||
query: {
|
||||
path: config.source
|
||||
}
|
||||
})
|
||||
}
|
||||
return stringifyLoaders(loaders)
|
||||
}
|
||||
|
||||
function configLoaderString (loaders, config) {
|
||||
loaders = [{
|
||||
name: defaultLoaders.json
|
||||
}]
|
||||
return stringifyLoaders(loaders)
|
||||
}
|
||||
|
||||
function dataLoaderString (loaders, config) {
|
||||
loaders = [{
|
||||
name: defaultLoaders.json
|
||||
}]
|
||||
return stringifyLoaders(loaders)
|
||||
}
|
||||
|
||||
function codegenHmlAndCss() {
|
||||
const options = {
|
||||
lang: {
|
||||
sass:['sass-loader'],
|
||||
scss:['sass-loader'],
|
||||
less:['less-loader']
|
||||
}
|
||||
}
|
||||
const customLang = options.lang || {}
|
||||
const loaderQuery = loaderUtils.getOptions(this) || {}
|
||||
const isElement = loaderQuery.element
|
||||
const resourceQuery = this.resourceQuery && loaderUtils.parseQuery(this.resourceQuery) || {}
|
||||
const isEntry = resourceQuery.entry
|
||||
let output = ''
|
||||
let jsFileName = this.resourcePath.replace(process.env.aceSuperVisualPath, process.env.aceModuleRoot)
|
||||
jsFileName = jsFileName.substr(0, jsFileName.length - 6) + 'js';
|
||||
|
||||
output = 'var $app_script$ = ' + getRequireString(this, getLoaderString('script', {
|
||||
customLang,
|
||||
lang: undefined,
|
||||
element: undefined,
|
||||
elementName: undefined,
|
||||
source: jsFileName
|
||||
}), jsFileName)
|
||||
|
||||
output += 'var $app_template$ = ' + getRequireString(this, getLoaderString('template', {
|
||||
customLang,
|
||||
lang: undefined,
|
||||
element: isElement,
|
||||
elementName: undefined,
|
||||
source: this.resourcePath
|
||||
}), this.resourcePath)
|
||||
|
||||
output += 'var $app_style$ = ' + getRequireString(this, getLoaderString('style', {
|
||||
customLang,
|
||||
lang: undefined,
|
||||
element: isElement,
|
||||
elementName: undefined,
|
||||
source: this.resourcePath
|
||||
}), this.resourcePath)
|
||||
|
||||
output += `
|
||||
$app_define$('@app-component/${getNameByPath(this.resourcePath)}', [], function($app_require$, $app_exports$, $app_module$) {
|
||||
` + `
|
||||
$app_script$($app_module$, $app_exports$, $app_require$)
|
||||
if ($app_exports$.__esModule && $app_exports$.default) {
|
||||
$app_module$.exports = $app_exports$.default
|
||||
}
|
||||
` + `
|
||||
$app_module$.exports.template = $app_template$
|
||||
` + `
|
||||
$app_module$.exports.style = $app_style$
|
||||
` + `
|
||||
})
|
||||
`
|
||||
|
||||
if (isEntry) {
|
||||
output += `$app_bootstrap$('@app-component/${getNameByPath(this.resourcePath)}'` + ',undefined' + ',undefined' + `)`
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
module.exports = codegenHmlAndCss
|
29
ace-loader/src/manifest-loader.js
Normal file
29
ace-loader/src/manifest-loader.js
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const utils = require('./util');
|
||||
const path = require('path');
|
||||
|
||||
let projectPath = process.env.aceModuleRoot || process.cwd();
|
||||
const manifestFilePath = process.env.aceManifestPath || path.resolve(projectPath, 'manifest.json');
|
||||
|
||||
function manifestLoader(source) {
|
||||
const manifestPlugin = utils.stringifyLoaders([{ name: path.resolve(__dirname, 'manifest-plugin.js') }]);
|
||||
const queryString = utils.getRequireString(this, manifestPlugin, manifestFilePath);
|
||||
source += ';(exports.default || module.exports).manifest = ' + queryString;
|
||||
return source;
|
||||
}
|
||||
module.exports = manifestLoader;
|
||||
|
26
ace-loader/src/manifest-plugin.js
Normal file
26
ace-loader/src/manifest-plugin.js
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const { DEVICE_LEVEL } = require('./lite/lite-enum');
|
||||
module.exports = function(source, map) {
|
||||
this.cacheable && this.cacheable()
|
||||
const callback = this.async()
|
||||
|
||||
if (process.env.DEVICE_LEVEL === DEVICE_LEVEL.LITE) {
|
||||
callback(null, JSON.stringify({ 'manifest.json': 'content' }), map)
|
||||
} else {
|
||||
callback(null, source, map)
|
||||
}
|
||||
};
|
25
ace-loader/src/module-script.js
Normal file
25
ace-loader/src/module-script.js
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
parseRequireModule
|
||||
} from './util';
|
||||
|
||||
module.exports = function(source, map) {
|
||||
source = parseRequireModule(source);
|
||||
this.cacheable && this.cacheable()
|
||||
const callback = this.async()
|
||||
callback(null, source, map)
|
||||
};
|
233
ace-loader/src/resource-plugin.js
Normal file
233
ace-loader/src/resource-plugin.js
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
|
||||
|
||||
const CUSTOM_THEME_PROP_GROUPS = require('./theme/customThemeStyles');
|
||||
const OHOS_THEME_PROP_GROUPS = require('./theme/ohosStyles');
|
||||
|
||||
const FILE_EXT_NAME = ['.js', '.css', '.jsx', '.less', '.sass', '.scss', '.md', '.DS_Store', '.hml'];
|
||||
const red = '\u001b[31m';
|
||||
const reset = '\u001b[39m';
|
||||
let input = '';
|
||||
let output = '';
|
||||
let manifestFilePath = '';
|
||||
let shareThemePath = '';
|
||||
let internalThemePath = '';
|
||||
|
||||
function copyFile(input, output) {
|
||||
try {
|
||||
if (fs.existsSync(input)) {
|
||||
const parent = path.join(output, '..');
|
||||
if (!(fs.existsSync(parent) && fs.statSync(parent).isDirectory())) {
|
||||
mkDir(parent);
|
||||
}
|
||||
const pathInfo = path.parse(input);
|
||||
const entryObj = addPageEntryObj();
|
||||
const indexPath = pathInfo.dir + path.sep + pathInfo.name + '.hml?entry';
|
||||
for (const key in entryObj) {
|
||||
if (entryObj[key] === indexPath) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (pathInfo.ext === '.json' && (pathInfo.dir === shareThemePath ||
|
||||
pathInfo.dir === internalThemePath)) {
|
||||
if (themeFileBuild(input, output)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const readStream = fs.createReadStream(input);
|
||||
const writeStream = fs.createWriteStream(output);
|
||||
readStream.pipe(writeStream);
|
||||
readStream.on('close', function() {
|
||||
writeStream.end();
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(red, `Failed to build file ${input}.`, reset);
|
||||
throw e.message;
|
||||
}
|
||||
}
|
||||
|
||||
function mkDir(path_) {
|
||||
const parent = path.join(path_, '..');
|
||||
if (!(fs.existsSync(parent) && !fs.statSync(parent).isFile())) {
|
||||
mkDir(parent);
|
||||
}
|
||||
fs.mkdirSync(path_);
|
||||
}
|
||||
|
||||
function circularFile(inputPath, outputPath, ext) {
|
||||
const realPath = path.join(inputPath, ext);
|
||||
const localI18n = path.join(input, 'i18n')
|
||||
if (!fs.existsSync(realPath) || realPath === output || realPath === localI18n) {
|
||||
return;
|
||||
}
|
||||
fs.readdirSync(realPath).forEach(function(file_) {
|
||||
const file = path.join(realPath, file_);
|
||||
const fileStat = fs.statSync(file);
|
||||
if (fileStat.isFile()) {
|
||||
const baseName = path.basename(file);
|
||||
const extName = path.extname(file);
|
||||
if (FILE_EXT_NAME.indexOf(extName) < 0 && baseName !== '.DS_Store') {
|
||||
const outputFile = path.join(outputPath, ext, path.basename(file_));
|
||||
if (outputFile === path.join(output, 'manifest.json')) {
|
||||
return;
|
||||
}
|
||||
if (fs.existsSync(outputFile)) {
|
||||
const outputFileStat = fs.statSync(outputFile);
|
||||
if (outputFileStat.isFile() && fileStat.size !== outputFileStat.size) {
|
||||
copyFile(file, outputFile);
|
||||
}
|
||||
} else {
|
||||
copyFile(file, outputFile);
|
||||
}
|
||||
}
|
||||
} else if (fileStat.isDirectory()) {
|
||||
circularFile(inputPath, outputPath, path.join(ext, file_));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class ResourcePlugin {
|
||||
constructor(input_, output_, manifestFilePath_) {
|
||||
input = input_;
|
||||
output = output_;
|
||||
manifestFilePath = manifestFilePath_;
|
||||
shareThemePath = path.join(input_, '../share/resources/styles');
|
||||
internalThemePath = path.join(input_, 'resources/styles');
|
||||
}
|
||||
apply(compiler) {
|
||||
compiler.hooks.beforeCompile.tap('resource Copy', () => {
|
||||
circularFile(input, output, '');
|
||||
circularFile(input, output, '../share');
|
||||
});
|
||||
compiler.hooks.normalModuleFactory.tap('OtherEntryOptionPlugin', () => {
|
||||
addPageEntryObj();
|
||||
for (const key in entryObj) {
|
||||
if (!compiler.options.entry[key]) {
|
||||
const singleEntry = new SingleEntryPlugin('', entryObj[key], key);
|
||||
singleEntry.apply(compiler);
|
||||
}
|
||||
}
|
||||
});
|
||||
compiler.hooks.done.tap('copyManifest', () => {
|
||||
copyManifest();
|
||||
if (fs.existsSync(path.join(output, 'app.js'))) {
|
||||
fs.utimesSync(path.join(output, 'app.js'), new Date(), new Date())
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function copyManifest() {
|
||||
copyFile(manifestFilePath, path.join(output, 'manifest.json'));
|
||||
}
|
||||
|
||||
let entryObj = {};
|
||||
|
||||
function addPageEntryObj() {
|
||||
entryObj = {};
|
||||
if (!fs.existsSync(manifestFilePath)) {
|
||||
throw Error('ERROR: missing manifest').message;
|
||||
}
|
||||
const jsonString = fs.readFileSync(manifestFilePath).toString();
|
||||
const obj = JSON.parse(jsonString);
|
||||
const pages = obj.pages;
|
||||
if (pages === undefined) {
|
||||
throw Error('ERROR: missing pages').message;
|
||||
}
|
||||
pages.forEach((element) => {
|
||||
const sourcePath = element;
|
||||
const hmlPath = path.join(input, sourcePath + '.hml')
|
||||
const aceSuperVisualPath = process.env.aceSuperVisualPath || ''
|
||||
const visualPath = path.join(aceSuperVisualPath, sourcePath + '.visual')
|
||||
const isHml = fs.existsSync(hmlPath)
|
||||
const isVisual = fs.existsSync(visualPath)
|
||||
if (isHml && isVisual) {
|
||||
logWarn(this, [{
|
||||
reason: 'ERROR: ' + sourcePath + ' cannot both have hml && visual'
|
||||
}])
|
||||
} else if (isHml) {
|
||||
entryObj['./' + element] = hmlPath + '?entry';
|
||||
} else if (isVisual){
|
||||
entryObj['./' + element] = visualPath + '?entry';
|
||||
}
|
||||
});
|
||||
if (process.env.isPreview !== 'true' && process.env.DEVICE_LEVEL === 'rich') {
|
||||
loadWorker(entryObj);
|
||||
}
|
||||
return entryObj;
|
||||
}
|
||||
|
||||
function loadWorker(entryObj) {
|
||||
const workerPath = path.resolve(input, 'workers');
|
||||
if (fs.existsSync(workerPath)) {
|
||||
const workerFiles = [];
|
||||
readFile(workerPath, workerFiles);
|
||||
workerFiles.forEach((item) => {
|
||||
if (/\.js$/.test(item)) {
|
||||
const relativePath = path.relative(workerPath, item).replace(/\.js$/, '');
|
||||
entryObj[`./workers/` + relativePath] = item;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function readFile(dir, utFiles) {
|
||||
try {
|
||||
const files = fs.readdirSync(dir);
|
||||
files.forEach((element) => {
|
||||
const filePath = path.join(dir, element);
|
||||
const status = fs.statSync(filePath);
|
||||
if (status.isDirectory()) {
|
||||
readFile(filePath, utFiles);
|
||||
} else {
|
||||
utFiles.push(filePath);
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
function themeFileBuild(customThemePath, customThemeBuild) {
|
||||
if (fs.existsSync(customThemePath)) {
|
||||
const themeContent = JSON.parse(fs.readFileSync(customThemePath));
|
||||
const newContent = {};
|
||||
if (themeContent && themeContent['style']) {
|
||||
newContent['style'] = {};
|
||||
const styleContent = themeContent['style'];
|
||||
Object.keys(styleContent).forEach(function(key) {
|
||||
const customKey = CUSTOM_THEME_PROP_GROUPS[key];
|
||||
const ohosKey = OHOS_THEME_PROP_GROUPS[key];
|
||||
if (ohosKey) {
|
||||
newContent['style'][ohosKey] = styleContent[key];
|
||||
} else if (customKey) {
|
||||
newContent['style'][customKey] = styleContent[key];
|
||||
} else {
|
||||
newContent['style'][key] = styleContent[key];
|
||||
}
|
||||
});
|
||||
fs.writeFileSync(customThemeBuild, JSON.stringify(newContent, null, 2));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
module.exports = ResourcePlugin;
|
67
ace-loader/src/resource-reference-script.js
Normal file
67
ace-loader/src/resource-reference-script.js
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
const OHOS_THEME_PROP_GROUPS = require('./theme/ohosStyles')
|
||||
module.exports = function (source) {
|
||||
let result
|
||||
// target format: this.$r("ohos.id_color_background") or this.$r('ohos.id_color_background') or
|
||||
// "this.$r('ohos.id_color_background')"
|
||||
let ResourceRefReg = /"?this\s*\.\$r\s*\(\s*((['"]ohos\.(?<resName>\w+)['"]))\s*\)"?/g
|
||||
while (result = ResourceRefReg.exec(source)) {
|
||||
const resourceName = result.groups['resName']
|
||||
if (resourceName && OHOS_THEME_PROP_GROUPS[resourceName]) {
|
||||
const resourceId = "\"@ohos_id_" + OHOS_THEME_PROP_GROUPS[resourceName] + "\""
|
||||
source = source.replace(result[0], resourceId)
|
||||
// update the start position of the next match
|
||||
ResourceRefReg.lastIndex -= result[0].length - resourceId.length
|
||||
}
|
||||
}
|
||||
|
||||
// target format: this.$r("sys.type.id_color_background") or this.$r('sys.type.id_color_background') or
|
||||
// "this.$r('sys.type.id_color_background')"
|
||||
// The "type" field can be "float", "color", "string" and so on.
|
||||
let SysResourceTypeRefReg = /"?this\s*\.\$r\s*\(\s*((['"]sys\.(?<resType>\w+)\.(?<resName>\w+)['"]))\s*\)"?/g
|
||||
while (result = SysResourceTypeRefReg.exec(source)) {
|
||||
const resourceName = result.groups['resName']
|
||||
const resourceType = result.groups['resType']
|
||||
if (resourceName && resourceType && OHOS_THEME_PROP_GROUPS[resourceName]) {
|
||||
const resourceId = "\"@sys." + resourceType + "." + OHOS_THEME_PROP_GROUPS[resourceName] + "\""
|
||||
source = source.replace(result[0], resourceId)
|
||||
// update the start position of the next match
|
||||
SysResourceTypeRefReg.lastIndex -= result[0].length - resourceId.length
|
||||
}
|
||||
}
|
||||
|
||||
// target format: this.$r("app.type.developer_defined_color") or this.$r('app.type.developer_defined_color') or
|
||||
// "this.$r('app.type.developer_defined_color')"
|
||||
// The "type" field can be "float", "color", "string" and so on.
|
||||
let AppResourceTypeRefReg = /"?this\s*\.\$r\s*\(\s*((['"]app\.(?<resType>\w+)\.(?<resName>\w+)['"]))\s*\)"?/g
|
||||
while (result = AppResourceTypeRefReg.exec(source)) {
|
||||
const resourceName = result.groups['resName']
|
||||
const resourceType = result.groups['resType']
|
||||
if (resourceName && resourceType) {
|
||||
const resourceId = "\"@app." + resourceType + "." + resourceName + "\""
|
||||
source = source.replace(result[0], resourceId)
|
||||
// update the start position of the next match
|
||||
AppResourceTypeRefReg.lastIndex -= result[0].length - resourceId.length
|
||||
}
|
||||
}
|
||||
|
||||
return source
|
||||
}
|
134
ace-loader/test/card/expected/commonAttr/commonAttr.json
Normal file
134
ace-loader/test/card/expected/commonAttr/commonAttr.json
Normal file
@ -0,0 +1,134 @@
|
||||
{
|
||||
"template": {
|
||||
"attr": {},
|
||||
"type": "div",
|
||||
"classList": [
|
||||
"container"
|
||||
],
|
||||
"children": [
|
||||
{
|
||||
"attr": {
|
||||
"value": "id_test1"
|
||||
},
|
||||
"type": "div",
|
||||
"id": "testid"
|
||||
},
|
||||
{
|
||||
"attr": {
|
||||
"value": "style_test_1"
|
||||
},
|
||||
"type": "div",
|
||||
"style": {
|
||||
"color": "#008000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"attr": {
|
||||
"value": "style_test_2"
|
||||
},
|
||||
"type": "div",
|
||||
"style": {
|
||||
"borderTopColor": "{{col}}",
|
||||
"borderRightColor": "{{col}}",
|
||||
"borderBottomColor": "{{col}}",
|
||||
"borderLeftColor": "{{col}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"attr": {
|
||||
"value": "style_test_2"
|
||||
},
|
||||
"type": "div",
|
||||
"style": {
|
||||
"borderTopColor": "{{col}}",
|
||||
"borderRightColor": "{{col}}",
|
||||
"borderBottomColor": "{{col}}",
|
||||
"borderLeftColor": "{{col}}",
|
||||
"width": "50px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"attr": {
|
||||
"value": "class_test1"
|
||||
},
|
||||
"type": "div",
|
||||
"classList": [
|
||||
"title"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attr": {
|
||||
"value": "class_test2"
|
||||
},
|
||||
"type": "div",
|
||||
"classList": [
|
||||
"title",
|
||||
"table"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attr": {
|
||||
"value": "class_test3"
|
||||
},
|
||||
"type": "div",
|
||||
"classList": [
|
||||
"title",
|
||||
"table"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attr": {
|
||||
"value": "class_test4"
|
||||
},
|
||||
"type": "div",
|
||||
"classList": [
|
||||
"{{testclass1}}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attr": {
|
||||
"value": "class_test5"
|
||||
},
|
||||
"type": "div",
|
||||
"classList": [
|
||||
"{{testclass1}}",
|
||||
"{{testclass2}}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attr": {
|
||||
"value": "class_test6"
|
||||
},
|
||||
"type": "div",
|
||||
"classList": [
|
||||
"{{testclass1}}",
|
||||
"{{testclass2}}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attr": {
|
||||
"disabled": "{{disabled}}",
|
||||
"value": "disable_test1"
|
||||
},
|
||||
"type": "div"
|
||||
}
|
||||
]
|
||||
},
|
||||
"styles": {},
|
||||
"actions": {},
|
||||
"data": {
|
||||
"testclass1": "testclass1",
|
||||
"testclass2": "testclass2",
|
||||
"col": "#008000",
|
||||
"disabled": true
|
||||
},
|
||||
"apiVersion": {
|
||||
"5": {
|
||||
"disabled": false
|
||||
},
|
||||
"6": {
|
||||
"col": "#808080",
|
||||
"content": "Hello World!"
|
||||
}
|
||||
}
|
||||
}
|
37
ace-loader/test/card/expected/event/event.json
Normal file
37
ace-loader/test/card/expected/event/event.json
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"template": {
|
||||
"type": "div",
|
||||
"attr": {},
|
||||
"children": [
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {},
|
||||
"events": {
|
||||
"click": "router"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {},
|
||||
"events": {
|
||||
"click": "router"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"styles": {},
|
||||
"actions": {
|
||||
"click": {
|
||||
"action": "router",
|
||||
"bundleName": "com.example.helloworld",
|
||||
"abilityName": "com.example.helloworld.MainAbility",
|
||||
"params": {
|
||||
"day": "$event.day",
|
||||
"time": "$event.time",
|
||||
"year": "$event.year"
|
||||
}
|
||||
}
|
||||
},
|
||||
"data": {},
|
||||
"apiVersion": {}
|
||||
}
|
23
ace-loader/test/card/expected/expression/expression.json
Normal file
23
ace-loader/test/card/expected/expression/expression.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"template": {
|
||||
"type": "div",
|
||||
"attr": {},
|
||||
"classList": [
|
||||
"container"
|
||||
],
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"attr": {
|
||||
"value": "{{content}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"actions": {},
|
||||
"styles": {},
|
||||
"data": {
|
||||
"content": "Hello World!"
|
||||
},
|
||||
"apiVersion": {}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
{
|
||||
"template": {
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "exteriorStyle_test"
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
".a": {
|
||||
"width": "100%",
|
||||
"height": "50%"
|
||||
},
|
||||
".b": {
|
||||
"width": "100px",
|
||||
"height": "200px"
|
||||
},
|
||||
".c": {
|
||||
"color": "#808080"
|
||||
},
|
||||
".d": {
|
||||
"color": "#008000"
|
||||
},
|
||||
".e": {
|
||||
"color": "rgba(80,60,150,1)"
|
||||
},
|
||||
".j": {
|
||||
"gridTemplateColumns": "50px 40px 80px"
|
||||
},
|
||||
".l": {
|
||||
"gridRowStart": 3
|
||||
},
|
||||
".m": {
|
||||
"borderTopWidth": "5px",
|
||||
"borderRightWidth": "5px",
|
||||
"borderBottomWidth": "5px",
|
||||
"borderLeftWidth": "5px",
|
||||
"borderStyle": "solid",
|
||||
"borderTopColor": "#808080",
|
||||
"borderRightColor": "#808080",
|
||||
"borderBottomColor": "#808080",
|
||||
"borderLeftColor": "#808080"
|
||||
},
|
||||
".n": {
|
||||
"textIndent": "50px"
|
||||
},
|
||||
".o": {
|
||||
"backgroundImage": "/common/img/a.jpg"
|
||||
},
|
||||
".t": {
|
||||
"startAngle": "240deg"
|
||||
},
|
||||
".v": {
|
||||
"paddingTop": "10px",
|
||||
"paddingRight": "15px",
|
||||
"paddingBottom": "10px",
|
||||
"paddingLeft": "15px"
|
||||
},
|
||||
"#w": {
|
||||
"fontSize": "15px",
|
||||
"fontFamily": "PingFangSC-Regular"
|
||||
},
|
||||
".gradient1": {
|
||||
"background": "{\"values\":[{\"type\":\"linearGradient\",\"directions\":[\"to\",\"bottom\"],\"values\":[\"#ff0000\",\"#00ff00\"]}]}"
|
||||
},
|
||||
".gradient2": {
|
||||
"background": "{\"values\":[{\"type\":\"linearGradient\",\"directions\":[\"45deg\"],\"values\":[\"rgb(255,0,0)\",\"rgb(0,255,0)\"]}]}"
|
||||
},
|
||||
".gradient3": {
|
||||
"background": "{\"values\":[{\"type\":\"linearGradient\",\"directions\":[\"to\",\"right\"],\"values\":[\"rgb(255,0,0) 90px\",\"rgb(0,0,255) 60%\"]}]}"
|
||||
},
|
||||
".gradient4": {
|
||||
"background": "{\"values\":[{\"type\":\"repeatingLinearGradient\",\"directions\":[\"to\",\"right\"],\"values\":[\"rgba(255,255,0,1) 30px\",\"rgba(0,0,255,0.5) 60px\"]}]}"
|
||||
},
|
||||
"@FONT-FACE": [
|
||||
{
|
||||
"fontFamily": "HWfont",
|
||||
"src": "url(/common/HWfont.ttf)"
|
||||
}
|
||||
],
|
||||
".txt": {
|
||||
"fontFamily": "HWfont"
|
||||
}
|
||||
},
|
||||
"actions": {},
|
||||
"data": {}
|
||||
}
|
36
ace-loader/test/card/expected/ifAttr/ifAttr.json
Normal file
36
ace-loader/test/card/expected/ifAttr/ifAttr.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"template": {
|
||||
"type": "div",
|
||||
"attr": {},
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"attr": {
|
||||
"value": "Hello-TV"
|
||||
},
|
||||
"shown": "{{show}}"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"attr": {
|
||||
"value": "Hello-Wearable"
|
||||
},
|
||||
"shown": "{{display}}&&!{{show}}"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"attr": {
|
||||
"value": "Hello-World"
|
||||
},
|
||||
"shown": "!{{display}}&&!{{show}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"styles": {},
|
||||
"actions": {},
|
||||
"data": {
|
||||
"show": false,
|
||||
"display": true
|
||||
},
|
||||
"apiVersion": {}
|
||||
}
|
21
ace-loader/test/card/expected/importCSS/importCSS.json
Normal file
21
ace-loader/test/card/expected/importCSS/importCSS.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"template": {
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "importCSS_test"
|
||||
},
|
||||
"classList": [
|
||||
"container"
|
||||
]
|
||||
},
|
||||
"styles": {
|
||||
".title": {
|
||||
"fontSize": "50px"
|
||||
},
|
||||
".container": {
|
||||
"justifyContent": "center"
|
||||
}
|
||||
},
|
||||
"actions": {},
|
||||
"data": {}
|
||||
}
|
18
ace-loader/test/card/expected/importLess/importLess.json
Normal file
18
ace-loader/test/card/expected/importLess/importLess.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"template": {
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "importLess_test"
|
||||
},
|
||||
"classList": [
|
||||
"container"
|
||||
]
|
||||
},
|
||||
"styles": {
|
||||
".container": {
|
||||
"backgroundColor": "#000000"
|
||||
}
|
||||
},
|
||||
"actions": {},
|
||||
"data": {}
|
||||
}
|
145
ace-loader/test/card/expected/inlineStyle/inlineStyle.json
Normal file
145
ace-loader/test/card/expected/inlineStyle/inlineStyle.json
Normal file
@ -0,0 +1,145 @@
|
||||
{
|
||||
"template": {
|
||||
"type": "div",
|
||||
"attr": {},
|
||||
"classList": [
|
||||
"container"
|
||||
],
|
||||
"children": [
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test1"
|
||||
},
|
||||
"style": {
|
||||
"width": "100%"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test2"
|
||||
},
|
||||
"style": {
|
||||
"height": "{{height}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test3"
|
||||
},
|
||||
"style": {
|
||||
"color": "#008000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test4"
|
||||
},
|
||||
"style": {
|
||||
"color": "#FF0000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test5"
|
||||
},
|
||||
"style": {
|
||||
"color": "rgba(200,180,120,1)"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test10"
|
||||
},
|
||||
"style": {
|
||||
"gridTemplateColumns": "50px 100px 60px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test11"
|
||||
},
|
||||
"style": {
|
||||
"gridRowStart": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test12"
|
||||
},
|
||||
"style": {
|
||||
"borderTopWidth": "5px",
|
||||
"borderRightWidth": "5px",
|
||||
"borderBottomWidth": "5px",
|
||||
"borderLeftWidth": "5px",
|
||||
"borderTopStyle": "solid",
|
||||
"borderRightStyle": "solid",
|
||||
"borderBottomStyle": "solid",
|
||||
"borderLeftStyle": "solid",
|
||||
"borderTopColor": "#FF0000",
|
||||
"borderRightColor": "#FF0000",
|
||||
"borderBottomColor": "#FF0000",
|
||||
"borderLeftColor": "#FF0000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test13"
|
||||
},
|
||||
"style": {
|
||||
"textIndent": "50px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test14"
|
||||
},
|
||||
"style": {
|
||||
"backgroundImage": "/common/img/xmad.jpg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "progress",
|
||||
"attr": {
|
||||
"value": "style_test19"
|
||||
},
|
||||
"style": {
|
||||
"startAngle": "240deg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test21"
|
||||
},
|
||||
"style": {
|
||||
"paddingTop": "10px",
|
||||
"paddingRight": "15px",
|
||||
"paddingBottom": "10px",
|
||||
"paddingLeft": "15px"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "style_test23"
|
||||
},
|
||||
"style": {
|
||||
"backgroundImage": "https://huawei.com/logo.jpg"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"styles": {},
|
||||
"actions": {},
|
||||
"data": {}
|
||||
}
|
49
ace-loader/test/card/expected/mediaQuery/mediaQuery.json
Normal file
49
ace-loader/test/card/expected/mediaQuery/mediaQuery.json
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
"template": {
|
||||
"type": "div",
|
||||
"attr": {
|
||||
"value": "mediaQuery_test"
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"@MEDIA": [
|
||||
{
|
||||
"condition": "(dark-mode:true)",
|
||||
".header": {
|
||||
"width": "100%",
|
||||
"height": "60px",
|
||||
"fontSize": "16px",
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center"
|
||||
},
|
||||
".footer": {
|
||||
"width": "100%",
|
||||
"height": "40px",
|
||||
"alignItems": "center"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "(dark-mode:true)",
|
||||
".title": {
|
||||
"fontSize": "16px",
|
||||
"color": "#333333",
|
||||
"alignItems": "center"
|
||||
},
|
||||
".container": {
|
||||
"width": "500px",
|
||||
"height": "500px",
|
||||
"backgroundColor": "#fa8072"
|
||||
},
|
||||
".button": {
|
||||
"paddingTop": "50px",
|
||||
"fontSize": "16px",
|
||||
"color": "#666666",
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"actions": {},
|
||||
"data": {}
|
||||
}
|
61
ace-loader/test/card/expected/privateAttr/privateAttr.json
Normal file
61
ace-loader/test/card/expected/privateAttr/privateAttr.json
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"template": {
|
||||
"type": "div",
|
||||
"attr": {},
|
||||
"classList": [
|
||||
"container"
|
||||
],
|
||||
"children": [
|
||||
{
|
||||
"type": "image",
|
||||
"attr": {
|
||||
"alt": "img",
|
||||
"src": "{{src}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "progress",
|
||||
"attr": {
|
||||
"type": "horizontal",
|
||||
"percent": "{{percent}}",
|
||||
"secondarypercent": "{{secondarypercent}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "progress",
|
||||
"attr": {
|
||||
"type": "scale-ring",
|
||||
"percent": "{{percent}}",
|
||||
"secondarypercent": "{{secondarypercent}}",
|
||||
"clockwise": "{{clockwise}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "progress",
|
||||
"attr": {
|
||||
"type": "arc",
|
||||
"percent": "{{percent}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "chart",
|
||||
"attr": {
|
||||
"type": "line",
|
||||
"options": "{{options}}",
|
||||
"datasets": "{{datasets}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "button",
|
||||
"attr": {
|
||||
"type": "capsule",
|
||||
"value": "{{value}}",
|
||||
"icon": "{{icon}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"styles": {},
|
||||
"actions": {},
|
||||
"data": {}
|
||||
}
|
31
ace-loader/test/card/expected/showAttr/showAttr.json
Normal file
31
ace-loader/test/card/expected/showAttr/showAttr.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"template": {
|
||||
"type": "div",
|
||||
"attr": {},
|
||||
"classList": [
|
||||
"container"
|
||||
],
|
||||
"children": [
|
||||
{
|
||||
"type": "text",
|
||||
"attr": {
|
||||
"show": "false",
|
||||
"value": "Hello World"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"attr": {
|
||||
"show": "{{visible}}",
|
||||
"value": "Hello World"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"styles": {},
|
||||
"actions": {},
|
||||
"data": {
|
||||
"visible": false
|
||||
},
|
||||
"apiVersion": {}
|
||||
}
|
96
ace-loader/test/card/test.js
Normal file
96
ace-loader/test/card/test.js
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path =require('path');
|
||||
|
||||
const chai = require('chai');
|
||||
const sinon = require('sinon');
|
||||
const sinonChai = require('sinon-chai');
|
||||
const expect = chai.expect;
|
||||
chai.use(sinonChai);
|
||||
|
||||
function getActualJSON(componentName, filaName) {
|
||||
const filePath = path.join(__dirname,"testcase/build/pages",`${componentName}`, filaName + `.json`);
|
||||
if(!fs.existsSync(filePath)){
|
||||
return {}
|
||||
}
|
||||
const fileContent = fs.readFileSync(filePath, "utf-8");
|
||||
const fileString = fileContent.toString();
|
||||
return JSON.parse(fileString);
|
||||
}
|
||||
|
||||
function getExpectJSON(componentName, filaName) {
|
||||
const filePath = path.join(__dirname, "expected", `${componentName}`, filaName + `.json`);
|
||||
if(!fs.existsSync(filePath)){
|
||||
return {}
|
||||
}
|
||||
const expectedContent = fs.readFileSync(filePath, "utf-8");
|
||||
const expectedObj = JSON.parse(expectedContent.toString());
|
||||
return expectedObj;
|
||||
}
|
||||
|
||||
describe('build', () => {
|
||||
it('commonAttr', () => {
|
||||
const page = 'commonAttr'
|
||||
expect(getActualJSON(page, 'commonAttr')).eql(getExpectJSON(page, 'commonAttr'));
|
||||
});
|
||||
it('event', () => {
|
||||
const page = 'event'
|
||||
expect(getActualJSON(page, 'event')).eql(getExpectJSON(page, 'event'));
|
||||
});
|
||||
it('expression', () => {
|
||||
const page = 'expression'
|
||||
expect(getActualJSON(page, 'expression')).eql(getExpectJSON(page, 'expression'));
|
||||
});
|
||||
it('exteriorStyle', () => {
|
||||
const page = 'exteriorStyle'
|
||||
expect(getActualJSON(page, 'exteriorStyl')).eql(getExpectJSON(page, 'exteriorStyl'));
|
||||
});
|
||||
it('ifAttr', () => {
|
||||
const page = 'ifAttr'
|
||||
expect(getActualJSON(page, 'ifAttr')).eql(getExpectJSON(page, 'ifAttr'));
|
||||
});
|
||||
it('importCSS', () => {
|
||||
const page = 'importCSS'
|
||||
expect(getActualJSON(page, 'importCSS')).eql(getExpectJSON(page, 'importCSS'));
|
||||
});
|
||||
it('importLess', () => {
|
||||
const page = 'importLess'
|
||||
expect(getActualJSON(page, 'importLess')).eql(getExpectJSON(page, 'importLess'));
|
||||
});
|
||||
it('inlineStyle', () => {
|
||||
const page = 'inlineStyle'
|
||||
expect(getActualJSON(page, 'inlineStyle')).eql(getExpectJSON(page, 'inlineStyle'));
|
||||
});
|
||||
it('mediaQuery', () => {
|
||||
const page = 'mediaQuery'
|
||||
expect(getActualJSON(page, 'mediaQuer')).eql(getExpectJSON(page, 'mediaQuer'));
|
||||
});
|
||||
it('privateAttr', () => {
|
||||
const page = 'privateAttr'
|
||||
expect(getActualJSON(page, 'privateAttr')).eql(getExpectJSON(page, 'privateAttr'));
|
||||
});
|
||||
it('showAttr', () => {
|
||||
const page = 'showAttr'
|
||||
expect(getActualJSON(page, 'showAttr')).eql(getExpectJSON(page, 'showAttr'));
|
||||
});
|
||||
});
|
@ -0,0 +1,13 @@
|
||||
.item{
|
||||
width: 700px;
|
||||
flex-direction: column;
|
||||
height: 300px;
|
||||
align-items: center;
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
.text_style {
|
||||
font-weight:500;
|
||||
font-family:Courier;
|
||||
font-size:40px
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<div>
|
||||
<slot>
|
||||
<text>default content form part1</text>
|
||||
</slot>
|
||||
</div>
|
14
ace-loader/test/card/testError/common/component/comp/comp.js
Normal file
14
ace-loader/test/card/testError/common/component/comp/comp.js
Normal file
@ -0,0 +1,14 @@
|
||||
export default {
|
||||
props:{
|
||||
title: {
|
||||
default: "title"
|
||||
}
|
||||
},
|
||||
data: {
|
||||
show: false,
|
||||
},
|
||||
textClicked () {
|
||||
this.$emit('textClicked');
|
||||
this.show = !this.show;
|
||||
},
|
||||
}
|
20
ace-loader/test/card/testError/manifest.json
Normal file
20
ace-loader/test/card/testError/manifest.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"appID": "com.example.ace.helloworld",
|
||||
"appName": "HelloAce",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": 1,
|
||||
"minPlatformVersion": "1.0.1",
|
||||
"pages": [
|
||||
"pages/for/for",
|
||||
"pages/element/element",
|
||||
"pages/pseudoclasses/pseudoclasses",
|
||||
"pages/selector/selector",
|
||||
"pages/amimation/amimation",
|
||||
"pages/transition/transition",
|
||||
"pages/gradient/gradient"
|
||||
],
|
||||
"window": {
|
||||
"designWidth": 720,
|
||||
"autoDesignWidth": false
|
||||
}
|
||||
}
|
43
ace-loader/test/card/testError/pages/amimation/amimation.css
Normal file
43
ace-loader/test/card/testError/pages/amimation/amimation.css
Normal file
@ -0,0 +1,43 @@
|
||||
.container {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
.button-div {
|
||||
padding-top: 50px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.text-div {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.animate {
|
||||
transform-origin: 20% 40%;
|
||||
transform: translate(0px) ;
|
||||
animation-name: myfirst;
|
||||
animation-delay: 2s;
|
||||
animation-duration: 5s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: none;
|
||||
}
|
||||
@keyframes Go
|
||||
{
|
||||
from {
|
||||
transform:translate(0px) rotate(0deg) scale(1.0);
|
||||
}
|
||||
to {
|
||||
transform-style:translate(100px) rotate(180deg) scale(2.0);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<div class="container">
|
||||
<div class="text-div animate">
|
||||
<text class="title">amimation_test</text>
|
||||
</div>
|
||||
<div class="button-div">
|
||||
<input type="button" value="Go to the second page" class="button" onclick="launch"/>
|
||||
</div>
|
||||
</div>
|
7
ace-loader/test/card/testError/pages/element/element.hml
Normal file
7
ace-loader/test/card/testError/pages/element/element.hml
Normal file
@ -0,0 +1,7 @@
|
||||
<element name='comp' src='../../common/component/comp'></element>
|
||||
<div class="container">
|
||||
<div class="text-div">
|
||||
<text class="title">element_test</text>
|
||||
</div>
|
||||
<comp @textClicked="textClicked"></comp>
|
||||
</div>
|
17
ace-loader/test/card/testError/pages/for/for.css
Normal file
17
ace-loader/test/card/testError/pages/for/for.css
Normal file
@ -0,0 +1,17 @@
|
||||
.container {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
.text-div {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
font-size: 30px;
|
||||
}
|
15
ace-loader/test/card/testError/pages/for/for.hml
Normal file
15
ace-loader/test/card/testError/pages/for/for.hml
Normal file
@ -0,0 +1,15 @@
|
||||
<div class="container">
|
||||
<div class="text-div">
|
||||
<text class="title">for列表渲染.</text>
|
||||
</div>
|
||||
|
||||
<div for="{{array}}" tid="id">
|
||||
<text>{{$idx}}.{{$item.name}}</text>
|
||||
</div>
|
||||
<div for="{{value in array}}" tid="id">
|
||||
<text>{{$idx}}.{{value.name}}</text>
|
||||
</div>
|
||||
<div for="{{(i, v) in array}}" tid="id">
|
||||
<text>{{i}}{{v.name}}</text>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,3 @@
|
||||
.button:active {
|
||||
background-color: #888888;
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<div class="container">
|
||||
<div class="text-div">
|
||||
<text class="title">pseudoclasses_test</text>
|
||||
</div>
|
||||
<div class="button-div">
|
||||
<input type="button" value="Go to the second page" class="button" onclick="launch"/>
|
||||
</div>
|
||||
</div>
|
23
ace-loader/test/card/testError/pages/selector/selector.css
Normal file
23
ace-loader/test/card/testError/pages/selector/selector.css
Normal file
@ -0,0 +1,23 @@
|
||||
div {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
#contentId {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.title, .content {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.container text {
|
||||
color: #007dff;
|
||||
};
|
||||
|
||||
.container > text {
|
||||
color: #fa2a2d;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<div id="containerId" class="container">
|
||||
<text id="titleId" class="title">selector_test</text>
|
||||
<div class="content">
|
||||
<text id="contentId">content</text>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,22 @@
|
||||
.a {
|
||||
shared-transition-effect: exchange;
|
||||
shared-transition-name: shared-transition;
|
||||
shared-transition-timing-function: friction;
|
||||
}
|
||||
@keyframes shared-transition {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translate(0px) rotate(0deg) scale(1.0);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translate(100px) rotate(180deg) scale(2.0);
|
||||
}
|
||||
}
|
||||
|
||||
.s{
|
||||
transition-enter: "translate(100px) rotate(180deg) scale(2.0)";
|
||||
transition-exit: 'translate(100px) rotate(180deg) scale(2.0)';
|
||||
transition-duration: 100ms;
|
||||
transition-timing-function: friction
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user