first commit

This commit is contained in:
2026-09-08 20:28:54 +08:00
commit 2ada8d3d5a
37380 changed files with 4886169 additions and 0 deletions
@@ -0,0 +1,202 @@
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
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
@@ -0,0 +1,56 @@
const isWin = /^win/.test(process.platform)
const normalizePath = path => (isWin ? (path.split(':')[1] || path).replace(/\\/g, '/') : path)
const METHODS = ['error', 'warn', 'info', 'log', 'debug']
const FORMAT_LOG = '__f__'
module.exports = function ({
types: t
}) {
return {
visitor: {
CallExpression (path, state) {
const opts = state.opts
if (path.node.callee.object &&
path.node.callee.object.name === 'console' &&
METHODS.includes(path.node.callee.property.name)) {
if (path.node.callee.property.name === 'debug') { // console.debug=>console.log
path.node.callee.property.name = 'log'
}
let file = state.file.opts.filename
if (file) {
if (opts && opts.file) {
file = opts.file(file)
}
if (file) {
const args = path.node.arguments
const arg = args[0]
if (
arg &&
arg.type === 'CallExpression' &&
arg.callee.name === FORMAT_LOG
) {
return
}
args.push({
type: 'StringLiteral',
value: ` at ${normalizePath(file)}:${path.node.loc.start.line}`
})
args.unshift(t.stringLiteral(path.node.callee.property.name))
const expr = opts && opts.isUniConsole ? t.memberExpression(t.identifier('uni'), t.identifier(
FORMAT_LOG)) : t.identifier(FORMAT_LOG)
path.replaceWith(t.callExpression(expr, args))
// path.node.arguments = [
// t.callExpression(
// t.identifier(FORMAT_LOG),
// args
// )
// ]
}
}
}
}
}
}
}
@@ -0,0 +1,11 @@
{
"name": "@dcloudio/babel-plugin-console",
"version": "0.0.1",
"description": "uni-app babel-plugin-console",
"main": "dist/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "fxy060608",
"license": "Apache-2.0"
}
@@ -0,0 +1,202 @@
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
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
@@ -0,0 +1,781 @@
function initUni() {
var isFn = function isFn(v) {
return typeof v === 'function';
};
var handlePromise = function handlePromise(promise) {
return promise.then(function(data) {
return [null, data];
}).catch(function(err) {
return [err];
});
};
var REGEX = /^\$|^on|^create|Sync$|Manager$|^pause/;
var API_NORMAL_LIST = ['os', 'getCurrentSubNVue', 'getSubNVueById', 'stopRecord', 'stopVoice',
'stopBackgroundAudio', 'stopPullDownRefresh', 'hideKeyboard', 'hideToast', 'hideLoading',
'showNavigationBarLoading', 'hideNavigationBarLoading', 'canIUse', 'navigateBack', 'closeSocket',
'pageScrollTo', 'drawCanvas'
];
var shouldPromise = function shouldPromise(name) {
if (REGEX.test(name) && name !== 'createBLEConnection') {
return false;
}
if (~API_NORMAL_LIST.indexOf(name)) {
return false;
}
return true;
};
var promisify = function promisify(api) {
return function() {
for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
params[_key - 1] = arguments[_key];
}
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (isFn(options.success) || isFn(options.fail) || isFn(options.complete)) {
return api.apply(undefined, [options].concat(params));
}
return handlePromise(new Promise(function(resolve, reject) {
api.apply(undefined, [Object.assign({}, options, {
success: resolve,
fail: reject
})].concat(params));
/* eslint-disable no-extend-native */
Promise.prototype.finally = function(callback) {
var promise = this.constructor;
return this.then(function(value) {
return promise.resolve(callback()).then(function() {
return value;
});
}, function(reason) {
return promise.resolve(callback()).then(function() {
throw reason;
});
});
};
}));
};
};
var onMessageCallbacks = [];
var origin = void 0;
function onSubNVueMessage(data) {
onMessageCallbacks.forEach(function(callback) {
return callback({
origin: origin,
data: data
});
});
}
var webviewId = weexPlus.webview.currentWebview().id;
var channel = new BroadcastChannel('UNI-APP-SUBNVUE');
channel.onmessage = function(event) {
if (event.data.to === webviewId) {
onSubNVueMessage(event.data.data);
}
};
function wrapper(webview) {
webview.$processed = true;
var currentWebviewId = weexPlus.webview.currentWebview().id;
var isPopupNVue = currentWebviewId === webview.id;
var hostNVueId = webview.__uniapp_origin_type === 'uniNView' && webview.__uniapp_origin_id;
var popupNVueId = webview.id;
webview.postMessage = function(data) {
if (hostNVueId) {
channel.postMessage({
data: data,
to: isPopupNVue ? hostNVueId : popupNVueId
});
} else {
postMessage({
type: 'UniAppSubNVue',
data: data
});
}
};
webview.onMessage = function(callback) {
onMessageCallbacks.push(callback);
};
if (!webview.__uniapp_mask_id) {
return;
}
origin = webview.__uniapp_host;
var maskColor = webview.__uniapp_mask;
var maskWebview = weexPlus.webview.getWebviewById(webview.__uniapp_mask_id);
maskWebview = maskWebview.parent() || maskWebview;//再次检测父
var oldShow = webview.show;
var oldHide = webview.hide;
var oldClose = webview.close;
var showMask = function showMask() {
maskWebview.setStyle({
mask: maskColor
});
};
var closeMask = function closeMask() {
maskWebview.setStyle({
mask: 'none'
});
};
webview.show = function() {
showMask();
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return oldShow.apply(webview, args);
};
webview.hide = function() {
closeMask();
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return oldHide.apply(webview, args);
};
webview.close = function() {
closeMask();
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
return oldClose.apply(webview, args);
};
}
function getSubNVueById(id) {
var webview = weexPlus.webview.getWebviewById(id);
if (webview && !webview.$processed) {
wrapper(webview);
}
return webview;
}
function getCurrentSubNVue() {
return getSubNVueById(weexPlus.webview.currentWebview().id);
}
var plus = weex.requireModule('plus');
var globalEvent = weex.requireModule('globalEvent');
var id = 0;
var callbacks = {};
var UNIAPP_SERVICE_NVUE_ID = '__uniapp__service';
globalEvent.addEventListener('plusMessage', function(e) {
if (e.data.type === 'UniAppJsApi') {
invoke(e.data.id, e.data.data);
} else if (e.data.type === 'UniAppSubNVue') {
onSubNVueMessage(e.data.data, e.data.options);
} else if (e.data.type === 'onNavigationBarButtonTap') {
if (typeof onNavigationBarButtonTapCallback === 'function') {
onNavigationBarButtonTapCallback(e.data.data);
}
} else if (e.data.type === 'onNavigationBarSearchInputChanged') {
if (typeof onNavigationBarSearchInputChangedCallback === 'function') {
onNavigationBarSearchInputChangedCallback(e.data.data);
}
} else if (e.data.type === 'onNavigationBarSearchInputConfirmed') {
if (typeof onNavigationBarSearchInputConfirmedCallback === 'function') {
onNavigationBarSearchInputConfirmedCallback(e.data.data);
}
} else if (e.data.type === 'onNavigationBarSearchInputClicked') {
if (typeof onNavigationBarSearchInputClickedCallback === 'function') {
onNavigationBarSearchInputClickedCallback(e.data.data);
}
}
});
var createCallback = function createCallback(args, type) {
var callback = function callback(res) {
if (isFn(args)) {
args(res);
} else if (args) {
if (~res.errMsg.indexOf(':ok')) {
isFn(args.success) && args.success(res);
} else if (~res.errMsg.indexOf(':fail')) {
isFn(args.fail) && args.fail(res);
}
isFn(args.complete) && args.complete(res);
}
};
if (isFn(args) || args && isFn(args.callback)) {
callback.keepAlive = true;
}
return callback;
};
var invoke = function invoke(callbackId, data) {
var callback = callbacks[callbackId];
if (callback) {
callback(data);
if (!callback.keepAlive) {
delete callbacks[callbackId];
}
} else {
console.error('callback[' + callbackId + '] is undefined');
}
};
var publish = function publish(_ref) {
var id = _ref.id,
type = _ref.type,
params = _ref.params;
callbacks[id] = createCallback(params, type);
plus.postMessage({
id: id,
type: type,
params: params
}, UNIAPP_SERVICE_NVUE_ID);
};
function postMessage(data) {
plus.postMessage(data, UNIAPP_SERVICE_NVUE_ID);
}
var createPublish = function createPublish(name) {
return function(args) {
publish({
id: id++,
type: name,
params: args
});
};
};
var onNavigationBarButtonTapCallback = void 0;
var onNavigationBarSearchInputChangedCallback = void 0;
var onNavigationBarSearchInputConfirmedCallback = void 0;
var onNavigationBarSearchInputClickedCallback = void 0;
function onNavigationBarButtonTap(callback) {
onNavigationBarButtonTapCallback = callback;
}
function onNavigationBarSearchInputChanged(callback) {
onNavigationBarSearchInputChangedCallback = callback;
}
function onNavigationBarSearchInputConfirmed(callback) {
onNavigationBarSearchInputConfirmedCallback = callback;
}
function onNavigationBarSearchInputClicked(callback) {
onNavigationBarSearchInputClickedCallback = callback;
}
function requireNativePlugin(pluginName) {
return weex.requireModule(pluginName);
}
var dom = weex.requireModule('dom');
function loadFontFace(_ref) {
var family = _ref.family,
source = _ref.source,
desc = _ref.desc,
success = _ref.success,
fail = _ref.fail,
complete = _ref.complete;
dom.addRule('fontFace', {
fontFamily: family,
src: source.replace(/"/g, '\'')
});
var res = {
errMsg: 'loadFontFace:ok',
status: 'loaded'
};
isFn(success) && success(res);
isFn(complete) && complete(res);
}
var globalEvent$1 = weex.requireModule('globalEvent');
var callbacks$1 = [];
globalEvent$1.addEventListener('plusMessage', function(e) {
if (e.data.type === 'UniAppReady') {
ready.isUniAppReady = true;
if (callbacks$1.length) {
callbacks$1.forEach(function(callback) {
return callback();
});
callbacks$1 = [];
}
}
});
function ready(callback) {
if (typeof callback === 'function') {
if (this.isUniAppReady) {
callback();
} else {
callbacks$1.push(callback);
}
}
}
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) {
return typeof obj;
} : function(obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ?
"symbol" : typeof obj;
};
var stream = weex.requireModule('stream');
// let requestTaskId = 0
var METHOD_GET = 'GET';
var METHOD_POST = 'POST';
var CONTENT_TYPE_JSON = 'application/json';
var CONTENT_TYPE_FORM = 'application/x-www-form-urlencoded';
var serialize = function serialize(data) {
var method = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : METHOD_GET;
var contentType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : CONTENT_TYPE_FORM;
if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') {
if (method.toUpperCase() === METHOD_POST && contentType.toLowerCase() === CONTENT_TYPE_JSON) {
return JSON.stringify(data);
} else {
return Object.keys(data).map(function(key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(data[key]);
}).join('&');
}
}
return data;
};
function request(_ref) {
var url = _ref.url,
data = _ref.data,
header = _ref.header,
_ref$method = _ref.method,
method = _ref$method === undefined ? 'GET' : _ref$method,
_ref$dataType = _ref.dataType,
dataType = _ref$dataType === undefined ? 'json' : _ref$dataType,
responseType = _ref.responseType,
success = _ref.success,
fail = _ref.fail,
complete = _ref.complete;
// requestTaskId++
var aborted = false;
var hasContentType = false;
var headers = {};
if (header) {
for (var name in header) {
if (!hasContentType && name.toLowerCase() === 'content-type') {
hasContentType = true;
headers['Content-Type'] = header[name];
} else {
headers[name] = header[name];
}
}
}
if (method === METHOD_GET && data) {
url = url + (~url.indexOf('?') ? url.substr(-1) === '&' || url.substr(-1) === '?' ? '' : '&' : '?') +
serialize(data);
}
stream.fetch({
url: url,
method: method,
headers: headers,
type: dataType === 'json' ? 'json' : 'text',
body: method !== METHOD_GET ? serialize(data, method, headers['Content-Type']) : ''
}, function(_ref2) {
var status = _ref2.status,
ok = _ref2.ok,
statusText = _ref2.statusText,
data = _ref2.data,
headers = _ref2.headers;
var ret = {};
if (!status || status === -1 || aborted) {
ret.errMsg = 'request:fail';
isFn(fail) && fail(ret);
} else {
ret.data = data;
ret.statusCode = status;
ret.header = headers;
isFn(success) && success(ret);
}
isFn(complete) && complete(ret);
});
return {
abort: function abort() {
aborted = true;
}
};
}
var storage = weex.requireModule('plusstorage');
var UNIAPP_STORAGE_DATA_TYPE = '__TYPE';
function getStorage(_ref) {
var key = _ref.key,
data = _ref.data,
success = _ref.success,
fail = _ref.fail,
complete = _ref.complete;
storage.getItem(key + UNIAPP_STORAGE_DATA_TYPE, function(ret) {
if (ret.result === 'success') {
var dataType = ret.data;
storage.getItem(key, function(res) {
if (res.result === 'success') {
var result = res.data;
if (dataType && result) {
if (dataType !== 'String') {
result = JSON.parse(result);
}
isFn(success) && success({
errMsg: 'getStorage:ok',
data: result
});
} else {
res.errMsg = 'setStorage:fail';
isFn(fail) && fail(res);
}
} else {
res.errMsg = 'setStorage:fail';
isFn(fail) && fail(res);
}
isFn(complete) && complete(res);
});
} else {
ret.errMsg = 'setStorage:fail';
isFn(fail) && fail(ret);
isFn(complete) && complete(ret);
}
});
}
function setStorage(_ref2) {
var key = _ref2.key,
data = _ref2.data,
success = _ref2.success,
fail = _ref2.fail,
complete = _ref2.complete;
var dataType = 'String';
if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') {
dataType = 'Object';
data = JSON.stringify(data);
}
storage.setItem(key, data, function(res) {
if (res.result === 'success') {
storage.setItem(key + UNIAPP_STORAGE_DATA_TYPE, dataType, function(ret) {
if (ret.result === 'success') {
isFn(success) && success({
errMsg: 'setStorage:ok'
});
} else {
ret.errMsg = 'setStorage:fail';
isFn(fail) && fail(ret);
}
});
} else {
res.errMsg = 'setStorage:fail';
isFn(fail) && fail(res);
}
isFn(complete) && complete(res);
});
}
function removeStorage(_ref3) {
var key = _ref3.key,
data = _ref3.data,
success = _ref3.success,
fail = _ref3.fail,
complete = _ref3.complete;
storage.removeItem(key, function(res) {
if (res.result === 'success') {
isFn(success) && success({
errMsg: 'removeStorage:ok'
});
} else {
res.errMsg = 'removeStorage:fail';
isFn(fail) && fail(res);
}
isFn(complete) && complete(res);
});
storage.removeItem(key + UNIAPP_STORAGE_DATA_TYPE);
}
function clearStorage(_ref4) {
var key = _ref4.key,
data = _ref4.data,
success = _ref4.success,
fail = _ref4.fail,
complete = _ref4.complete;
}
var clipboard = weex.requireModule('clipboard');
function getClipboardData(_ref) {
var success = _ref.success,
fail = _ref.fail,
complete = _ref.complete;
clipboard.getString(function(_ref2) {
var data = _ref2.data;
var res = {
errMsg: 'getClipboardData:ok',
data: data
};
isFn(success) && success(res);
isFn(complete) && complete(res);
});
}
function setClipboardData(_ref3) {
var data = _ref3.data,
success = _ref3.success,
fail = _ref3.fail,
complete = _ref3.complete;
var res = {
errMsg: 'setClipboardData:ok'
};
clipboard.setString(data);
isFn(success) && success(res);
isFn(complete) && complete(res);
}
var getEmitter = function() {
if (typeof getUniEmitter === 'function') {
/* eslint-disable no-undef */
return getUniEmitter;
}
var Emitter = {
$on: function $on() {
console.warn('uni.$on failed');
},
$off: function $off() {
console.warn('uni.$off failed');
},
$once: function $once() {
console.warn('uni.$once failed');
},
$emit: function $emit() {
console.warn('uni.$emit failed');
}
};
return function getUniEmitter() {
return Emitter;
};
}();
function apply(ctx, method, args) {
return ctx[method].apply(ctx, args);
}
function $on() {
return apply(getEmitter(), '$on', [].concat(Array.prototype.slice.call(arguments)));
}
function $off() {
return apply(getEmitter(), '$off', [].concat(Array.prototype.slice.call(arguments)));
}
function $once() {
return apply(getEmitter(), '$once', [].concat(Array.prototype.slice.call(arguments)));
}
function $emit() {
return apply(getEmitter(), '$emit', [].concat(Array.prototype.slice.call(arguments)));
}
var api = /*#__PURE__*/ Object.freeze({
loadFontFace: loadFontFace,
ready: ready,
request: request,
getStorage: getStorage,
setStorage: setStorage,
removeStorage: removeStorage,
clearStorage: clearStorage,
getClipboardData: getClipboardData,
setClipboardData: setClipboardData,
onSubNVueMessage: onSubNVueMessage,
getSubNVueById: getSubNVueById,
getCurrentSubNVue: getCurrentSubNVue,
$on: $on,
$off: $off,
$once: $once,
$emit: $emit
});
var wx = {
uploadFile: true,
downloadFile: true,
chooseImage: true,
previewImage: true,
getImageInfo: true,
saveImageToPhotosAlbum: true,
chooseVideo: true,
saveVideoToPhotosAlbum: true,
saveFile: true,
getSavedFileList: true,
getSavedFileInfo: true,
removeSavedFile: true,
openDocument: true,
setStorage: true,
getStorage: true,
getStorageInfo: true,
removeStorage: true,
clearStorage: true,
getLocation: true,
chooseLocation: true,
openLocation: true,
getSystemInfo: true,
getNetworkType: true,
makePhoneCall: true,
scanCode: true,
setScreenBrightness: true,
getScreenBrightness: true,
setKeepScreenOn: true,
vibrateLong: true,
vibrateShort: true,
addPhoneContact: true,
showToast: true,
showLoading: true,
hideToast: true,
hideLoading: true,
showModal: true,
showActionSheet: true,
setNavigationBarTitle: true,
setNavigationBarColor: true,
navigateTo: true,
redirectTo: true,
reLaunch: true,
switchTab: true,
navigateBack: true,
getProvider: true,
login: true,
getUserInfo: true,
share: true,
requestPayment: true,
subscribePush: true,
unsubscribePush: true,
onPush: true,
offPush: true
};
var baseUni = {
os: {
nvue: true
}
};
var uni = {};
if (typeof Proxy !== 'undefined') {
uni = new Proxy({}, {
get: function get(target, name) {
if (name === 'os') {
return {
nvue: true
};
}
if (name === 'postMessage') {
return postMessage;
}
if (name === 'requireNativePlugin') {
return requireNativePlugin;
}
if (name === 'onNavigationBarButtonTap') {
return onNavigationBarButtonTap;
}
if (name === 'onNavigationBarSearchInputChanged') {
return onNavigationBarSearchInputChanged;
}
if (name === 'onNavigationBarSearchInputConfirmed') {
return onNavigationBarSearchInputConfirmed;
}
if (name === 'onNavigationBarSearchInputClicked') {
return onNavigationBarSearchInputClicked;
}
var method = api[name];
if (!method) {
method = createPublish(name);
}
if (shouldPromise(name)) {
return promisify(method);
}
return method;
}
});
} else {
Object.keys(baseUni).forEach(function(key) {
uni[key] = baseUni[key];
});
uni.postMessage = postMessage;
uni.requireNativePlugin = requireNativePlugin;
uni.onNavigationBarButtonTap = onNavigationBarButtonTap;
uni.onNavigationBarSearchInputChanged = onNavigationBarSearchInputChanged;
uni.onNavigationBarSearchInputConfirmed = onNavigationBarSearchInputConfirmed;
uni.onNavigationBarSearchInputClicked = onNavigationBarSearchInputClicked;
Object.keys(wx).forEach(function(name) {
var method = api[name];
if (!method) {
method = createPublish(name);
}
if (shouldPromise(name)) {
uni[name] = promisify(method);
} else {
uni[name] = method;
}
});
}
return uni;
}
var createUni;
if (typeof getUni === 'function') {
createUni = getUni;
} else {
createUni = initUni;
}
var weexPlus = new WeexPlus(weex);
export default createUni(weex, weexPlus, BroadcastChannel);
export {
weexPlus
};
@@ -0,0 +1,11 @@
{
"name": "@dcloudio/uni-app-plus-nvue-v8",
"version": "0.0.1",
"description": "uni-app app-plus-nvue-v8",
"main": "dist/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "fxy060608",
"license": "Apache-2.0"
}
@@ -0,0 +1,202 @@
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
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
@@ -0,0 +1,3 @@
export default function getCurrentSubNVue() {
return uni.getSubNVueById(plus.webview.currentWebview().id)
}
@@ -0,0 +1,612 @@
var isFn = function isFn(v) {
return typeof v === 'function';
};
var handlePromise = function handlePromise(promise) {
return promise.then(function (data) {
return [null, data];
}).catch(function (err) {
return [err];
});
};
var REGEX = /^on|^create|Sync$|Manager$|^pause/;
var API_NORMAL_LIST = ['os', 'stopRecord', 'stopVoice', 'stopBackgroundAudio', 'stopPullDownRefresh', 'hideKeyboard', 'hideToast', 'hideLoading', 'showNavigationBarLoading', 'hideNavigationBarLoading', 'canIUse', 'navigateBack', 'closeSocket', 'pageScrollTo', 'drawCanvas'];
var shouldPromise = function shouldPromise(name) {
if (REGEX.test(name) && name !== 'createBLEConnection') {
return false;
}
if (~API_NORMAL_LIST.indexOf(name)) {
return false;
}
return true;
};
var promisify = function promisify(api) {
return function () {
for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
params[_key - 1] = arguments[_key];
}
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (isFn(options.success) || isFn(options.fail) || isFn(options.complete)) {
return api.apply(undefined, [options].concat(params));
}
return handlePromise(new Promise(function (resolve, reject) {
api.apply(undefined, [Object.assign({}, options, {
success: resolve,
fail: reject
})].concat(params));
/* eslint-disable no-extend-native */
Promise.prototype.finally = function (callback) {
var promise = this.constructor;
return this.then(function (value) {
return promise.resolve(callback()).then(function () {
return value;
});
}, function (reason) {
return promise.resolve(callback()).then(function () {
throw reason;
});
});
};
}));
};
};
var UNIAPP_LAUNCH_WEBVIEW_ID = '__UNIAPP_LAUNCH_WEBVIEW_ID';
var plus = weex.requireModule('plus');
var storage = weex.requireModule('plusstorage');
var globalEvent = weex.requireModule('globalEvent');
var id = 0;
var callbacks = {};
var WEBVIEW_ID = '';
if (weex.config.plus_appid) {
WEBVIEW_ID = weex.config.plus_appid;
} else {
storage && storage.getItem && storage.getItem(UNIAPP_LAUNCH_WEBVIEW_ID, function (evt) {
if (evt.result === 'success' && evt.data) {
WEBVIEW_ID = evt.data;
}
});
}
globalEvent.addEventListener('plusMessage', function (e) {
if (e.data.type === 'UniAppJsApi') {
invoke(e.data.id, e.data.data);
} else if (e.data.type === 'onNavigationBarButtonTap') {
if (typeof onNavigationBarButtonTapCallback === 'function') {
onNavigationBarButtonTapCallback(e.data.data);
}
} else if (e.data.type === 'onNavigationBarSearchInputChanged') {
if (typeof onNavigationBarSearchInputChangedCallback === 'function') {
onNavigationBarSearchInputChangedCallback(e.data.data);
}
} else if (e.data.type === 'onNavigationBarSearchInputConfirmed') {
if (typeof onNavigationBarSearchInputConfirmedCallback === 'function') {
onNavigationBarSearchInputConfirmedCallback(e.data.data);
}
} else if (e.data.type === 'onNavigationBarSearchInputClicked') {
if (typeof onNavigationBarSearchInputClickedCallback === 'function') {
onNavigationBarSearchInputClickedCallback(e.data.data);
}
}
});
var createCallback = function createCallback(args, type) {
var callback = function callback(res) {
if (isFn(args)) {
args(res);
} else if (args) {
if (~res.errMsg.indexOf(':ok')) {
isFn(args.success) && args.success(res);
} else if (~res.errMsg.indexOf(':fail')) {
isFn(args.fail) && args.fail(res);
}
isFn(args.complete) && args.complete(res);
}
};
if (isFn(args) || args && isFn(args.callback)) {
callback.keepAlive = true;
}
return callback;
};
var invoke = function invoke(callbackId, data) {
var callback = callbacks[callbackId];
if (callback) {
callback(data);
if (!callback.keepAlive) {
delete callbacks[callbackId];
}
} else {
console.error('callback[' + callbackId + '] is undefined');
}
};
var publish = function publish(_ref) {
var id = _ref.id,
type = _ref.type,
params = _ref.params;
callbacks[id] = createCallback(params, type);
if (WEBVIEW_ID) {
plus.postMessage({
id: id,
type: type,
params: params
}, WEBVIEW_ID);
} else {
console.error('launch webview id is not ready');
}
};
function postMessage(data) {
if (WEBVIEW_ID) {
plus.postMessage(data, WEBVIEW_ID);
} else {
console.error('launch webview id is not ready');
}
}
var createPublish = function createPublish(name) {
return function (args) {
publish({
id: id++,
type: name,
params: args
});
};
};
var onNavigationBarButtonTapCallback = void 0;
var onNavigationBarSearchInputChangedCallback = void 0;
var onNavigationBarSearchInputConfirmedCallback = void 0;
var onNavigationBarSearchInputClickedCallback = void 0;
function onNavigationBarButtonTap(callback) {
onNavigationBarButtonTapCallback = callback;
}
function onNavigationBarSearchInputChanged(callback) {
onNavigationBarSearchInputChangedCallback = callback;
}
function onNavigationBarSearchInputConfirmed(callback) {
onNavigationBarSearchInputConfirmedCallback = callback;
}
function onNavigationBarSearchInputClicked(callback) {
onNavigationBarSearchInputClickedCallback = callback;
}
function requireNativePlugin(pluginName) {
return weex.requireModule(pluginName);
}
var dom = weex.requireModule('dom');
function loadFontFace(_ref) {
var family = _ref.family,
source = _ref.source,
desc = _ref.desc,
success = _ref.success,
fail = _ref.fail,
complete = _ref.complete;
dom.addRule('fontFace', {
fontFamily: family,
src: source.replace(/"/g, '\'')
});
var res = {
errMsg: 'loadFontFace:ok',
status: 'loaded'
};
isFn(success) && success(res);
isFn(complete) && complete(res);
}
var globalEvent$1 = weex.requireModule('globalEvent');
var callbacks$1 = [];
globalEvent$1.addEventListener('plusMessage', function (e) {
if (e.data.type === 'UniAppReady') {
ready.isUniAppReady = true;
if (callbacks$1.length) {
callbacks$1.forEach(function (callback) {
return callback();
});
callbacks$1 = [];
}
}
});
function ready(callback) {
if (typeof callback === 'function') {
if (this.isUniAppReady) {
callback();
} else {
callbacks$1.push(callback);
}
}
}
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
var stream = weex.requireModule('stream');
// let requestTaskId = 0
var METHOD_GET = 'GET';
var METHOD_POST = 'POST';
var CONTENT_TYPE_JSON = 'application/json';
var CONTENT_TYPE_FORM = 'application/x-www-form-urlencoded';
var serialize = function serialize(data) {
var method = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : METHOD_GET;
var contentType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : CONTENT_TYPE_FORM;
if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') {
if (method.toUpperCase() === METHOD_POST && contentType.toLowerCase() === CONTENT_TYPE_JSON) {
return JSON.stringify(data);
} else {
return Object.keys(data).map(function (key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(data[key]);
}).join('&');
}
}
return data;
};
function request(_ref) {
var url = _ref.url,
data = _ref.data,
header = _ref.header,
_ref$method = _ref.method,
method = _ref$method === undefined ? 'GET' : _ref$method,
_ref$dataType = _ref.dataType,
dataType = _ref$dataType === undefined ? 'json' : _ref$dataType,
responseType = _ref.responseType,
success = _ref.success,
fail = _ref.fail,
complete = _ref.complete;
// requestTaskId++
var aborted = false;
var hasContentType = false;
var headers = {};
if (header) {
for (var name in header) {
if (!hasContentType && name.toLowerCase() === 'content-type') {
hasContentType = true;
headers['Content-Type'] = header[name];
} else {
headers[name] = header[name];
}
}
}
if (method === METHOD_GET && data) {
url = url + (~url.indexOf('?') ? url.substr(-1) === '&' || url.substr(-1) === '?' ? '' : '&' : '?') + serialize(data);
}
stream.fetch({
url: url,
method: method,
headers: headers,
type: dataType === 'json' ? 'json' : 'text',
body: method !== METHOD_GET ? serialize(data, method, headers['Content-Type']) : ''
}, function (_ref2) {
var status = _ref2.status,
ok = _ref2.ok,
statusText = _ref2.statusText,
data = _ref2.data,
headers = _ref2.headers;
var ret = {};
if (!status || status === -1 || aborted) {
ret.errMsg = 'request:fail';
isFn(fail) && fail(ret);
} else {
ret.data = data;
ret.statusCode = status;
ret.header = headers;
isFn(success) && success(ret);
}
isFn(complete) && complete(ret);
});
return {
abort: function abort() {
aborted = true;
}
};
}
var storage$1 = weex.requireModule('plusstorage');
var UNIAPP_STORAGE_DATA_TYPE = '__TYPE';
function getStorage(_ref) {
var key = _ref.key,
data = _ref.data,
success = _ref.success,
fail = _ref.fail,
complete = _ref.complete;
storage$1.getItem(key + UNIAPP_STORAGE_DATA_TYPE, function (ret) {
if (ret.result === 'success') {
var dataType = ret.data;
storage$1.getItem(key, function (res) {
if (res.result === 'success') {
var result = res.data;
if (dataType && result) {
if (dataType !== 'String') {
result = JSON.parse(result);
}
isFn(success) && success({
errMsg: 'getStorage:ok',
data: result
});
} else {
res.errMsg = 'setStorage:fail';
isFn(fail) && fail(res);
}
} else {
res.errMsg = 'setStorage:fail';
isFn(fail) && fail(res);
}
isFn(complete) && complete(res);
});
} else {
ret.errMsg = 'setStorage:fail';
isFn(fail) && fail(ret);
isFn(complete) && complete(ret);
}
});
}
function setStorage(_ref2) {
var key = _ref2.key,
data = _ref2.data,
success = _ref2.success,
fail = _ref2.fail,
complete = _ref2.complete;
var dataType = 'String';
if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') {
dataType = 'Object';
data = JSON.stringify(data);
}
storage$1.setItem(key, data, function (res) {
if (res.result === 'success') {
storage$1.setItem(key + UNIAPP_STORAGE_DATA_TYPE, dataType, function (ret) {
if (ret.result === 'success') {
isFn(success) && success({
errMsg: 'setStorage:ok'
});
} else {
ret.errMsg = 'setStorage:fail';
isFn(fail) && fail(ret);
}
});
} else {
res.errMsg = 'setStorage:fail';
isFn(fail) && fail(res);
}
isFn(complete) && complete(res);
});
}
function removeStorage(_ref3) {
var key = _ref3.key,
data = _ref3.data,
success = _ref3.success,
fail = _ref3.fail,
complete = _ref3.complete;
storage$1.removeItem(key, function (res) {
if (res.result === 'success') {
isFn(success) && success({
errMsg: 'removeStorage:ok'
});
} else {
res.errMsg = 'removeStorage:fail';
isFn(fail) && fail(res);
}
isFn(complete) && complete(res);
});
storage$1.removeItem(key + UNIAPP_STORAGE_DATA_TYPE);
}
function clearStorage(_ref4) {
var key = _ref4.key,
data = _ref4.data,
success = _ref4.success,
fail = _ref4.fail,
complete = _ref4.complete;
}
var clipboard = weex.requireModule('clipboard');
function getClipboardData(_ref) {
var success = _ref.success,
fail = _ref.fail,
complete = _ref.complete;
clipboard.getString(function (_ref2) {
var data = _ref2.data;
var res = {
errMsg: 'getClipboardData:ok',
data: data
};
isFn(success) && success(res);
isFn(complete) && complete(res);
});
}
function setClipboardData(_ref3) {
var data = _ref3.data,
success = _ref3.success,
fail = _ref3.fail,
complete = _ref3.complete;
var res = {
errMsg: 'setClipboardData:ok'
};
clipboard.setString(data);
isFn(success) && success(res);
isFn(complete) && complete(res);
}
var api = /*#__PURE__*/Object.freeze({
loadFontFace: loadFontFace,
ready: ready,
request: request,
getStorage: getStorage,
setStorage: setStorage,
removeStorage: removeStorage,
clearStorage: clearStorage,
getClipboardData: getClipboardData,
setClipboardData: setClipboardData
});
var wx = {
uploadFile: true,
downloadFile: true,
chooseImage: true,
previewImage: true,
getImageInfo: true,
saveImageToPhotosAlbum: true,
chooseVideo: true,
saveVideoToPhotosAlbum: true,
saveFile: true,
getSavedFileList: true,
getSavedFileInfo: true,
removeSavedFile: true,
openDocument: true,
setStorage: true,
getStorage: true,
getStorageInfo: true,
removeStorage: true,
clearStorage: true,
getLocation: true,
chooseLocation: true,
openLocation: true,
getSystemInfo: true,
getNetworkType: true,
makePhoneCall: true,
scanCode: true,
setScreenBrightness: true,
getScreenBrightness: true,
setKeepScreenOn: true,
vibrateLong: true,
vibrateShort: true,
addPhoneContact: true,
showToast: true,
showLoading: true,
hideToast: true,
hideLoading: true,
showModal: true,
showActionSheet: true,
setNavigationBarTitle: true,
setNavigationBarColor: true,
navigateTo: true,
redirectTo: true,
reLaunch: true,
switchTab: true,
navigateBack: true,
getProvider: true,
login: true,
getUserInfo: true,
share: true,
requestPayment: true,
subscribePush: true,
unsubscribePush: true,
onPush: true,
offPush: true
};
var uni = {};
var baseUni = {
os: {
nvue: true
}
};
if (typeof Proxy !== 'undefined') {
uni = new Proxy({}, {
get: function get(target, name) {
if (name === 'os') {
return {
nvue: true
};
}
if (name === 'postMessage') {
return postMessage;
}
if (name === 'requireNativePlugin') {
return requireNativePlugin;
}
if (name === 'onNavigationBarButtonTap') {
return onNavigationBarButtonTap;
}
if (name === 'onNavigationBarSearchInputChanged') {
return onNavigationBarSearchInputChanged;
}
if (name === 'onNavigationBarSearchInputConfirmed') {
return onNavigationBarSearchInputConfirmed;
}
if (name === 'onNavigationBarSearchInputClicked') {
return onNavigationBarSearchInputClicked;
}
var method = api[name];
if (!method) {
method = createPublish(name);
}
if (shouldPromise(name)) {
return promisify(method);
}
return method;
}
});
} else {
Object.keys(baseUni).forEach(function (key) {
uni[key] = baseUni[key];
});
uni.postMessage = postMessage;
uni.requireNativePlugin = requireNativePlugin;
uni.onNavigationBarButtonTap = onNavigationBarButtonTap;
uni.onNavigationBarSearchInputChanged = onNavigationBarSearchInputChanged;
uni.onNavigationBarSearchInputConfirmed = onNavigationBarSearchInputConfirmed;
uni.onNavigationBarSearchInputClicked = onNavigationBarSearchInputClicked;
Object.keys(wx).forEach(function (name) {
var method = api[name];
if (!method) {
method = createPublish(name);
}
if (shouldPromise(name)) {
uni[name] = promisify(method);
} else {
uni[name] = method;
}
});
}
var uni$1 = uni;
export default uni$1;
@@ -0,0 +1,3 @@
export default function requireNativePlugin(name) {
return weex.requireModule(name)
}
@@ -0,0 +1,11 @@
{
"name": "@dcloudio/uni-app-plus-nvue",
"version": "0.0.1",
"description": "uni-app app-plus-nvue",
"main": "dist/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "fxy060608",
"license": "Apache-2.0"
}
@@ -0,0 +1,202 @@
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
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
@@ -0,0 +1,157 @@
var isFn = function isFn(v) {
return typeof v === 'function';
};
var handlePromise = function handlePromise(promise) {
return promise.then(function (data) {
return [null, data];
}).catch(function (err) {
return [err];
});
};
var REGEX = /^on|^create|Sync$|Manager$|^pause/;
var API_NORMAL_LIST = ['os', 'stopRecord', 'stopVoice', 'stopBackgroundAudio', 'stopPullDownRefresh', 'hideKeyboard', 'hideToast', 'hideLoading', 'showNavigationBarLoading', 'hideNavigationBarLoading', 'canIUse', 'navigateBack', 'closeSocket', 'pageScrollTo', 'drawCanvas'];
var shouldPromise = function shouldPromise(name) {
if (REGEX.test(name) && name !== 'createBLEConnection') {
return false;
}
if (~API_NORMAL_LIST.indexOf(name)) {
return false;
}
return true;
};
var promisify = function promisify(api) {
return function () {
for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
params[_key - 1] = arguments[_key];
}
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (isFn(options.success) || isFn(options.fail) || isFn(options.complete)) {
return api.apply(undefined, [options].concat(params));
}
return handlePromise(new Promise(function (resolve, reject) {
api.apply(undefined, [Object.assign({}, options, {
success: resolve,
fail: reject
})].concat(params));
/* eslint-disable no-extend-native */
Promise.prototype.finally = function (callback) {
var promise = this.constructor;
return this.then(function (value) {
return promise.resolve(callback()).then(function () {
return value;
});
}, function (reason) {
return promise.resolve(callback()).then(function () {
throw reason;
});
});
};
}));
};
};
var EPS = 1e-4;
var BASE_DEVICE_WIDTH = 750;
var isIOS = false;
var deviceWidth = 0;
var deviceDPR = 0;
function checkDeviceWidth() {
var _wx$getSystemInfoSync = wx.getSystemInfoSync(),
platform = _wx$getSystemInfoSync.platform,
pixelRatio = _wx$getSystemInfoSync.pixelRatio,
windowWidth = _wx$getSystemInfoSync.windowWidth;
deviceWidth = windowWidth;
deviceDPR = pixelRatio;
isIOS = platform === 'ios';
}
function transformUpx(number, newDeviceWidth) {
if (deviceWidth === 0) {
checkDeviceWidth();
}
if (number === 0) {
return 0;
}
var result = number / BASE_DEVICE_WIDTH * (newDeviceWidth || deviceWidth);
if (result < 0) {
result = -result;
}
result = Math.floor(result + EPS);
if (result === 0) {
if (deviceDPR === 1 || !isIOS) {
return 1;
} else {
return 0.5;
}
}
return number < 0 ? -result : result;
}
function requireNativePlugin(pluginName) {
/* eslint-disable no-undef */
return __requireNativePlugin__(pluginName);
}
var uni = {};
var baseUni = {
os: {
plus: true
}
};
if (typeof Proxy !== 'undefined') {
uni = new Proxy({}, {
get: function get(target, name) {
if (baseUni.hasOwnProperty(name)) {
return baseUni[name];
}
if (name === 'upx2px') {
return transformUpx;
}
if (name === 'requireNativePlugin') {
return requireNativePlugin;
}
if (!wx.hasOwnProperty(name)) {
return;
}
if (shouldPromise(name)) {
return promisify(wx[name]);
}
return wx[name];
}
});
} else {
uni.upx2px = transformUpx;
uni.requireNativePlugin = requireNativePlugin;
Object.keys(baseUni).forEach(function (key) {
uni[key] = baseUni[key];
});
Object.keys(wx).forEach(function (key) {
if (wx.hasOwnProperty(key)) {
if (shouldPromise(key)) {
uni[key] = promisify(wx[key]);
} else {
uni[key] = wx[key];
}
}
});
}
var uni$1 = uni;
export default uni$1;
@@ -0,0 +1,626 @@
import Vue from 'vue';
const _toString = Object.prototype.toString;
const hasOwnProperty = Object.prototype.hasOwnProperty;
function isFn (fn) {
return typeof fn === 'function'
}
function isStr (str) {
return typeof str === 'string'
}
function isPlainObject (obj) {
return _toString.call(obj) === '[object Object]'
}
function hasOwn (obj, key) {
return hasOwnProperty.call(obj, key)
}
function noop () {}
const SYNC_API_RE = /hideKeyboard|upx2px|canIUse|^create|Sync$|Manager$/;
const CONTEXT_API_RE = /^create|Manager$/;
const CALLBACK_API_RE = /^on/;
function isContextApi (name) {
return CONTEXT_API_RE.test(name)
}
function isSyncApi (name) {
return SYNC_API_RE.test(name)
}
function isCallbackApi (name) {
return CALLBACK_API_RE.test(name)
}
function handlePromise (promise) {
return promise.then(data => {
return [null, data]
})
.catch(err => [err])
}
function shouldPromise (name) {
if (isSyncApi(name)) {
return false
}
if (isCallbackApi(name)) {
return false
}
return true
}
function promisify (name, api) {
if (!shouldPromise(name)) {
return api
}
return function promiseApi (options = {}, ...params) {
if (isFn(options.success) || isFn(options.fail) || isFn(options.complete)) {
return api(options, ...params)
}
return handlePromise(new Promise((resolve, reject) => {
api(Object.assign({}, options, {
success: resolve,
fail: reject
}), ...params);
/* eslint-disable no-extend-native */
Promise.prototype.finally = function (callback) {
const promise = this.constructor;
return this.then(
value => promise.resolve(callback()).then(() => value),
reason => promise.resolve(callback()).then(() => {
throw reason
})
)
};
}))
}
}
const EPS = 1e-4;
const BASE_DEVICE_WIDTH = 750;
let isIOS = false;
let deviceWidth = 0;
let deviceDPR = 0;
function checkDeviceWidth () {
const {
platform,
pixelRatio,
windowWidth
} = wx.getSystemInfoSync(); // uni=>wx runtime 编译目标是 uni 对象,内部不允许直接使用 uni
deviceWidth = windowWidth;
deviceDPR = pixelRatio;
isIOS = platform === 'ios';
}
function upx2px (number, newDeviceWidth) {
if (deviceWidth === 0) {
checkDeviceWidth();
}
number = Number(number);
if (number === 0) {
return 0
}
let result = (number / BASE_DEVICE_WIDTH) * (newDeviceWidth || deviceWidth);
if (result < 0) {
result = -result;
}
result = Math.floor(result + EPS);
if (result === 0) {
if (deviceDPR === 1 || !isIOS) {
return 1
} else {
return 0.5
}
}
return number < 0 ? -result : result
}
var protocols = {};
const CALLBACKS = ['success', 'fail', 'cancel', 'complete'];
function processCallback (methodName, method, returnValue) {
return function (res) {
return method(processReturnValue(methodName, res, returnValue))
}
}
function processArgs (methodName, fromArgs, argsOption = {}, returnValue = {}, keepFromArgs = false) {
if (isPlainObject(fromArgs)) { // 一般 api 的参数解析
const toArgs = keepFromArgs === true ? fromArgs : {}; // returnValue 为 false 时,说明是格式化返回值,直接在返回值对象上修改赋值
if (isFn(argsOption)) {
argsOption = argsOption(fromArgs, toArgs) || {};
}
for (let key in fromArgs) {
if (hasOwn(argsOption, key)) {
let keyOption = argsOption[key];
if (isFn(keyOption)) {
keyOption = keyOption(fromArgs[key], fromArgs, toArgs);
}
if (!keyOption) { // 不支持的参数
console.warn(`app-plus ${methodName}暂不支持${key}`);
} else if (isStr(keyOption)) { // 重写参数 key
toArgs[keyOption] = fromArgs[key];
} else if (isPlainObject(keyOption)) { // {name:newName,value:value}可重新指定参数 key:value
toArgs[keyOption.name ? keyOption.name : key] = keyOption.value;
}
} else if (CALLBACKS.includes(key)) {
toArgs[key] = processCallback(methodName, fromArgs[key], returnValue);
} else {
if (!keepFromArgs) {
toArgs[key] = fromArgs[key];
}
}
}
return toArgs
} else if (isFn(fromArgs)) {
fromArgs = processCallback(methodName, fromArgs, returnValue);
}
return fromArgs
}
function processReturnValue (methodName, res, returnValue, keepReturnValue = false) {
if (isFn(protocols.returnValue)) { // 处理通用 returnValue
res = protocols.returnValue(methodName, res);
}
return processArgs(methodName, res, returnValue, {}, keepReturnValue)
}
function wrapper (methodName, method) {
if (hasOwn(protocols, methodName)) {
const protocol = protocols[methodName];
if (!protocol) { // 暂不支持的 api
return function () {
console.error(`app-plus 暂不支持${methodName}`);
}
}
return function (arg1, arg2) { // 目前 api 最多两个参数
let options = protocol;
if (isFn(protocol)) {
options = protocol(arg1);
}
arg1 = processArgs(methodName, arg1, options.args, options.returnValue);
const returnValue = wx[options.name || methodName](arg1, arg2);
if (isSyncApi(methodName)) { // 同步 api
return processReturnValue(methodName, returnValue, options.returnValue, isContextApi(methodName))
}
return returnValue
}
}
return method
}
const todoApis = Object.create(null);
const TODOS = [
'subscribePush',
'unsubscribePush',
'onPush',
'offPush',
'share'
];
function createTodoApi (name) {
return function todoApi ({
fail,
complete
}) {
const res = {
errMsg: `${name}:fail:暂不支持 ${name} 方法`
};
isFn(fail) && fail(res);
isFn(complete) && complete(res);
}
}
TODOS.forEach(function (name) {
todoApis[name] = createTodoApi(name);
});
var providers = {};
function getProvider ({
service,
success,
fail,
complete
}) {
let res = false;
if (providers[service]) {
res = {
errMsg: 'getProvider:ok',
service,
provider: providers[service]
};
isFn(success) && success(res);
} else {
res = {
errMsg: 'getProvider:fail:服务[' + service + ']不存在'
};
isFn(fail) && fail(res);
}
isFn(complete) && complete(res);
}
var extraApi = /*#__PURE__*/Object.freeze({
getProvider: getProvider
});
function requireNativePlugin (pluginName) {
/* eslint-disable no-undef */
return __requireNativePlugin__(pluginName)
}
var api = /*#__PURE__*/Object.freeze({
requireNativePlugin: requireNativePlugin
});
const MOCKS = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__'];
function initMocks (vm) {
const mpInstance = vm.$mp[vm.mpType];
MOCKS.forEach(mock => {
if (hasOwn(mpInstance, mock)) {
vm[mock] = mpInstance[mock];
}
});
}
function initHooks (mpOptions, hooks) {
hooks.forEach(hook => {
mpOptions[hook] = function (args) {
this.$vm.__call_hook(hook, args);
};
});
}
function getData (data) {
if (typeof data === 'function') {
try {
return data()
} catch (e) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。');
}
return {}
}
return data || {}
}
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function getProperties (props) {
const properties = {};
if (Array.isArray(props)) { // ['title']
props.forEach(key => {
properties[key] = null;
});
} else if (isPlainObject(props)) { // {title:{type:String,default:''},content:String}
Object.keys(props).forEach(key => {
const opts = props[key];
if (isPlainObject(opts)) { // title:{type:String,default:''}
let value = opts['default'];
if (isFn(value)) {
value = value();
}
properties[key] = {
type: PROP_TYPES.includes(opts.type) ? opts.type : null,
value
};
} else { // content:String
properties[key] = PROP_TYPES.includes(opts) ? opts : null;
}
});
}
return properties
}
function wrapper$1 (event) {
event.stopPropagation = noop;
event.preventDefault = noop;
event.target = event.target || {};
event.detail = event.detail || {};
// TODO 又得兼容 mpvue 的 mp 对象
event.mp = event;
event.target = Object.assign({}, event.target, event.detail);
return event
}
function processEventArgs (event, args = [], isCustom) {
if (isCustom && !args.length) { // 无参数,直接传入 detail 数组
return event.detail
}
const ret = [];
args.forEach(arg => {
if (arg === '$event') {
ret.push(isCustom ? event.detail[0] : event);
} else {
ret.push(arg);
}
});
return ret
}
const ONCE = '~';
const CUSTOM = '^';
function handleEvent (event) {
event = wrapper$1(event);
// [['tap',[['handle',[1,2,a]],['handle1',[1,2,a]]]]]
const eventOpts = (event.currentTarget || event.target).dataset.eventOpts;
if (!eventOpts) {
return console.warn(`事件信息不存在`)
}
// [['handle',[1,2,a]],['handle1',[1,2,a]]]
const eventType = event.type;
eventOpts.forEach(eventOpt => {
let type = eventOpt[0];
const eventsArray = eventOpt[1];
const isCustom = type.charAt(0) === CUSTOM;
type = isCustom ? type.slice(1) : type;
const isOnce = type.charAt(0) === ONCE;
type = isOnce ? type.slice(1) : type;
if (eventsArray && eventType === type) {
eventsArray.forEach(eventArray => {
const handler = this.$vm[eventArray[0]];
if (isOnce) {
if (handler.once) {
return
}
handler.once = true;
}
handler.apply(this.$vm, processEventArgs(event, eventArray[1], isCustom));
});
}
});
}
function handleLink (event) {
event.detail.$parent = this.$vm;
}
function initRefs (vm) {
const mpInstance = vm.$mp[vm.mpType];
Object.defineProperty(vm, '$refs', {
get () {
const $refs = Object.create(null);
const components = mpInstance.selectAllComponents('.__ref__');
components.forEach(component => {
const id = component.id;
$refs[id] = component.$vm;
});
const forComponents = mpInstance.selectAllComponents('.__ref-in-for__');
forComponents.forEach(component => {
const id = component.id;
if (!$refs[id]) {
$refs[id] = [];
}
$refs[id].push(component.$vm);
});
return $refs
}
});
}
const hooks = [
'onShow',
'onHide',
'onError',
'onPageNotFound'
];
function createApp (vueOptions) {
vueOptions = vueOptions.default || vueOptions;
const appOptions = {
onLaunch (args) {
this.$vm = new Vue(vueOptions);
this.$vm.mpType = 'app';
this.$vm.$mp = {
app: this
};
this.$vm.$mount();
this.$vm.__call_hook('onLaunch', args);
}
};
initHooks(appOptions, hooks);
App(appOptions);
return vueOptions
}
const hooks$1 = [
'onShow',
'onHide',
'onPullDownRefresh',
'onReachBottom',
'onShareAppMessage',
'onPageScroll',
'onResize',
'onTabItemTap',
'onBackPress',
'onNavigationBarButtonTap',
'onNavigationBarSearchInputChanged',
'onNavigationBarSearchInputConfirmed',
'onNavigationBarSearchInputClicked'
];
function createPage (vueOptions) {
vueOptions = vueOptions.default || vueOptions;
const pageOptions = {
data: getData(vueOptions.data),
onLoad (args) {
this.$vm = new Vue(vueOptions);
this.$vm.mpType = 'page';
this.$vm.$mp = {
data: {},
page: this
};
initRefs(this.$vm);
initMocks(this.$vm);
this.$vm.$mount();
this.$vm.__call_hook('onLoad', args);
},
onReady () {
this.$vm._isMounted = true;
this.$vm.__call_hook('onReady');
},
onUnload () {
this.$vm.__call_hook('onUnload');
this.$vm.$destroy();
},
__e: handleEvent,
__l: handleLink
};
initHooks(pageOptions, hooks$1);
return Page(pageOptions)
}
function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions;
const properties = getProperties(vueOptions.props);
const VueComponent = Vue.extend(vueOptions);
const componentOptions = {
options: {
multipleSlots: true,
addGlobalClass: true
},
data: getData(vueOptions.data),
properties,
attached () {
// props的处理,一个是直接 与 mp 的 properties 对接,另一个是要做成 reactive,且排除掉 render watch
const options = {
propsData: this.properties,
$component: this
};
// 初始化 vue 实例
this.$vm = new VueComponent(options);
this.$vm.mpType = 'component';
this.$vm.$mp = {
data: {},
component: this
};
initRefs(this.$vm);
initMocks(this.$vm);
// 初始化渲染数据
this.$vm.$mount();
},
ready () {
this.triggerEvent('__l', this.$vm);
const eventId = this.dataset.eventId;
if (eventId) {
const listeners = this.$vm.$parent.$mp.listeners;
if (listeners) {
const listenerOpts = listeners[eventId];
Object.keys(listenerOpts).forEach(eventType => {
listenerOpts[eventType].forEach(handler => {
this.$vm[handler.once ? '$once' : '$on'](eventType, handler);
});
});
}
}
this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady');
},
detached () {
this.$vm.$destroy();
},
pageLifetimes: {
show (args) {
this.$vm.__call_hook('onPageShow', args);
},
hide () {
this.$vm.__call_hook('onPageHide');
},
resize (size) {
this.$vm.__call_hook('onPageResize', size);
}
},
methods: {
__e: handleEvent,
__l: handleLink
}
};
return Component(componentOptions)
}
let uni = {};
if (typeof Proxy !== 'undefined') {
uni = new Proxy({}, {
get (target, name) {
if (name === 'upx2px') {
return upx2px
}
if (api[name]) {
return promisify(name, api[name])
}
if (extraApi[name]) {
return promisify(name, extraApi[name])
}
if (todoApis[name]) {
return promisify(name, todoApis[name])
}
if (!hasOwn(wx, name) && !hasOwn(protocols, name)) {
return
}
return promisify(name, wrapper(name, wx[name]))
}
});
} else {
uni.upx2px = upx2px;
Object.keys(todoApis).forEach(name => {
uni[name] = promisify(name, todoApis[name]);
});
Object.keys(extraApi).forEach(name => {
uni[name] = promisify(name, todoApis[name]);
});
Object.keys(api).forEach(name => {
uni[name] = promisify(name, api[name]);
});
Object.keys(wx).forEach(name => {
if (hasOwn(wx, name) || hasOwn(protocols, name)) {
uni[name] = promisify(name, wrapper(name, wx[name]));
}
});
}
var uni$1 = uni;
export default uni$1;
export { createApp, createPage, createComponent };
@@ -0,0 +1,11 @@
{
"name": "@dcloudio/uni-app-plus",
"version": "0.0.1",
"description": "uni-app app-plus",
"main": "dist/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "fxy060608",
"license": "Apache-2.0"
}
@@ -0,0 +1,55 @@
const {
done
} = require('@vue/cli-shared-utils')
const { showRunPrompt } = require('@dcloudio/uni-cli-shared')
class WebpackAppPlusNVuePlugin {
apply (compiler) {
let isFirst = !process.env.UNI_USING_NATIVE && !process.env.UNI_USING_V3_NATIVE
if (process.env.UNI_AUTOMATOR_WS_ENDPOINT) {
isFirst = true
}
const chunkVersions = {}
const changedFiles = []
compiler.hooks.emit.tapAsync('webpack-uni-nvue', (compilation, callback) => {
changedFiles.length = 0
compilation.chunks.forEach(chunk => {
const oldVersion = chunkVersions[chunk.name]
chunkVersions[chunk.name] = chunk.hash
if (chunk.hash !== oldVersion && Array.isArray(chunk.files)) {
chunk.files.forEach(file => {
!changedFiles.includes(file) && (changedFiles.push(file))
})
}
})
callback()
})
compiler.hooks.done.tapPromise('webpack-uni-nvue', compilation => {
return new Promise((resolve, reject) => {
if (isFirst) {
isFirst = false
} else {
if (process.env.NODE_ENV === 'development') {
if (
changedFiles.length > 0 &&
!changedFiles.find(file => file === 'app-config.js' || file === 'app-service.js')
) {
done('Build complete. PAGES:' + JSON.stringify(changedFiles))
} else {
done('Build complete. Watching for changes...')
showRunPrompt()
}
} else {
done('Build complete. ')
showRunPrompt()
}
}
resolve()
})
})
}
}
module.exports = WebpackAppPlusNVuePlugin
@@ -0,0 +1,171 @@
const fs = require('fs')
const path = require('path')
const uniI18n = require('@dcloudio/uni-cli-i18n')
const {
log,
done
} = require('@vue/cli-shared-utils')
const {
showRunPrompt
} = require('@dcloudio/uni-cli-shared')
let nvueCompiled = true
let serviceCompiled = true
let viewCompiled = true
const nvueChangedFiles = []
const serviceChangedFiles = []
const viewChangedFiles = []
let isFirst = true
let compiling = false
class WebpackAppPlusPlugin {
apply (compiler) {
if (process.env.UNI_USING_V3) {
const chunkVersions = {}
let isAppService = false
let isAppView = false
let isAppNVue = false
const entry = compiler.options.entry()
// 兼容webpack5
if (entry instanceof Promise) {
compiler.hooks.beforeRun.tapAsync('EntryListPlugin', (compilation, callback) => {
entry.then(entry => {
isAppService = !!entry['app-service']
isAppView = !!entry['app-view']
isAppNVue = !isAppService && !isAppView
callback()
}).catch(callback)
})
} else {
isAppService = !!entry['app-service']
isAppView = !!entry['app-view']
isAppNVue = !isAppService && !isAppView
}
compiler.hooks.invalid.tap('WebpackAppPlusPlugin', (fileName, changeTime) => {
if (!compiling) {
compiling = true
console.log(uniI18n.__('performingHotReload'))
}
})
compiler.hooks.beforeCompile.tapAsync('WebpackAppPlusPlugin', (params, callback) => {
isAppNVue && (nvueCompiled = false)
isAppService && (serviceCompiled = false)
isAppView && (viewCompiled = false)
callback()
})
compiler.hooks.emit.tapAsync('WebpackAppPlusPlugin', (compilation, callback) => {
compilation.chunks.forEach(chunk => {
const oldVersion = chunkVersions[chunk.name]
chunkVersions[chunk.name] = chunk.hash
if (chunk.hash !== oldVersion && Array.isArray(chunk.files)) {
chunk.files.forEach(file => {
if (isAppService) {
!serviceChangedFiles.includes(file) && (serviceChangedFiles.push(file))
} else if (isAppView) {
!viewChangedFiles.includes(file) && (viewChangedFiles.push(file))
} else if (isAppNVue) {
!nvueChangedFiles.includes(file) && (nvueChangedFiles.push(file))
}
})
}
})
callback()
})
compiler.hooks.done.tapPromise('WebpackAppPlusPlugin', stats => {
return new Promise((resolve, reject) => {
isAppNVue && (nvueCompiled = true)
isAppService && (serviceCompiled = true)
isAppView && (viewCompiled = true)
if (serviceCompiled && viewCompiled && nvueCompiled) {
if (process.env.NODE_ENV === 'development') {
const changedFiles = [...new Set([
...serviceChangedFiles,
...viewChangedFiles,
...nvueChangedFiles
])]
let utsChangedFiles = []
try {
utsChangedFiles = JSON.parse(process.env.UNI_APP_UTS_CHANGED_FILES || '[]')
if (utsChangedFiles.length) {
changedFiles.push(...utsChangedFiles)
}
process.env.UNI_APP_UTS_CHANGED_FILES = ''
} catch (e) {}
if (!isFirst && changedFiles.length > 0) {
if (serviceChangedFiles.length === 0 && viewChangedFiles.length === 0 && utsChangedFiles
.length === 0) {
// 仅 nvue 页面发生变化
done('Build complete. PAGES:' + JSON.stringify(changedFiles))
} else {
done('Build complete. FILES:' + JSON.stringify(changedFiles))
}
} else {
// if (!stats.hasErrors()) {
!process.env.UNI_AUTOMATOR_WS_ENDPOINT && done('Build complete. Watching for changes...')
showRunPrompt()
// };
}
isFirst = false
} else {
done('Build complete. ')
showRunPrompt()
}
nvueChangedFiles.length = 0
serviceChangedFiles.length = 0
viewChangedFiles.length = 0
compiling = false
}
resolve()
})
})
} else {
compiler.hooks.done.tapPromise('WebpackAppPlusPlugin', stats => {
return new Promise((resolve, reject) => {
if (process.env.UNI_USING_NATIVE || process.env.UNI_USING_V3_NATIVE) {
return resolve()
}
const callback = function () {
fs.copyFileSync(path.resolve(process.env.UNI_OUTPUT_TMP_DIR,
'manifest.json'),
path.resolve(process.env.UNI_OUTPUT_DIR, 'manifest.json'))
log()
if (process.env.NODE_ENV === 'development') {
done('Build complete. Watching for changes...')
} else {
done('Build complete. ')
}
showRunPrompt()
resolve()
}
// Copy manifest.json
const wxmp = require(path.resolve(process.env.UNI_HBUILDERX_PLUGINS,
'weapp-tools/lib'))
try {
wxmp(
process.env.UNI_OUTPUT_TMP_DIR,
process.env.UNI_OUTPUT_DIR,
path.basename(process.env.UNI_INPUT_DIR),
callback
)
} catch (e) {
resolve()
console.error(e.message)
}
})
})
}
}
}
module.exports = WebpackAppPlusPlugin
@@ -0,0 +1,202 @@
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
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
@@ -0,0 +1,80 @@
const fs = require('fs')
const path = require('path')
const loaderUtils = require('loader-utils')
const {
parseComponent
} = require('weex-template-compiler')
const {
attrsToQuery
} = require('vue-loader/lib/codegen/utils')
const {
normalizePath,
getPlatformStat,
getDevUniConsoleCode
} = require('@dcloudio/uni-cli-shared')
const appVuePath = path.resolve(process.env.UNI_INPUT_DIR, 'App.vue')
function genStyleRequest (style, i, stringifyRequest) {
const src = style.src || normalizePath(appVuePath)
const attrsQuery = attrsToQuery(style.attrs, 'css')
const query = `?vue&type=style&index=${i}${attrsQuery}`
return stringifyRequest(src + query)
}
function getAppStyleCode (stringifyRequest) {
if (!process.env.UNI_USING_NVUE_COMPILER) {
return ''
}
let code = 'Vue.prototype.__$appStyle__ = {}\n'
let styles = []
try {
if (fs.existsSync(appVuePath)) {
styles = parseComponent(fs.readFileSync(appVuePath, 'utf8')).styles
}
} catch (e) {}
styles.forEach((style, index) => {
code = code +
`Vue.prototype.__merge_style && Vue.prototype.__merge_style(require(${genStyleRequest(style, index, stringifyRequest)}).default,Vue.prototype.__$appStyle__)\n`
})
return code
}
module.exports = function (content, map) {
this.cacheable && this.cacheable()
const loaderContext = this
const statCode = getPlatformStat()
const uniConsoleCode = getDevUniConsoleCode()
if (this.resourceQuery) {
const params = loaderUtils.parseQuery(this.resourceQuery)
if (params) {
if (params.page) {
params.page = decodeURIComponent(params.page)
// import Vue from 'vue'是为了触发 vendor 合并
return `${uniConsoleCode}
${statCode}
import 'uni-app-style'
import 'uni-polyfill'
import App from './${normalizePath(params.page)}.nvue?mpType=page'
App.mpType = 'page'
App.route = '${params.page}'
App.el = '#root'
new Vue(App)
`
} else if (params.type === 'appStyle') {
const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
return `${getAppStyleCode(stringifyRequest)}`
}
}
}
const automatorCode = process.env.UNI_AUTOMATOR_WS_ENDPOINT ? 'import \'@dcloudio/uni-app-plus/dist/automator\';'
: ''
return uniConsoleCode + automatorCode + statCode + content
}
@@ -0,0 +1,81 @@
var path = require('path')
var styler = require('weex-styler')
var {
normalizePath
} = require('@dcloudio/uni-cli-shared')
module.exports = function (content, map) {
this.cacheable && this.cacheable()
this.callback(null, 'module.exports = ' + genStyleString(content, this), map)
}
const uniI18n = require('@dcloudio/uni-cli-i18n')
// @todo:
// font-relative lengths: em, ex, ch, ic
// viewport-relative lengths: vi, vb
// https://drafts.csswg.org/css-values/#lengths
var REGEXP_LENGTH = /^([-+]?[0-9]*\.?[0-9]+)(rem|vw|vh|vmin|vmax|cm|mm|q|in|pt|pc|px)$/
function convertLength (k, v) {
if (typeof v !== 'string') {
return v
}
var result = v.match(REGEXP_LENGTH)
if (result) {
if (result[2] === 'px') {
return result[1]
}
return result[1] + 'CSS_UNIT_' + result[2].toUpperCase()
}
return v
}
let isFirst = true
function genStyleString (input, loader) {
var output = '{}'
var resourcePath = normalizePath(path.relative(process.env.UNI_INPUT_DIR, loader.resourcePath))
styler.parse(input, function (err, obj) {
if (err) {
loader.emitError(err)
return
}
if (obj && obj.jsonStyle) {
if (obj.log) {
var msgs = []
obj.log.map((log) => {
if (log.reason.indexOf('NOTE:') !== 0) { // 仅显示警告,错误信息
if (log.selectors) {
msgs.push(`${log.selectors}: ${log.reason} at ${resourcePath}:${log.line}`)
} else {
msgs.push(`${log.reason} at ${resourcePath}:${log.line}`)
}
}
})
if (msgs.length) {
if (isFirst) {
msgs.unshift(uniI18n.__('pluginHbuilderx.nvueCssWarning'))
isFirst = false
}
msgs.forEach(msg => {
switch (msg.split(':')[0]) {
case 'ERROR':
console.error(msg)
break
case 'WARNING' :
console.warn(msg)
break
default:
console.log(msg)
break
}
})
}
}
try {
output = JSON.stringify(obj.jsonStyle, convertLength, 2)
.replace(/"([-+]?[0-9]*\.?[0-9]+)CSS_UNIT_([A-Z]+)"/g, '$1 * CSS_UNIT.$2')
} catch (e) {}
}
})
return output
}
@@ -0,0 +1,82 @@
const path = require('path')
const {
removeExt,
normalizePath,
getPagesJson
} = require('@dcloudio/uni-cli-shared')
const {
normalizeNodeModules
} = require('@dcloudio/webpack-uni-mp-loader/lib/shared')
const SCROLLER_COMPONENTS = [
'list',
'scroller',
'scroll-view',
'waterfall'
]
module.exports = function (content, map) {
this.cacheable && this.cacheable()
const source = content.trim()
if (SCROLLER_COMPONENTS.find(name => source.indexOf('<' + name) === 0)) {
return this.callback(null, content, map)
}
if (source.indexOf('<recycle-list') !== -1) {
return this.callback(null, content, map)
}
let resourcePath = normalizeNodeModules(
removeExt(normalizePath(path.relative(process.env.UNI_INPUT_DIR, this.resourcePath)))
)
if (
!process.UNI_NVUE_ENTRY[resourcePath] &&
this._module.issuer &&
this._module.issuer.issuer
) {
// <template src=""/>
resourcePath = normalizeNodeModules(
removeExt(normalizePath(path.relative(process.env.UNI_INPUT_DIR, this._module.issuer.issuer.resource)))
)
}
if (!process.UNI_NVUE_ENTRY[resourcePath]) {
return this.callback(null, content, map)
}
// 暂时实时读取配置信息,查找是否 disableScroll
const appJson = getPagesJson()
let pageJson
if (appJson.nvue) { // 旧版本
if (!appJson.nvue || !appJson.nvue.pages) {
return this.callback(null, content, map)
}
const pagePath = resourcePath + '.html'
pageJson = appJson.nvue.pages.find(page => page.path === pagePath)
} else {
pageJson = appJson.pages.find(page => page.path === resourcePath)
}
if (!pageJson) {
return this.callback(null, content, map)
}
if (!appJson.globalStyle) {
appJson.globalStyle = {}
}
Object.assign(appJson.globalStyle, appJson.globalStyle['app-plus'] || {})
pageJson.style = pageJson.style || {}
Object.assign(pageJson.style, pageJson.style['app-plus'] || {})
const pageJsonStyle = Object.assign(appJson.globalStyle, pageJson.style)
if (pageJsonStyle.disableScroll === true) {
return this.callback(null, content, map)
}
this.callback(null,
`<scroll-view :scroll-y="true" :show-scrollbar="${pageJsonStyle.scrollIndicator === 'none' ? 'false' : 'true'}" :enableBackToTop="true" bubble="true" style="flex-direction:column">${content}</scroll-view>`,
map)
}
@@ -0,0 +1,18 @@
const loaderUtils = require('loader-utils')
module.exports = function (content, map) {
this.cacheable && this.cacheable()
const vueLoaderOptions = this.loaders.find(loader => loader.ident === 'vue-loader-options')
if (vueLoaderOptions) {
const params = loaderUtils.parseQuery(this.resourceQuery)
if (params.recyclable) {
Object.assign(vueLoaderOptions.options.compilerOptions, {
recyclable: true
})
}
} else {
throw new Error('vue-loader-options parse error')
}
this.callback(null, content, map)
}
@@ -0,0 +1,10 @@
{
"name": "@dcloudio/webpack-uni-nvue-loader",
"version": "0.0.1",
"description": "webpack-uni-nvue-loader",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "fxy060608",
"license": "Apache-2.0"
}
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-present, songsiqi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,124 @@
# Weex `<style>` Transformer
[![NPM version][npm-image]][npm-url]
[![Build status][circle-image]][circle-url]
[![Downloads][downloads-image]][downloads-url]
[npm-image]: https://img.shields.io/npm/v/weex-styler.svg?style=flat-square
[npm-url]: https://npmjs.org/package/weex-styler
[circle-image]: https://circleci.com/gh/alibaba/weex_toolchain.svg?style=svg
[circle-url]: https://circleci.com/gh/alibaba/weex_toolchain/tree/master
[downloads-image]: https://img.shields.io/npm/dm/weex-styler.svg?style=flat-square
[downloads-url]: https://npmjs.org/package/weex-styler
## Features
- convert a `<style>` element to JSON format
- autofix common mistakes
- friendly warnings
## API
- `parse(code, done)`
- `validate(json, done)`
- `validateItem(name, value)`
### util api
- `util.hyphenedToCamelCase(value)`
- `util.camelCaseToHyphened(value)`
```javascript
/**
* Parse `<style>` code to a JSON Object and log errors & warnings
*
* @param {string} code
* @param {function} done
*/
function parse(code, done) {}
/**
* Validate a JSON Object and log errors & warnings
*
* @param {object} json
* @param {function} done
*/
function validate(json, done) {}
/**
* Result callback
*
* data
* - jsonStyle{}: `classname.propname.value`-like object
* - log[{line, column, reason}]
*
* @param {Error} err
* @param {object} data
*/
function done(err, data) {}
/**
* Validate a single name-value pair
*
* @param {string} name camel cased
* @param {string} value
* @return {object}
* - value
* - log{reason}
*/
function validateItem(name, value) {}
```
## Validation
- rule check: only common rule type supported, othres will be ignored
- selector check: only single-classname selector is supported, others will be ignored
- prop name check: out-of-defined prop name will be warned but preserved
- prop value check: common prop value mistakes will be autofixed or ignored
+ color type: keywords, `#xxx` -> warning: `#xxxxxx`
+ color type: `transparent` -> error: not supported
+ length type: `100px` -> warning: `100`
## Demo
```javascript
var styler = require('weex-styler')
var code = 'html {color: #000000;} .foo {color: red; -webkit-transform: rotate(90deg); width: 200px;}'
styler.parse(code, function (err, data) {
// syntax error
// format: {line, column, reason, ...}
err
// result
// {foo: {color: '#ff0000', webkitTransform: 'rotate(90deg)', width: 200}}
data.jsonStyle
// format: {line, column, reason}
// - Error: Selector `html` is not supported. Weex only support single-classname selector
// - Warning: prop value `red` is autofixed to `#ff0000`
// - Warning: prop name `-webkit-transform` is not supported
// - Warning: prop value `200px` is autofixed to `200`
data.log[]
})
var jsonStyle = {
foo: {
color: 'red',
webkitTransform: 'rotate(90deg)',
width: '200px'
}
}
styler.validate(json, function (err, data) {
// syntax error
err
// result
// {foo: {color: '#ff0000', webkitTransform: 'rotate(90deg)', width: 200}}
data.jsonStyle
// format: {reason}
// - Warning: prop value `red` is autofixed to `#ff0000`
// - Warning: prop name `-webkit-transform` is not supported
// - Warning: prop value `200px` is autofixed to `200`
data.log[]
})
```
@@ -0,0 +1,3 @@
machine:
node:
version: 4.2.1
@@ -0,0 +1,25 @@
var gulp = require('gulp')
var jscs = require('gulp-jscs')
var mocha = require('gulp-mocha')
gulp.task('default', ['test'], function() {
console.log('done')
})
gulp.task('watch', function () {
return gulp.watch('**/*.js', ['test'])
})
gulp.task('test', ['jscs', 'mocha'], function () {
console.log('test done')
})
gulp.task('mocha', function () {
return gulp.src([
'test/*.js'
]).pipe(mocha())
})
gulp.task('jscs', function () {
return gulp.src('**/*.js').pipe(jscs())
})
@@ -0,0 +1,231 @@
'use strict'
var css = require('css')
var util = require('./lib/util')
var validateItem = require('./lib/validator').validate
var shorthandParser = require('./lib/shorthand-parser')
/**
* mergeStyle
* @param {*} object
* @param {*} classNames
* @param {*} preClassNames
* @param {*} ruleResult
* @param {*} prop
* @param {*} index
*/
function mergeStyle (object, classNames, preClassNames, ruleResult, prop, index) {
if (!process.env.UNI_USING_NVUE_STYLE_COMPILER) {
object[classNames] = object[classNames] || {}
object[classNames][prop] = ruleResult[prop]
return
}
classNames = classNames.split('.').map(str => '.' + str).slice(1)
var className = classNames.find(className => className in object) || classNames[0]
// 假设选择器已经去重简化
preClassNames += classNames.filter(str => str !== className).sort().join('')
var rules = object[className] = object[className] || {}
var style = rules[preClassNames] = rules[preClassNames] || {}
// 增加其他权重信息
style[prop] = [...ruleResult[prop], preClassNames.split('.').length - 1, index]
}
/**
* Parse `<style>` code to a JSON Object and log errors & warnings
*
* @param {string} code
* @param {function} done which will be called with
* - err:Error
* - data.jsonStyle{}: `classname.propname.value`-like object
* - data.log[{line, column, reason}]
*/
function parse (code, done) {
var ast, err, jsonStyle = {}, log = []
// css parse
ast = css.parse(code, { silent: true })
// catch syntax error
if (ast.stylesheet.parsingErrors && ast.stylesheet.parsingErrors.length) {
err = ast.stylesheet.parsingErrors
err.forEach(function (error) {
log.push({ line: error.line, column: error.column, reason: error.toString().replace('Error', 'ERROR') })
})
}
// walk all
/* istanbul ignore else */
if (ast && ast.type === 'stylesheet' && ast.stylesheet &&
ast.stylesheet.rules && ast.stylesheet.rules.length) {
ast.stylesheet.rules.forEach(function (rule, index) {
var type = rule.type
var ruleResult = {}
var ruleLog = []
if (type === 'rule') {
if (rule.declarations && rule.declarations.length) {
rule.declarations = shorthandParser(rule.declarations)
rule.declarations.forEach(function (declaration) {
var subType = declaration.type
var name, value, line, column, subResult, camelCasedName
/* istanbul ignore if */
if (subType !== 'declaration') {
return
}
name = declaration.property
value = declaration.value
var newValue = value.replace(/\s*!important/g, '')
var importantWeight = Number(value !== newValue)
value = newValue
// validate declarations and collect them to result
camelCasedName = util.hyphenedToCamelCase(name)
subResult = validateItem(camelCasedName, value)
/* istanbul ignore else */
if (typeof subResult.value === 'number' || typeof subResult.value === 'string') {
if (process.env.UNI_USING_NVUE_STYLE_COMPILER) {
var oldValue = ruleResult[camelCasedName]
// 增加 important 权重信息
ruleResult[camelCasedName] = Array.isArray(oldValue) && oldValue[1] > importantWeight ? oldValue : [subResult.value, importantWeight]
} else {
ruleResult[camelCasedName] = subResult.value
}
}
if (subResult.log) {
subResult.log.line = declaration.position.start.line
subResult.log.column = declaration.position.start.column
ruleLog.push(subResult.log)
}
})
rule.selectors.forEach(function (selector) {
selector = selector.replace(/\s*([\+\~\>])\s*/g, '$1').replace(/\s+/, ' ')
// 支持组合选择器
const res = selector.match(process.env.UNI_USING_NVUE_STYLE_COMPILER ? /^((?:(?:\.[A-Za-z0-9_\-]+)+[\+\~\> ])*)((?:\.[A-Za-z0-9_\-\:]+)+)$/ : /^(\.)([A-Za-z0-9_\-:]+)$/)
if (res) {
var preClassNames = res[1]
var classNames = res[2]
// handle pseudo class
var pseudoIndex = classNames.indexOf(':')
if (pseudoIndex > -1) {
var pseudoCls = classNames.slice(pseudoIndex)
classNames = classNames.slice(0, pseudoIndex)
var pseudoRuleResult = {}
Object.keys(ruleResult).forEach(function (prop) {
pseudoRuleResult[prop + pseudoCls] = ruleResult[prop]
})
ruleResult = pseudoRuleResult
}
// merge style
Object.keys(ruleResult).forEach(function (prop) {
// // handle transition
// if (prop.indexOf('transition') === 0 && prop !== 'transition') {
// var realProp = prop.replace('transition', '')
// realProp = realProp[0].toLowerCase() + realProp.slice(1)
// var object = jsonStyle['@TRANSITION'] = jsonStyle['@TRANSITION'] || {}
// mergeStyle(object, classNames, preClassNames, ruleResult, prop, index)
// }
mergeStyle(jsonStyle, classNames, preClassNames, ruleResult, prop, index)
})
}
else {
log.push({
line: rule.position.start.line,
column: rule.position.start.column,
reason: 'ERROR: Selector `' + selector + '` is not supported. Weex only support classname selector'
})
}
})
log = log.concat(ruleLog)
}
}
/* istanbul ignore else */
else if (type === 'font-face') {
/* istanbul ignore else */
if (rule.declarations && rule.declarations.length) {
rule.declarations.forEach(function (declaration) {
/* istanbul ignore if */
if (declaration.type !== 'declaration') {
return
}
var name = util.hyphenedToCamelCase(declaration.property)
var value = declaration.value
if (name === 'fontFamily' && '\"\''.indexOf(value[0]) > -1) { // FIXME: delete leading and trailing quotes
value = value.slice(1, value.length - 1)
}
ruleResult[name] = value
})
if (!jsonStyle['@FONT-FACE']) {
jsonStyle['@FONT-FACE'] = []
}
jsonStyle['@FONT-FACE'].push(ruleResult)
}
}
})
}
jsonStyle['@VERSION'] = 2
done(err, { jsonStyle: jsonStyle, log: log })
}
/**
* Validate a JSON Object and log errors & warnings
*
* @param {object} json
* @param {function} done which will be called with
* - err:Error
* - data.jsonStyle{}: `classname.propname.value`-like object
* - data.log[{reason}]
*/
function validate (json, done) {
var log = []
var err
try {
json = JSON.parse(JSON.stringify(json))
}
catch (e) {
err = e
json = {}
}
Object.keys(json).forEach(function (selector) {
var declarations = json[selector]
Object.keys(declarations).forEach(function (name) {
var value = declarations[name]
var result = validateItem(name, value)
if (typeof result.value === 'number' || typeof result.value === 'string') {
declarations[name] = result.value
}
else {
delete declarations[name]
}
if (result.log) {
log.push(result.log)
}
})
})
done(err, {
jsonStyle: json,
log: log
})
}
module.exports = {
parse: parse,
validate: validate,
validateItem: validateItem,
util: util
}
@@ -0,0 +1,233 @@
function generateDeclaration (property, value, important, position) {
return {
type: 'declaration',
property,
value: value + (important ? ' !important' : ''),
position
}
}
function clearImportant (value) {
var newValue = value.replace(/\s*!important/g, '')
return {
value: newValue,
important: value !== newValue
}
}
function transition (declaration) {
var CHUNK_REGEXP = /^([a-z-_]\S*)(\s+[\d.]+m?s)?(\s+[a-z-_]\S*)?(\s+[\d.]+m?s)?/
var { value, important } = clearImportant(declaration.value)
var values = value.replace(/(\d)\s*,\s*/g, '$1#').split(',')
var position = declaration.position
var result = []
var map = {
'transition-property': [],
'transition-duration': [],
'transition-timing-function': [],
'transition-delay': []
}
if (values.length) {
for (var i1 = 0; i1 < values.length; i1++) {
var match = values[i1].trim().match(CHUNK_REGEXP)
if (!match) {
return []
}
map['transition-property'].push(match[1] || 'all')
map['transition-duration'].push((match[2] || '0s').trim())
map['transition-timing-function'].push((match[3] || 'ease').trim().replace(/#/g, ', '))
map['transition-delay'].push((match[4] || '0s').trim())
}
for (var key in map) {
var value = map[key]
value = value.find(item => item !== value[0]) ? value.join(', ') : value[0]
result.push(generateDeclaration(key, value, important, position))
}
}
return result
}
function createParser (property) {
return function (declaration) {
var { value, important } = clearImportant(declaration.value)
var position = declaration.position
var splitResult = value.split(/\s+/)
var result = []
switch (splitResult.length) {
case 1:
splitResult.push(splitResult[0], splitResult[0], splitResult[0])
break
case 2:
splitResult.push(splitResult[0], splitResult[1])
break
case 3:
splitResult.push(splitResult[1])
break
}
result.push(
generateDeclaration(property + '-top', splitResult[0], important, position),
generateDeclaration(property + '-right', splitResult[1], important, position),
generateDeclaration(property + '-bottom', splitResult[2], important, position),
generateDeclaration(property + '-left', splitResult[3], important, position)
)
return result
}
}
var margin = createParser('margin')
var padding = createParser('padding')
function border (declaration) {
var { value, important } = clearImportant(declaration.value)
var property = declaration.property
var position = declaration.position
var splitResult = value.replace(/\s*,\s*/g, ',').split(/\s+/)
var result = [/^[\d\.]+\S*$/, /^(solid|dashed|dotted)$/, /\S+/].map(item => {
var index = splitResult.findIndex(str => item.test(str))
return index < 0 ? null : splitResult.splice(index, 1)[0]
})
if (splitResult.length) {
return declaration
}
return [
generateDeclaration(property + '-width', (result[0] || '0').trim(), important, position),
generateDeclaration(property + '-style', (result[1] || 'solid').trim(), important, position),
generateDeclaration(property + '-color', (result[2] || '#000000').trim(), important, position)
]
}
function borderProperty (declaration) {
var { value, important } = clearImportant(declaration.value)
var position = declaration.position
var property = declaration.property.split('-')[1]
var splitResult = value.replace(/\s*,\s*/g, ',').split(/\s+/)
var result = []
switch (splitResult.length) {
case 1:
return declaration
case 2:
splitResult.push(splitResult[0], splitResult[1])
break
case 3:
splitResult.push(splitResult[1])
break
}
result.push(
generateDeclaration('border-top-' + property, splitResult[0], important, position),
generateDeclaration('border-right-' + property, splitResult[1], important, position),
generateDeclaration('border-bottom-' + property, splitResult[2], important, position),
generateDeclaration('border-left-' + property, splitResult[3], important, position)
)
return result
}
function borderRadius (declaration) {
var { value, important } = clearImportant(declaration.value)
var position = declaration.position
var splitResult = value.split(/\s+/)
var result = []
if (value.includes('/')) {
return declaration
}
switch (splitResult.length) {
case 1:
return declaration
case 2:
splitResult.push(splitResult[0], splitResult[1])
break
case 3:
splitResult.push(splitResult[1])
break
}
result.push(
generateDeclaration('border-top-left-radius', splitResult[0], important, position),
generateDeclaration('border-top-right-radius', splitResult[1], important, position),
generateDeclaration('border-bottom-right-radius', splitResult[2], important, position),
generateDeclaration('border-bottom-left-radius', splitResult[3], important, position)
)
return result
}
function flexFlow (declaration) {
var { value, important } = clearImportant(declaration.value)
var position = declaration.position
var splitResult = value.split(/\s+/)
var result = [/^(column|column-reverse|row|row-reverse)$/, /^(nowrap|wrap|wrap-reverse)$/].map(item => {
var index = splitResult.findIndex(str => item.test(str))
return index < 0 ? null : splitResult.splice(index, 1)[0]
})
if (splitResult.length) {
return declaration
}
return [
generateDeclaration('flex-direction', result[0] || 'column', important, position),
generateDeclaration('flex-wrap', result[1] || 'nowrap', important, position)
]
}
function font (declaration) {
var { value, important } = clearImportant(declaration.value)
var position = declaration.position
var splitResult = value.replace(/,\s*/g, ',').replace(/\s*\/\s*/, '/').replace(/['"].+?['"]/g, str => str.replace(/\s+/g, '#')).split(/\s+/)
var result = []
var styleValues = ['normal', 'italic', 'oblique']
result.push(generateDeclaration('font-style', styleValues[Math.max(0, styleValues.indexOf(splitResult[0]))], important, position))
var weight = splitResult.slice(0, -2).find(str => /normal|bold|lighter|bolder|\d+/.test(str))
if (weight) {
result.push(generateDeclaration('font-weight', weight, important, position))
}
splitResult = splitResult.slice(-2)
if (/[\d\.]+\S*(\/[\d\.]+\S*)?/.test(splitResult[0])) {
var [size, height] = splitResult[0].split('/')
result.push(
generateDeclaration('font-size', size, important, position),
generateDeclaration('line-height', height || 'normal', important, position),
generateDeclaration('font-family', splitResult[1].replace(/#/g, ' '), important, position)
)
return result
}
return []
}
function background (declaration) {
var { value, important } = clearImportant(declaration.value)
var position = declaration.position
if (/^#?\S+$/.test(value) || /^rgba?(.+)$/.test(value)) {
return generateDeclaration('background-color', value, important, position)
} else if (/^linear-gradient(.+)$/.test(value)) {
return generateDeclaration('background-image', value, important, position)
} else {
return declaration
}
}
var parserCollection = {
transition,
margin,
padding,
border,
'border-top': border,
'border-right': border,
'border-bottom': border,
'border-left': border,
'border-style': borderProperty,
'border-width': borderProperty,
'border-color': borderProperty,
'border-radius': borderRadius,
'flex-flow': flexFlow,
font,
background
}
module.exports = function (declarations) {
return declarations.reduce((result, declaration) => {
var parser = parserCollection[declaration.property]
if (parser) {
return result.concat(parser(declaration))
} else {
result.push(declaration)
return result
}
}, [])
}
@@ -0,0 +1,30 @@
/**
* rules:
* - abc-def -> abcDef
* - -abc-def -> AbcDef
*
* @param {string} value
* @return {string}
*/
exports.hyphenedToCamelCase = function hyphenedToCamelCase(value) {
return value.replace(/-([a-z])/g, function(s, m) {
return m.toUpperCase()
})
}
/**
* rules:
* - abcDef -> abc-def
* - AbcDef -> -abc-def
*
* @param {string} value
* @return {string}
*/
exports.camelCaseToHyphened = function camelCaseToHyphened(value) {
return value.replace(/([A-Z])/g, function(s, m) {
if (typeof m === 'string') {
return '-' + m.toLowerCase()
}
return m
})
}
@@ -0,0 +1,725 @@
var util = require('./util')
// http://www.w3.org/TR/css3-color/#html4
var BASIC_COLOR_KEYWORDS = {
black: '#000000',
silver: '#C0C0C0',
gray: '#808080',
white: '#FFFFFF',
maroon: '#800000',
red: '#FF0000',
purple: '#800080',
fuchsia: '#FF00FF',
green: '#008000',
lime: '#00FF00',
olive: '#808000',
yellow: '#FFFF00',
navy: '#000080',
blue: '#0000FF',
teal: '#008080',
aqua: '#00FFFF'
}
// http://www.w3.org/TR/css3-color/#svg-color
var EXTENDED_COLOR_KEYWORDS = {
aliceblue: '#F0F8FF',
antiquewhite: '#FAEBD7',
aqua: '#00FFFF',
aquamarine: '#7FFFD4',
azure: '#F0FFFF',
beige: '#F5F5DC',
bisque: '#FFE4C4',
black: '#000000',
blanchedalmond: '#FFEBCD',
blue: '#0000FF',
blueviolet: '#8A2BE2',
brown: '#A52A2A',
burlywood: '#DEB887',
cadetblue: '#5F9EA0',
chartreuse: '#7FFF00',
chocolate: '#D2691E',
coral: '#FF7F50',
cornflowerblue: '#6495ED',
cornsilk: '#FFF8DC',
crimson: '#DC143C',
cyan: '#00FFFF',
darkblue: '#00008B',
darkcyan: '#008B8B',
darkgoldenrod: '#B8860B',
darkgray: '#A9A9A9',
darkgreen: '#006400',
darkgrey: '#A9A9A9',
darkkhaki: '#BDB76B',
darkmagenta: '#8B008B',
darkolivegreen: '#556B2F',
darkorange: '#FF8C00',
darkorchid: '#9932CC',
darkred: '#8B0000',
darksalmon: '#E9967A',
darkseagreen: '#8FBC8F',
darkslateblue: '#483D8B',
darkslategray: '#2F4F4F',
darkslategrey: '#2F4F4F',
darkturquoise: '#00CED1',
darkviolet: '#9400D3',
deeppink: '#FF1493',
deepskyblue: '#00BFFF',
dimgray: '#696969',
dimgrey: '#696969',
dodgerblue: '#1E90FF',
firebrick: '#B22222',
floralwhite: '#FFFAF0',
forestgreen: '#228B22',
fuchsia: '#FF00FF',
gainsboro: '#DCDCDC',
ghostwhite: '#F8F8FF',
gold: '#FFD700',
goldenrod: '#DAA520',
gray: '#808080',
green: '#008000',
greenyellow: '#ADFF2F',
grey: '#808080',
honeydew: '#F0FFF0',
hotpink: '#FF69B4',
indianred: '#CD5C5C',
indigo: '#4B0082',
ivory: '#FFFFF0',
khaki: '#F0E68C',
lavender: '#E6E6FA',
lavenderblush: '#FFF0F5',
lawngreen: '#7CFC00',
lemonchiffon: '#FFFACD',
lightblue: '#ADD8E6',
lightcoral: '#F08080',
lightcyan: '#E0FFFF',
lightgoldenrodyellow: '#FAFAD2',
lightgray: '#D3D3D3',
lightgreen: '#90EE90',
lightgrey: '#D3D3D3',
lightpink: '#FFB6C1',
lightsalmon: '#FFA07A',
lightseagreen: '#20B2AA',
lightskyblue: '#87CEFA',
lightslategray: '#778899',
lightslategrey: '#778899',
lightsteelblue: '#B0C4DE',
lightyellow: '#FFFFE0',
lime: '#00FF00',
limegreen: '#32CD32',
linen: '#FAF0E6',
magenta: '#FF00FF',
maroon: '#800000',
mediumaquamarine: '#66CDAA',
mediumblue: '#0000CD',
mediumorchid: '#BA55D3',
mediumpurple: '#9370DB',
mediumseagreen: '#3CB371',
mediumslateblue: '#7B68EE',
mediumspringgreen: '#00FA9A',
mediumturquoise: '#48D1CC',
mediumvioletred: '#C71585',
midnightblue: '#191970',
mintcream: '#F5FFFA',
mistyrose: '#FFE4E1',
moccasin: '#FFE4B5',
navajowhite: '#FFDEAD',
navy: '#000080',
oldlace: '#FDF5E6',
olive: '#808000',
olivedrab: '#6B8E23',
orange: '#FFA500',
orangered: '#FF4500',
orchid: '#DA70D6',
palegoldenrod: '#EEE8AA',
palegreen: '#98FB98',
paleturquoise: '#AFEEEE',
palevioletred: '#DB7093',
papayawhip: '#FFEFD5',
peachpuff: '#FFDAB9',
peru: '#CD853F',
pink: '#FFC0CB',
plum: '#DDA0DD',
powderblue: '#B0E0E6',
purple: '#800080',
red: '#FF0000',
rosybrown: '#BC8F8F',
royalblue: '#4169E1',
saddlebrown: '#8B4513',
salmon: '#FA8072',
sandybrown: '#F4A460',
seagreen: '#2E8B57',
seashell: '#FFF5EE',
sienna: '#A0522D',
silver: '#C0C0C0',
skyblue: '#87CEEB',
slateblue: '#6A5ACD',
slategray: '#708090',
slategrey: '#708090',
snow: '#FFFAFA',
springgreen: '#00FF7F',
steelblue: '#4682B4',
tan: '#D2B48C',
teal: '#008080',
thistle: '#D8BFD8',
tomato: '#FF6347',
turquoise: '#40E0D0',
violet: '#EE82EE',
wheat: '#F5DEB3',
white: '#FFFFFF',
whitesmoke: '#F5F5F5',
yellow: '#FFFF00',
yellowgreen: '#9ACD32'
}
var LENGTH_REGEXP = /^[-+]?\d*\.?\d+(\S*)$/
var SUPPORT_CSS_UNIT = ['px', 'pt', 'wx']
if(process.env.UNI_USING_NVUE_COMPILER){
SUPPORT_CSS_UNIT.push('upx')
SUPPORT_CSS_UNIT.push('rpx')
}
var ANYTHING_VALIDATOR = function ANYTHING_VALIDATOR(v) {
return { value: v }
}
/**
* the values below is valid
* - number
* - number + 'px'
*
* @param {string} v
* @return {function} a function to return
* - value: number|null
* - reason(k, v, result)
*/
var LENGTH_VALIDATOR = function LENGTH_VALIDATOR(v) {
v = (v || '').toString()
var match = v.match(LENGTH_REGEXP)
if (match) {
var unit = match[1]
if (!unit) {
return {value: parseFloat(v)}
}
else if (SUPPORT_CSS_UNIT.indexOf(unit) > -1) {
return {value: v}
}
else {
return {
value: parseFloat(v),
reason: function reason(k, v, result) {
return 'NOTE: unit `' + unit + '` is not supported and property value `' + v + '` is autofixed to `' + result + '`'
}
}
}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (only number and pixel values are supported)'
}
}
}
/**
* the values below is valid
* - number {1,4}
* - number + 'px' {1,4}
*
* @param {string} v
* @return {function} a function to return
* - value: number|null
* - reason(k, v, result)
*/
var SHORTHAND_LENGTH_VALIDATOR = function SHORTHAND_LENGTH_VALIDATOR(v) {
v = (v || '').toString()
var value = []
var reason = []
var results = v.split(/\s+/).map(LENGTH_VALIDATOR)
for (var i = 0; i < results.length; ++i) {
var res = results[i]
if (!res.value) {
value = null
reason = res.reason
break
}
value.push(res.value)
reason.push(res.reason)
}
if (!value) {
return {
value: value,
reason: reason
}
} else {
return {
value: value.join(' '),
reason: function (k, v, result) {
return reason.map(function (res) {
if (typeof res === 'function') {
return res(k, v, result)
}
}).join('\n')
}
}
}
}
/**
* the values below is valid
* - hex color value (#xxxxxx or #xxx)
* - basic and extended color keywords in CSS spec
*
* @param {string} v
* @return {function} a function to return
* - value: string|null
* - reason(k, v, result)
*/
var COLOR_VALIDATOR = function COLOR_VALIDATOR(v) {
v = (v || '').toString()
if (v.match(/^#[0-9a-fA-F]{6}$/)) {
return {value: v}
}
if (v.match(/^#[0-9a-fA-F]{3}$/)) {
return {
value: '#' + v[1] + v[1] + v[2] + v[2] + v[3] + v[3],
reason: function reason(k, v, result) {
return 'NOTE: property value `' + v + '` is autofixed to `' + result + '`'
}
}
}
if (EXTENDED_COLOR_KEYWORDS[v]) {
return {
value: EXTENDED_COLOR_KEYWORDS[v],
reason: function reason(k, v, result) {
return 'NOTE: property value `' + v + '` is autofixed to `' + result + '`'
}
}
}
var arrColor, r, g, b, a
var RGB_REGEXP = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/gi
var RGBA_REGEXP = /^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d*\.?\d+)\s*\)$/gi
if (arrColor = RGB_REGEXP.exec(v)) {
r = parseInt(arrColor[1])
g = parseInt(arrColor[2])
b = parseInt(arrColor[3])
if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {
return {value: 'rgb(' + [r, g, b].join(',') + ')'}
}
}
if (arrColor = RGBA_REGEXP.exec(v)) {
r = parseInt(arrColor[1])
g = parseInt(arrColor[2])
b = parseInt(arrColor[3])
a = parseFloat(arrColor[4])
if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255 && a >= 0 && a <= 1) {
return {value: 'rgba(' + [r, g, b, a].join(',') + ')'}
}
}
if (v === 'transparent') {
return {value: 'rgba(0,0,0,0)'}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not valid for `' + util.camelCaseToHyphened(k) + '`'
}
}
}
/**
* only integer or float value is valid
*
* @param {string} v
* @return {function} a function to return
* - value: number|null
* - reason(k, v, result)
*/
var NUMBER_VALIDATOR = function NUMBER_VALIDATOR(v) {
v = (v || '').toString()
var match = v.match(LENGTH_REGEXP)
if (match && !match[1]) {
return {value: parseFloat(v)}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (only number is supported)'
}
}
}
/**
* only integer value is valid
*
* @param {string} v
* @return {function} a function to return
* - value: number|null
* - reason(k, v, result)
*/
var INTEGER_VALIDATOR = function INTEGER_VALIDATOR(v) {
v = (v || '').toString()
if (v.match(/^[-+]?\d+$/)) {
return {value: parseInt(v, 10)}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (only integer is supported)'
}
}
}
/**
* transition-property: only css property is valid
*
* @param {string} v
* @return {function} a function to return
* - value: string|null
* - reason(k, v, result)
*/
var TRANSITION_PROPERTY_VALIDATOR = function TRANSITION_PROPERTY_VALIDATOR(v) {
v = (v || '').toString()
v = v.split(/\s*,\s*/).map(util.hyphenedToCamelCase).join(',')
if (v.split(/\s*,\s*/).every(p => !!validatorMap[p])) {
return {value: v}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (only css property is valid)'
}
}
}
/**
* transition-duration & transition-delay: only number of seconds or milliseconds is valid
*
* @param {string} v
* @return {function} a function to return
* - value: number|null
* - reason(k, v, result)
*/
var TRANSITION_INTERVAL_VALIDATOR = function TRANSITION_INTERVAL_VALIDATOR(v) {
v = (v || 0).toString()
var match, num, ret
if (match = v.match(/^\d*\.?\d+(ms|s)?$/)) {
num = parseFloat(match[0])
if (!match[1]) {
ret = {value: parseInt(num)}
}
else {
if (match[1] === 's') {
num *= 1000
}
ret = {
value: parseInt(num),
reason: function reason(k, v, result) {
return 'NOTE: property value `' + v + '` is autofixed to `' + result + '`'
}
}
}
return ret
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (only number of seconds and milliseconds is valid)'
}
}
}
/**
* transition-timing-function: only linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n) is valid
*
* @param {string} v
* @return {function} a function to return
* - value: linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n)|null
* - reason(k, v, result)
*/
var TRANSITION_TIMING_FUNCTION_VALIDATOR = function TRANSITION_TIMING_FUNCTION_VALIDATOR(v) {
v = (v || '').toString()
if (v.match(/^linear|ease|ease-in|ease-out|ease-in-out$/)) {
return {value: v}
}
var match, ret
var NUM_REGEXP = /^[-]?\d*\.?\d+$/
if (match = v.match(/^cubic-bezier\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*\)$/)) {
/* istanbul ignore else */
if (match[1].match(NUM_REGEXP) && match[2].match(NUM_REGEXP) && match[3].match(NUM_REGEXP) && match[4].match(NUM_REGEXP)) {
ret = [parseFloat(match[1]), parseFloat(match[2]), parseFloat(match[3]), parseFloat(match[4])].join(',')
return {value: 'cubic-bezier(' + ret + ')'}
}
}
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (supported values are: `linear`|`ease`|`ease-in`|`ease-out`|`ease-in-out`|`cubic-bezier(n,n,n,n)`)'
}
}
}
var TRANSFORM_VALIDATOR = function TRANSFORM_VALIDATOR (v) {
// TODO
return { value: v }
}
/**
* generate a function to check whether a value is in `list`
* - first value: default, could be removed
* - not in `list`: error
*
* @param {Array} list
* @return {function} a function(v) which returns a function to return
* - value: string|null
* - reason(k, v, result)
*/
function genEnumValidator(list) {
return function ENUM_VALIDATOR(v) {
var index = list.indexOf(v)
if (index > 0) {
return {value: v}
}
if (index === 0) {
return {
value: v,
reason: function reason(k, v, result) {
return 'NOTE: property value `' + v + '` is the DEFAULT value for `' + util.camelCaseToHyphened(k) + '` (could be removed)'
}
}
}
else {
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (supported values are: `' + list.join('`|`') + '`)'
}
}
}
}
}
function FLEW_WRAP_VALIDATOR (v) {
var list = ['nowrap', 'wrap', 'wrap-reverse']
var index = list.indexOf(v)
if (index > 0) {
return {
value: v,
reason: function reason(k, v, result) {
return 'NOTE: the ' + util.camelCaseToHyphened(k) + ' property may have compatibility problem on native'
}
}
}
if (index === 0) {
return {
value: v,
reason: function reason(k, v, result) {
return 'NOTE: property value `' + v + '` is the DEFAULT value for `' + util.camelCaseToHyphened(k) + '` (could be removed)'
}
}
}
else {
return {
value: null,
reason: function reason(k, v, result) {
return 'ERROR: property value `' + v + '` is not supported for `' + util.camelCaseToHyphened(k) + '` (supported values are: `' + list.join('`|`') + '`)'
}
}
}
}
var PROP_NAME_GROUPS = {
boxModel: {
display: genEnumValidator(['flex']),
width: LENGTH_VALIDATOR,
height: LENGTH_VALIDATOR,
overflow: genEnumValidator(['hidden']),
padding: SHORTHAND_LENGTH_VALIDATOR,
paddingLeft: LENGTH_VALIDATOR,
paddingRight: LENGTH_VALIDATOR,
paddingTop: LENGTH_VALIDATOR,
paddingBottom: LENGTH_VALIDATOR,
margin: SHORTHAND_LENGTH_VALIDATOR,
marginLeft: LENGTH_VALIDATOR,
marginRight: LENGTH_VALIDATOR,
marginTop: LENGTH_VALIDATOR,
marginBottom: LENGTH_VALIDATOR,
borderWidth: LENGTH_VALIDATOR,
borderLeftWidth: LENGTH_VALIDATOR,
borderTopWidth: LENGTH_VALIDATOR,
borderRightWidth: LENGTH_VALIDATOR,
borderBottomWidth: LENGTH_VALIDATOR,
borderColor: COLOR_VALIDATOR,
borderLeftColor: COLOR_VALIDATOR,
borderTopColor: COLOR_VALIDATOR,
borderRightColor: COLOR_VALIDATOR,
borderBottomColor: COLOR_VALIDATOR,
borderStyle: genEnumValidator(['dotted', 'dashed', 'solid']),
borderTopStyle: genEnumValidator(['dotted', 'dashed', 'solid']),
borderRightStyle: genEnumValidator(['dotted', 'dashed', 'solid']),
borderBottomStyle: genEnumValidator(['dotted', 'dashed', 'solid']),
borderLeftStyle: genEnumValidator(['dotted', 'dashed', 'solid']),
borderRadius: LENGTH_VALIDATOR,
borderBottomLeftRadius: LENGTH_VALIDATOR,
borderBottomRightRadius: LENGTH_VALIDATOR,
borderTopLeftRadius: LENGTH_VALIDATOR,
borderTopRightRadius: LENGTH_VALIDATOR
},
flexbox: {
flex: NUMBER_VALIDATOR,
flexWrap: FLEW_WRAP_VALIDATOR,
flexDirection: genEnumValidator(['column', 'row', 'column-reverse', 'row-reverse']),
justifyContent: genEnumValidator(['flex-start', 'flex-end', 'center', 'space-between','space-around']),
alignItems: genEnumValidator(['stretch', 'flex-start', 'flex-end', 'center'])
},
position: {
position: genEnumValidator(['relative', 'absolute', 'sticky', 'fixed']),
top: LENGTH_VALIDATOR,
bottom: LENGTH_VALIDATOR,
left: LENGTH_VALIDATOR,
right: LENGTH_VALIDATOR,
zIndex: INTEGER_VALIDATOR
},
common: {
opacity: NUMBER_VALIDATOR,
boxShadow: ANYTHING_VALIDATOR,
backgroundColor: COLOR_VALIDATOR,
backgroundImage: ANYTHING_VALIDATOR
},
text: {
lines: INTEGER_VALIDATOR,
color: COLOR_VALIDATOR,
fontSize: LENGTH_VALIDATOR,
fontStyle: genEnumValidator(['normal', 'italic']),
fontFamily: ANYTHING_VALIDATOR,
fontWeight: genEnumValidator(['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900']),
textDecoration: genEnumValidator(['none', 'underline', 'line-through']),
textAlign: genEnumValidator(['left', 'center', 'right']),
textOverflow: genEnumValidator(['clip', 'ellipsis', 'unset', 'fade']),
lineHeight: LENGTH_VALIDATOR
},
transition: {
transitionProperty: TRANSITION_PROPERTY_VALIDATOR,
transitionDuration: TRANSITION_INTERVAL_VALIDATOR,
transitionDelay: TRANSITION_INTERVAL_VALIDATOR,
transitionTimingFunction: TRANSITION_TIMING_FUNCTION_VALIDATOR
},
transform: {
transform: TRANSFORM_VALIDATOR,
transformOrigin: TRANSFORM_VALIDATOR,// fixed by xxxxxx
},
customized: {
itemSize: LENGTH_VALIDATOR,
itemColor: COLOR_VALIDATOR,
itemSelectedColor: COLOR_VALIDATOR,
textColor: COLOR_VALIDATOR,
timeColor: COLOR_VALIDATOR,
textHighlightColor: COLOR_VALIDATOR
}
}
var SUGGESTED_PROP_NAME_GROUP = {
background: 'backgroundColor'
}
var validatorMap = {}
/**
* flatten `PROP_NAME_GROUPS` to `validatorMap`
*/
function genValidatorMap() {
var groupName, group, name
for (groupName in PROP_NAME_GROUPS) {
group = PROP_NAME_GROUPS[groupName]
for (name in group) {
validatorMap[name] = group[name]
}
}
}
genValidatorMap()
/**
* validate a CSS name/value pair
*
* @param {string} name camel cased
* @param {string} value
* @return {object}
* - value:string or null
* - log:{reason:string} or undefined
*/
function validate(name, value) {
var result, log
var validator = validatorMap[name]
if (typeof validator === 'function') {
if (typeof value !== 'function') {
result = validator(value)
}
/* istanbul ignore else */
else {
result = {value: value}
}
if (result.reason) {
log = {reason: result.reason(name, value, result.value)}
}
}
else {
// ensure number type, no `px`
/* istanbul ignore else */
if (typeof value !== 'function') {
var match = value.match(LENGTH_REGEXP)
if (match && (!match[1] || SUPPORT_CSS_UNIT.indexOf(match[1]) === -1)) {
value = parseFloat(value)
}
}
result = {value: value}
var suggestedName = SUGGESTED_PROP_NAME_GROUP[name]
var suggested = suggestedName ? ', suggest `' + util.camelCaseToHyphened(suggestedName) + '`' : ''
log = {reason: 'WARNING: `' + util.camelCaseToHyphened(name) + '` is not a standard property name (may not be supported)' + suggested}
}
return {
value: result.value,
log: log
}
}
module.exports = {
BASIC_COLOR_KEYWORDS: BASIC_COLOR_KEYWORDS,
EXTENDED_COLOR_KEYWORDS: EXTENDED_COLOR_KEYWORDS,
LENGTH_VALIDATOR: LENGTH_VALIDATOR,
COLOR_VALIDATOR: COLOR_VALIDATOR,
NUMBER_VALIDATOR: NUMBER_VALIDATOR,
INTEGER_VALIDATOR: INTEGER_VALIDATOR,
genEnumValidator: genEnumValidator,
TRANSITION_PROPERTY_VALIDATOR: TRANSITION_PROPERTY_VALIDATOR,
TRANSITION_DURATION_VALIDATOR: TRANSITION_INTERVAL_VALIDATOR,
TRANSITION_DELAY_VALIDATOR: TRANSITION_INTERVAL_VALIDATOR,
TRANSITION_TIMING_FUNCTION_VALIDATOR: TRANSITION_TIMING_FUNCTION_VALIDATOR,
PROP_NAME_GROUPS: PROP_NAME_GROUPS,
map: validatorMap,
validate: validate
}
@@ -0,0 +1,67 @@
{
"_args": [
[
"weex-styler@0.3.1",
"/Users/fxy/Documents/DCloud/HBuilderX/uniapp-cli"
]
],
"_development": true,
"_from": "weex-styler@0.3.1",
"_id": "weex-styler@0.3.1",
"_inBundle": false,
"_integrity": "sha512-xkX5/wS/QLiJXKwbdpeytbLN0kHviQwj9CLdvBxqu+RRZABZpTniKZr1oxjh9Q0+n/aRC+smwFpQpUKvXh9V1g==",
"_location": "/weex-styler",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "weex-styler@0.3.1",
"name": "weex-styler",
"escapedName": "weex-styler",
"rawSpec": "0.3.1",
"saveSpec": null,
"fetchSpec": "0.3.1"
},
"_requiredBy": [
"/weex-vue-loader"
],
"_resolved": "https://registry.npmjs.org/weex-styler/-/weex-styler-0.3.1.tgz",
"_spec": "0.3.1",
"_where": "/Users/fxy/Documents/DCloud/HBuilderX/uniapp-cli",
"author": {
"name": "songsiqi",
"email": "songsiqi2006@126.com"
},
"bugs": {
"url": "https://github.com/weexteam/weex-styler/issues"
},
"dependencies": {
"css": "~2.2.1"
},
"description": "Weex <style> transformer",
"devDependencies": {
"chai": "~3.4.1",
"gulp": "~3.9.0",
"gulp-jscs": "~3.0.2",
"gulp-mocha": "~2.2.0",
"isparta": "~4.0.0",
"sinon": "~1.17.2",
"sinon-chai": "~2.8.0"
},
"homepage": "https://github.com/weexteam/weex-styler#readme",
"keywords": [
"weex"
],
"license": "MIT",
"main": "index.js",
"name": "weex-styler",
"repository": {
"type": "git",
"url": "git+https://github.com/weexteam/weex-styler.git"
},
"scripts": {
"cover": "node node_modules/isparta/bin/isparta cover node_modules/gulp-mocha/node_modules/.bin/_mocha -- --reporter dot",
"test": "gulp test && npm run cover"
},
"version": "0.3.1"
}
@@ -0,0 +1,289 @@
var chai = require('chai')
var sinon = require('sinon')
var sinonChai = require('sinon-chai')
var expect = chai.expect
chai.use(sinonChai)
var styler = require('../')
describe('parse', function () {
it('parse normal style code', function (done) {
var code = 'html {color: #000000;}\n\n.foo {color: red; background-color: rgba(255,255,255,0.6); -webkit-transform: rotate(90deg); width: 200px; left: 0; right: 0px; border-width: 1pt; font-weight: 100}\n\n.bar {background: red}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({foo: {color: '#FF0000', backgroundColor: 'rgba(255,255,255,0.6)', WebkitTransform: 'rotate(90deg)', width: '200px', left: 0, right: '0px', borderWidth: '1pt', fontWeight: '100'}, bar: {background: 'red'}})
expect(data.log).eql([
{line: 1, column: 1, reason: 'ERROR: Selector `html` is not supported. Weex only support single-classname selector'},
{line: 3, column: 7, reason: 'NOTE: property value `red` is autofixed to `#FF0000`'},
{line: 3, column: 60, reason: 'WARNING: `-webkit-transform` is not a standard property name (may not be supported)'},
{line: 5, column: 7, reason: 'WARNING: `background` is not a standard property name (may not be supported), suggest `background-color`'}
])
done()
})
})
it('parse and fix prop value', function (done) {
var code = '.foo {font-size: 200px;}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({foo: {fontSize: '200px'}})
done()
})
})
it('parse and ensure number type value', function (done) {
var code = '.foo {line-height: 40;}\n\n .bar {line-height: 20px;}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({foo: {lineHeight: 40}, bar: {lineHeight: '20px'}})
done()
})
})
it('handle complex class definition', function (done) {
var code = '.foo, .bar {font-size: 20;}\n\n .foo {color: #ff5000;}\n\n .bar {color: #000000;}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
foo: {fontSize: 20, color: '#ff5000'},
bar: {fontSize: 20, color: '#000000'}
})
done()
})
})
it('handle more complex class definition', function (done) {
var code = '.foo, .bar {font-size: 20; color: #000000}\n\n .foo, .bar, .baz {color: #ff5000; height: 30;}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
foo: {fontSize: 20, color: '#ff5000', height: 30},
bar: {fontSize: 20, color: '#ff5000', height: 30},
baz: {color: '#ff5000', height: 30}
})
done()
})
})
it('parse transition', function (done) {
var code = '.foo {transition-property: margin-top; transition-duration: 300ms; transition-delay: 0.2s; transition-timing-function: ease-in;}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle['@TRANSITION']).eql({foo: {property: 'marginTop', duration: 300, delay: 200, timingFunction: 'ease-in'}})
expect(data.jsonStyle.foo).eql({
transitionDelay: 200,
transitionDuration: 300,
transitionProperty: "marginTop",
transitionTimingFunction: "ease-in"
})
expect(data.log).eql([
{line: 1, column: 40, reason: 'NOTE: property value `300ms` is autofixed to `300`'},
{line: 1, column: 68, reason: 'NOTE: property value `0.2s` is autofixed to `200`'}
])
done()
})
})
it('parse transition transform', function (done) {
var code = '.foo {transition-property: transform; transition-duration: 300ms; transition-delay: 0.2s; transition-timing-function: ease-in-out;}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle['@TRANSITION']).eql({foo: {property: 'transform', duration: 300, delay: 200, timingFunction: 'ease-in-out'}})
expect(data.jsonStyle.foo).eql({
transitionDelay: 200,
transitionDuration: 300,
transitionProperty: "transform",
transitionTimingFunction: "ease-in-out"
})
done()
})
})
it('parse multi transition properties', function (done) {
var code = '.foo {transition-property: margin-top, height; transition-duration: 300ms; transition-delay: 0.2s; transition-timing-function: ease-in-out;}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle['@TRANSITION']).eql({foo: {property: 'marginTop,height', duration: 300, delay: 200, timingFunction: 'ease-in-out'}})
expect(data.jsonStyle.foo).eql({
transitionDelay: 200,
transitionDuration: 300,
transitionProperty: "marginTop,height",
transitionTimingFunction: "ease-in-out"
})
done()
})
})
it('parse complex transition', function (done) {
var code = '.foo {font-size: 20; color: #000000}\n\n .foo, .bar {color: #ff5000; height: 30; transition-property: margin-top; transition-duration: 300ms; transition-delay: 0.2s; transition-timing-function: ease-in;}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle['@TRANSITION']).eql({
foo: {property: 'marginTop', duration: 300, delay: 200, timingFunction: 'ease-in'},
bar: {property: 'marginTop', duration: 300, delay: 200, timingFunction: 'ease-in'}
})
expect(data.jsonStyle.foo).eql({
fontSize: 20, color: '#ff5000', height: 30,
transitionDelay: 200,
transitionDuration: 300,
transitionProperty: "marginTop",
transitionTimingFunction: "ease-in"
})
expect(data.jsonStyle.bar).eql({
color: '#ff5000', height: 30,
transitionDelay: 200,
transitionDuration: 300,
transitionProperty: "marginTop",
transitionTimingFunction: "ease-in"
})
expect(data.log).eql([
{line: 3, column: 75, reason: 'NOTE: property value `300ms` is autofixed to `300`'},
{line: 3, column: 103, reason: 'NOTE: property value `0.2s` is autofixed to `200`'}
])
done()
})
})
it('parse transition shorthand', function (done) {
var code = '.foo {font-size: 20; transition: margin-top 500ms ease-in-out 1s}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle['@TRANSITION']).eql({foo: {property: 'marginTop', duration: 500, delay: 1000, timingFunction: 'ease-in-out' }})
expect(data.jsonStyle.foo).eql({
fontSize: 20,
transitionDelay: 1000,
transitionDuration: 500,
transitionProperty: "marginTop",
transitionTimingFunction: "ease-in-out"
})
expect(data.log).eql([
{line: 1, column: 22, reason: 'NOTE: property value `500ms` is autofixed to `500`'},
{line: 1, column: 22, reason: 'NOTE: property value `1s` is autofixed to `1000`'}
])
done()
})
})
it.skip('override transition shorthand', function (done) {
var code = '.foo {font-size: 32px; transition: margin-top 500ms ease-in-out 1s; transition-duration: 300ms}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle['@TRANSITION']).eql({foo: {property: 'marginTop', duration: 300, delay: 1000, timingFunction: 'ease-in-out' }})
expect(data.jsonStyle.foo).eql({
fontSize: 32,
transitionDelay: 1000,
transitionDuration: 300,
transitionProperty: "marginTop",
transitionTimingFunction: "ease-in-out"
})
done()
})
})
it('parse padding & margin shorthand', function (done) {
var code = '.foo { padding: 20px; margin: 30px 40; } .bar { margin: 10px 20 30; padding: 10 20px 30px 40;}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle.foo).eql({
paddingTop: '20px',
paddingRight: '20px',
paddingBottom: '20px',
paddingLeft: '20px',
marginTop: '30px',
marginRight: 40,
marginBottom: '30px',
marginLeft: 40
})
expect(data.jsonStyle.bar).eql({
paddingTop: 10,
paddingRight: '20px',
paddingBottom: '30px',
paddingLeft: 40,
marginTop: '10px',
marginRight: 20,
marginBottom: 30,
marginLeft: 20
})
done()
})
})
it('override padding & margin shorthand', function (done) {
var code = '.foo { padding: 20px; padding-left: 30px; } .bar { margin: 10px 20; margin-bottom: 30px;}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle.foo).eql({
paddingTop: '20px',
paddingRight: '20px',
paddingBottom: '20px',
paddingLeft: '30px'
})
expect(data.jsonStyle.bar).eql({
marginTop: '10px',
marginRight: 20,
marginBottom: '30px',
marginLeft: 20
})
done()
})
})
it('handle pseudo class', function (done) {
var code = '.class-a {color: #0000ff;} .class-a:last-child:focus {color: #ff0000;}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
'class-a': {
color: '#0000ff',
'color:last-child:focus': '#ff0000'
}
})
done()
})
})
it('handle iconfont', function (done) {
var code = '@font-face {font-family: "font-family-name-1"; src: url("font file url 1-1") format("truetype");} @font-face {font-family: "font-family-name-2"; src: url("font file url 2-1") format("truetype"), url("font file url 2-2") format("woff");}'
styler.parse(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
'@FONT-FACE': [
{fontFamily: 'font-family-name-1', src: 'url("font file url 1-1") format("truetype")'},
{fontFamily: 'font-family-name-2', src: 'url("font file url 2-1") format("truetype"), url("font file url 2-2") format("woff")'}
]
})
done()
})
})
it('handle syntax error', function (done) {
var code = 'asdf'
styler.parse(code, function (err, data) {
expect(err).is.an.array
expect(err[0].toString()).eql('Error: undefined:1:5: missing \'{\'')
expect(err[0].reason).eql('missing \'{\'')
expect(err[0].filename).eql(undefined)
expect(err[0].line).eql(1)
expect(err[0].column).eql(5)
expect(err[0].source).eql('')
expect(data.log).eql([{line: 1, column: 5, reason: 'ERROR: undefined:1:5: missing \'{\''}])
done()
})
})
})
@@ -0,0 +1,238 @@
var chai = require('chai')
var sinon = require('sinon')
var sinonChai = require('sinon-chai')
var expect = chai.expect
chai.use(sinonChai)
var shorthandParser = require('../lib/shorthand-parser')
describe('shorthand-parser', function () {
it('parse transition', function () {
var declarations = [
{
type: 'declaration',
property: 'transition',
value: 'margin-top 500ms ease-in-out 1s',
position: {}
}
]
var result = shorthandParser(declarations)
expect(result).eql([
{
type: 'declaration',
property: 'transition-property',
value: 'margin-top',
position: {}
},
{
type: 'declaration',
property: 'transition-duration',
value: '500ms',
position: {}
},
{
type: 'declaration',
property: 'transition-timing-function',
value: 'ease-in-out',
position: {}
},
{
type: 'declaration',
property: 'transition-delay',
value: '1s',
position: {}
}
])
expect(shorthandParser([{
type: 'declaration',
property: 'transition',
value: 'width 2s ease-in-out, height 1s 1s, top cubic-bezier(0.1, 0.7, 1.0, 0.1)',
position: {}
}])).eql([{
type: 'declaration',
property: 'transition-property',
value: 'width, height, top',
position: {}
},
{
type: 'declaration',
property: 'transition-duration',
value: '2s, 1s, 0s',
position: {}
},
{
type: 'declaration',
property: 'transition-timing-function',
value: 'ease-in-out, ease, cubic-bezier(0.1, 0.7, 1.0, 0.1)',
position: {}
},
{
type: 'declaration',
property: 'transition-delay',
value: '0s, 1s, 0s',
position: {}
}])
expect(shorthandParser([{
type: 'declaration',
property: 'transition',
value: 'width 2s, height 2s',
position: {}
}])).eql([{
type: 'declaration',
property: 'transition-property',
value: 'width, height',
position: {}
},
{
type: 'declaration',
property: 'transition-duration',
value: '2s',
position: {}
},
{
type: 'declaration',
property: 'transition-timing-function',
value: 'ease',
position: {}
},
{
type: 'declaration',
property: 'transition-delay',
value: '0s',
position: {}
}])
})
it('parse margin', function () {
var declarations = [
{
type: 'declaration',
property: 'margin',
value: '1px',
position: {}
},
{
type: 'declaration',
property: 'margin',
value: '21px 22px',
position: {}
},
{
type: 'declaration',
property: 'margin',
value: '31px 32px 33px',
position: {}
},
{
type: 'declaration',
property: 'margin',
value: '41px 42px 43px 44px',
position: {}
}
]
var result = shorthandParser(declarations)
expect(result).eql([
{
type: 'declaration',
property: 'margin-top',
value: '1px',
position: {}
},
{
type: 'declaration',
property: 'margin-right',
value: '1px',
position: {}
},
{
type: 'declaration',
property: 'margin-bottom',
value: '1px',
position: {}
},
{
type: 'declaration',
property: 'margin-left',
value: '1px',
position: {}
},
{
type: 'declaration',
property: 'margin-top',
value: '21px',
position: {}
},
{
type: 'declaration',
property: 'margin-right',
value: '22px',
position: {}
},
{
type: 'declaration',
property: 'margin-bottom',
value: '21px',
position: {}
},
{
type: 'declaration',
property: 'margin-left',
value: '22px',
position: {}
},
{
type: 'declaration',
property: 'margin-top',
value: '31px',
position: {}
},
{
type: 'declaration',
property: 'margin-right',
value: '32px',
position: {}
},
{
type: 'declaration',
property: 'margin-bottom',
value: '33px',
position: {}
},
{
type: 'declaration',
property: 'margin-left',
value: '32px',
position: {}
},
{
type: 'declaration',
property: 'margin-top',
value: '41px',
position: {}
},
{
type: 'declaration',
property: 'margin-right',
value: '42px',
position: {}
},
{
type: 'declaration',
property: 'margin-bottom',
value: '43px',
position: {}
},
{
type: 'declaration',
property: 'margin-left',
value: '44px',
position: {}
}
])
})
})
@@ -0,0 +1,445 @@
var chai = require('chai')
var sinon = require('sinon')
var sinonChai = require('sinon-chai')
var expect = chai.expect
chai.use(sinonChai)
var styler = require('../')
describe('validate', function () {
it('parse normal style code', function (done) {
var code = {
foo: {
color: '#FF0000',
width: '200',
position: 'sticky',
zIndex: 4
}
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({foo: {color: '#FF0000', width: 200, position: 'sticky', zIndex: 4}})
expect(data.log).eql([])
done()
})
})
it('parse length', function (done) {
var code = {
foo: {
width: '200px',
paddingLeft: '300',
borderWidth: '1pt',
left: '0',
right: '0px',
marginRight: 'asdf'
}
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({foo: {
width: '200px',
paddingLeft: 300,
borderWidth: '1pt',
left: 0,
right: '0px'
}})
expect(data.log).eql([
{reason: 'ERROR: property value `asdf` is not supported for `margin-right` (only number and pixel values are supported)'}
])
done()
})
})
it('parse number', function (done) {
var code = {
foo: {
opacity: '1'
},
bar: {
opacity: '0.5'
},
baz: {
opacity: 'a'
},
boo: {
opacity: '0.5a'
},
zero: {
opacity: '0'
}
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
foo: {
opacity: 1
},
bar: {
opacity: 0.5
},
baz: {},
boo: {},
zero: {
opacity: 0
}
})
expect(data.log).eql([
{reason: 'ERROR: property value `a` is not supported for `opacity` (only number is supported)'},
{reason: 'ERROR: property value `0.5a` is not supported for `opacity` (only number is supported)'}
])
done()
})
})
it('parse integer', function (done) {
var code = {
foo: {
zIndex: '1'
},
bar: {
zIndex: '0.5'
},
baz: {
zIndex: 'a'
},
boo: {
zIndex: '0.5a'
},
zero: {
zIndex: '0'
}
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
foo: {
zIndex: 1
},
bar: {},
baz: {},
boo: {},
zero: {
zIndex: 0
}
})
expect(data.log).eql([
{reason: 'ERROR: property value `0.5` is not supported for `z-index` (only integer is supported)'},
{reason: 'ERROR: property value `a` is not supported for `z-index` (only integer is supported)'},
{reason: 'ERROR: property value `0.5a` is not supported for `z-index` (only integer is supported)'}
])
done()
})
})
it('parse color', function (done) {
var code = {
foo: {
color: '#FF0000',
backgroundColor: '#ff0000'
},
bar: {
color: '#F00',
backgroundColor: '#f00'
},
baz: {
color: 'red',
backgroundColor: 'lightpink'
},
rgba: {
color: 'rgb(23, 0, 255)',
backgroundColor: 'rgba(234, 45, 99, .4)'
},
transparent: {
color: 'transparent',
backgroundColor: 'asdf'
},
errRgba: {
color: 'rgb(266,0,255)',
backgroundColor: 'rgba(234,45,99,1.3)'
}
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
foo: {
color: '#FF0000',
backgroundColor: '#ff0000'
},
bar: {
color: '#FF0000',
backgroundColor: '#ff0000'
},
baz: {
color: '#FF0000',
backgroundColor: '#FFB6C1'
},
rgba: {
color: 'rgb(23,0,255)',
backgroundColor: 'rgba(234,45,99,0.4)'
},
transparent: {
color: 'rgba(0,0,0,0)'
},
errRgba: {}
})
expect(data.log).eql([
{reason: 'NOTE: property value `#F00` is autofixed to `#FF0000`'},
{reason: 'NOTE: property value `#f00` is autofixed to `#ff0000`'},
{reason: 'NOTE: property value `red` is autofixed to `#FF0000`'},
{reason: 'NOTE: property value `lightpink` is autofixed to `#FFB6C1`'},
{reason: 'ERROR: property value `asdf` is not valid for `background-color`'},
{reason: 'ERROR: property value `rgb(266,0,255)` is not valid for `color`'},
{reason: 'ERROR: property value `rgba(234,45,99,1.3)` is not valid for `background-color`'}
])
done()
})
})
it('parse color', function (done) {
var code = {
foo: {
color: '#FF0000',
backgroundColor: '#ff0000'
},
bar: {
color: '#F00',
backgroundColor: '#f00'
},
baz: {
color: 'red',
backgroundColor: 'lightpink'
},
rgba: {
color: 'rgb(23, 0, 255)',
backgroundColor: 'rgba(234, 45, 99, .4)'
},
transparent: {
color: 'transparent',
backgroundColor: 'asdf'
},
errRgba: {
color: 'rgb(266,0,255)',
backgroundColor: 'rgba(234,45,99,1.3)'
}
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
foo: {
color: '#FF0000',
backgroundColor: '#ff0000'
},
bar: {
color: '#FF0000',
backgroundColor: '#ff0000'
},
baz: {
color: '#FF0000',
backgroundColor: '#FFB6C1'
},
rgba: {
color: 'rgb(23,0,255)',
backgroundColor: 'rgba(234,45,99,0.4)'
},
transparent: {
color: 'rgba(0,0,0,0)'
},
errRgba: {}
})
expect(data.log).eql([
{reason: 'NOTE: property value `#F00` is autofixed to `#FF0000`'},
{reason: 'NOTE: property value `#f00` is autofixed to `#ff0000`'},
{reason: 'NOTE: property value `red` is autofixed to `#FF0000`'},
{reason: 'NOTE: property value `lightpink` is autofixed to `#FFB6C1`'},
{reason: 'ERROR: property value `asdf` is not valid for `background-color`'},
{reason: 'ERROR: property value `rgb(266,0,255)` is not valid for `color`'},
{reason: 'ERROR: property value `rgba(234,45,99,1.3)` is not valid for `background-color`'}
])
done()
})
})
it('parse flex-wrap', function (done) {
var code = {
foo: { flexWrap: 'nowrap' },
bar: { flexWrap: 'wrap' }
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
foo: { flexWrap: 'nowrap' },
bar: { flexWrap: 'wrap' }
})
expect(data.log).eql([
{reason: 'NOTE: property value `nowrap` is the DEFAULT value for `flex-wrap` (could be removed)'},
{reason: 'NOTE: the flex-wrap property may have compatibility problem on native'},
])
done()
})
})
it('parse transition-property', function (done) {
var code = {
foo: {
transitionProperty: 'margin-top'
},
bar: {
transitionProperty: 'height'
},
foobar: {
transitionProperty: 'margin-top, height'
},
baz: {
transitionProperty: 'abc'
}
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
foo: {
transitionProperty: 'marginTop'
},
bar: {
transitionProperty: 'height'
},
foobar: {
transitionProperty: 'marginTop,height'
},
baz: {}
})
expect(data.log).eql([
{reason: 'ERROR: property value `abc` is not supported for `transition-property` (only css property is valid)'}
])
done()
})
})
it('parse transition-duration & transition-delay', function (done) {
var code = {
foo: {
transitionDuration: '200ms',
transitionDelay: '0.5s'
},
bar: {
transitionDuration: '200',
transitionDelay: 'abc'
}
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
foo: {
transitionDuration: 200,
transitionDelay: 500
},
bar: {
transitionDuration: 200
}
})
expect(data.log).eql([
{reason: 'NOTE: property value `200ms` is autofixed to `200`'},
{reason: 'NOTE: property value `0.5s` is autofixed to `500`'},
{reason: 'ERROR: property value `abc` is not supported for `transition-delay` (only number of seconds and milliseconds is valid)'}
])
done()
})
})
it('parse transition-timing-function', function (done) {
var code = {
foo: {
transitionTimingFunction: 'ease-in-out'
},
bar: {
transitionTimingFunction: 'cubic-bezier(.88, 1.0, -0.67, 1.37)'
},
baz: {
transitionTimingFunction: 'abc'
}
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
foo: {
transitionTimingFunction: 'ease-in-out'
},
bar: {
transitionTimingFunction: 'cubic-bezier(0.88,1,-0.67,1.37)'
},
baz: {}
})
expect(data.log).eql([
{reason: 'ERROR: property value `abc` is not supported for `transition-timing-function` (supported values are: `linear`|`ease`|`ease-in`|`ease-out`|`ease-in-out`|`cubic-bezier(n,n,n,n)`)'}
])
done()
})
})
it('parse unknown', function (done) {
var code = {
foo: {
background: '#ff0000',
abc: '123',
def: '456px',
ghi: '789pt',
AbcDef: '456',
abcDef: 'abc'
}
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({
foo: {
background: '#ff0000',
abc: 123,
def: '456px',
ghi: '789pt',
AbcDef: 456,
abcDef: 'abc'
}
})
expect(data.log).eql([
{reason: 'WARNING: `background` is not a standard property name (may not be supported), suggest `background-color`'},
{reason: 'WARNING: `abc` is not a standard property name (may not be supported)'},
{reason: 'WARNING: `def` is not a standard property name (may not be supported)'},
{reason: 'WARNING: `ghi` is not a standard property name (may not be supported)'},
{reason: 'WARNING: `-abc-def` is not a standard property name (may not be supported)'},
{reason: 'WARNING: `abc-def` is not a standard property name (may not be supported)'}
])
done()
})
})
it('parse complex style code', function (done) {
var code = {
foo: {
color: 'red',
WebkitTransform: 'rotate(90deg)',
width: '200px'
}
}
styler.validate(code, function (err, data) {
expect(err).is.undefined
expect(data).is.an.object
expect(data.jsonStyle).eql({foo: {color: '#FF0000', WebkitTransform: 'rotate(90deg)', width: '200px'}})
expect(data.log).eql([
{reason: 'NOTE: property value `red` is autofixed to `#FF0000`'},
{reason: 'WARNING: `-webkit-transform` is not a standard property name (may not be supported)'}
])
done()
})
})
})
@@ -0,0 +1,3 @@
# weex-template-compiler
> This package is auto-generated. For pull requests please see [src/platforms/weex/entry-compiler.js](https://github.com/vuejs/vue/tree/dev/src/platforms/weex/entry-compiler.js).
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,17 @@
try {
var vueVersion = require('weex-vue-framework').version
} catch (e) {}
var packageName = require('./package.json').name
var packageVersion = require('./package.json').version
if (vueVersion && vueVersion !== packageVersion) {
throw new Error(
'\n\nVue packages version mismatch:\n\n' +
'- vue@' + vueVersion + '\n' +
'- ' + packageName + '@' + packageVersion + '\n\n' +
'This may cause things to work incorrectly. Make sure to use the same version for both.\n' +
'If you are using weex-vue-loader, re-installing them should bump ' + packageName + ' to the latest.\n'
)
}
module.exports = require('./build')
@@ -0,0 +1,25 @@
{
"name": "weex-template-compiler",
"version": "2.6.10-weex.1",
"description": "Weex template compiler for Vue 2.0",
"main": "index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/vue.git"
},
"keywords": [
"vue",
"compiler"
],
"author": "Evan You",
"license": "MIT",
"bugs": {
"url": "https://github.com/vuejs/vue/issues"
},
"homepage": "https://github.com/vuejs/vue/tree/dev/packages/weex-template-compiler#readme",
"dependencies": {
"acorn": "^5.2.1",
"escodegen": "^1.8.1",
"he": "^1.1.0"
}
}