未验证 提交 08cbbf7f 编写于 作者: B beatles-chameleon 提交者: GitHub

Merge pull request #155 from didi/0.4.x-dev

0.4.x dev
......@@ -15,6 +15,7 @@
"dependencies": {
"babel-core": "^6.26.3",
"babel-istanbul": "^0.12.2",
"chai": "^4.2.0",
"codecov": "^3.1.0",
"coveralls": "^3.0.2",
"mocha": "*",
......
const _ = module.exports = {};
const path = require('path');
const cmlUtils = require('chameleon-tool-utils');
const fse = require('fs-extra');
_.handleApptabbar = function(newJsonObj, filePath, type) {
let tabbarIconPaths = _.getTabbarIconPaths(newJsonObj.tabBar, type);
if (tabbarIconPaths.length) {
tabbarIconPaths.forEach((item) => {
let rootDir = path.resolve(cml.projectRoot, `dist/${type}`);
let destIconPath = path.resolve(rootDir, item.finalPath); // 获取到要将icon拷贝的路径
let sourceIconPath = path.resolve(filePath, item.originPath) // 获取到原来的icon的路径
if (cmlUtils.isFile(sourceIconPath)) {
fse.copySync(sourceIconPath, destIconPath)
} else {
cmlUtils.log.warn(`${sourceIconPath} is not exsit`)
}
});
}
}
_.getRelativeIconPath = function(p) {
let fileName = path.parse(p).base;
return path.join('./icon', fileName)
}
_.getTabbarIconPaths = function(tabbar, type) {
let iconPaths = [];
if (tabbar && (type === 'baidu' || type === 'wx')) {
(tabbar.list || []).forEach((item) => {
if (item.iconPath) {
let iconInfo = {};
iconInfo.originPath = item.iconPath;
item.iconPath = _.getRelativeIconPath(item.iconPath);
iconInfo.finalPath = item.iconPath;
iconPaths.push(iconInfo);
}
if (item.selectedIconPath) {
let iconInfo = {};
iconInfo.originPath = item.selectedIconPath;
item.selectedIconPath = _.getRelativeIconPath(item.selectedIconPath);
iconInfo.finalPath = item.selectedIconPath;
iconPaths.push(iconInfo);
}
})
}
if (tabbar && type === 'alipay') {
(tabbar.items || []).forEach((item) => {
if (item.icon) {
let iconInfo = {};
iconInfo.originPath = item.icon;
item.icon = _.getRelativeIconPath(item.icon);
iconInfo.finalPath = item.icon;
iconPaths.push(iconInfo);
}
if (item.activeIcon) {
let iconInfo = {};
iconInfo.originPath = item.activeIcon;
item.activeIcon = _.getRelativeIconPath(item.activeIcon);
iconInfo.finalPath = item.activeIcon;
iconPaths.push(iconInfo);
}
})
}
return iconPaths;
}
......@@ -17,6 +17,7 @@ const cmlUtils = require('chameleon-tool-utils');
const prehandle = require('./utils/prehandle.js');
const loaderMethods = require('./loaderMethods');
const miniAppScript = require('./miniapp-script.js');
const loadIcon = require('./load-icon.js');
let jsonObject = {};
module.exports = function (content) {
......@@ -271,7 +272,7 @@ module.exports = function (content) {
});
//处理tabbar中配置的icon路径
if(type == 'app'){
miniAppScript.handleApptabbar(newJsonObj,filePath,cmlType)
loadIcon.handleApptabbar(newJsonObj,filePath,cmlType)
}
let jsonResult = JSON.stringify(newJsonObj, '', 4);
self.emitFile(emitJsonPath, jsonResult);
......
const miniAppScript = require('../../src/miniapp-script.js');
const loadIcon = require('../../src/load-icon.js');
const expect = require('chai').expect;
const path = require('path');
describe('miniapp-script', function() {
let result = miniAppScript.getRelativeIconPath('./dir/chameleon.png')
describe('load-icon', function() {
it('handleApptabbar', function() {
let newJsonObj = {
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index/index",
"text": "组件",
"iconPath": "../../assets/images/chameleon.png",
"selectedIconPath": "../../assets/images/icon_API.png"
},
{
"pagePath": "pages/index/index2",
"text": "接口"
}
]
}
}
let filePath = path.resolve(__dirname);
let result = loadIcon.handleApptabbar(newJsonObj, filePath, 'wx');
expect(result).to.not.be.ok;
})
it('getRelativeIconPath', function() {
let result = loadIcon.getRelativeIconPath('./dir/chameleon.png');
expect(result).to.equal('icon/chameleon.png')
});
it('getTabbarIconPaths-baidu', function() {
......@@ -26,7 +52,7 @@ describe('miniapp-script', function() {
}
]
}
let result = miniAppScript.getTabbarIconPaths(tabbar, 'baidu')
let result = loadIcon.getTabbarIconPaths(tabbar, 'baidu')
expect(result).to.be.an('array')
});
it('getTabbarIconPaths-wx', function() {
......@@ -48,7 +74,7 @@ describe('miniapp-script', function() {
}
]
}
let result = miniAppScript.getTabbarIconPaths(tabbar, 'wx')
let result = loadIcon.getTabbarIconPaths(tabbar, 'wx')
expect(result).to.be.an('array')
});
it('getTabbarIconPaths-baidu', function() {
......@@ -70,7 +96,7 @@ describe('miniapp-script', function() {
}
]
}
let result = miniAppScript.getTabbarIconPaths(tabbar, 'alipay')
let result = loadIcon.getTabbarIconPaths(tabbar, 'alipay')
expect(result).to.be.an('array')
});
......
const commonMixins = require('./wx-alipay-common-mixins.js');
var _ = module.exports = commonMixins.deepClone(commonMixins);
const utils = require('./utils.js');
commonMixins.merge(_.mixins.methods, {
[_.eventEmitName]: function(eventKey, detail) {
let dataset = {};
......@@ -22,6 +22,8 @@ commonMixins.merge(_.mixins.methods, {
return match.toUpperCase();
})
}
// 这里对于用户自定义事件,会将首字母大写,但是对于原生事件 touchstart 仅仅大写是不够的,还需要将 touchstart ==> TouchStart
eventKey = utils.handleCompEventType(eventKey);
let callback = this.props['on' + titleLize(eventKey)];
if (callback && _.isType(callback, 'Function')) {
callback({
......
......@@ -3,7 +3,7 @@ const _ = module.exports = {};
const utils = require('./utils.js')
_.eventProxyName = '_cmlEventProxy';
_.modelEventProxyName = '_cmlModelEventProxy';// c-model v-model的事件代理
_.inlineStatementEventProxy = '_cmlInlineStatementEventProxy';// 内联语句的事件代理
_.inlineStatementEventProxy = '_cmlInline';// 内联语句的事件代理
_.eventEmitName = '$cmlEmit'; // 触发事件的方法
_.styleParseName = '$cmlStyle'; // 提供各端处理style属性的方法 weex中处理成对象,wx中处理成字符串,web中不处理
_.styleProxyName = '_cmlStyleProxy'; // 提供代理 weex和web端处理style
......
......@@ -7,5 +7,17 @@ describe('utils.js', function() {
let result = utils.getStyleKeyValue(source);
expect(result).to.include.keys('key');
expect(result).to.include.keys('value');
})
});
it('test handleEventType', function() {
expect(utils.handleEventType('touchStart')).to.equal('touchstart')
expect(utils.handleEventType('touchMove')).to.equal('touchmove')
expect(utils.handleEventType('touchEnd')).to.equal('touchend')
expect(utils.handleEventType('tap')).to.equal('tap')
});
it('test handleCompEventType', function() {
expect(utils.handleCompEventType('touchstart')).to.equal('touchStart')
expect(utils.handleCompEventType('touchmove')).to.equal('touchMove')
expect(utils.handleCompEventType('touchend')).to.equal('touchEnd')
expect(utils.handleCompEventType('tap')).to.equal('tap')
});
})
const mixins = require('../web-mixins.js').mixins.methods;
const {expect} = require('chai');
let eventEmittter = require('events')
let e = {
type: 'touchstart',
target: {
},
stopPropagation: function() {},
timeStamp: 3795662,
currentTarget: {
dataset: {
eventtouchstart: ['handleTouchStart', '$event', 1]
}
},
touches: [{
identifier: 'identifier',
pageX: 'pageX',
pageY: 'pageY',
screenX: 'screenX',
screenY: 'screenY'
}],
changedTouches: [{
identifier: 'identifier',
pageX: 'pageX',
pageY: 'pageY',
screenX: 'screenX',
screenY: 'screenY'
}]
}
describe('web-mixins.js', function() {
it('test _cmlInline', function() {
global.Event = eventEmittter
let thisArg = {
handleTouchStart: function() {
}
}
expect(mixins._cmlInline.call(thisArg, 'handleTouchStart', true, e)).to.be.not.ok
});
it('test _cmlModelEventProxy', function() {
let thisArg = {
key: 'modelKey'
}
expect(mixins._cmlModelEventProxy.call(thisArg, e, 'key')).to.be.not.ok
});
it('test _cmlEventProxy', function() {
let thisArg = {
handleTouchStart: function() {
}
}
expect(mixins._cmlEventProxy.call(thisArg, e, 'handleTouchStart', true)).to.be.not.ok
});
it('test $cmlEmit', function() {
let thisArg = {
$emit: function() {
},
$__checkCmlEmit__: function() {
}
}
expect(mixins.$cmlEmit.call(thisArg, 'handleTouchStart', {detail: 'detail'})).to.be.not.ok
});
it('test styleProxyName function:aimed to transform cssStyle object to cssStyle string', function() {
expect(mixins.$cmlStyle('width:100px;')).to.be.equal('width:100px;')
expect(mixins.$cmlStyle({width: '100px'})).to.be.equal('width:100px;')
......
......@@ -2,6 +2,96 @@ const mixins = require('../weex-mixins.js').mixins.methods;
const {expect} = require('chai');
describe('weex-mixins.js', function() {
it('test _cmlInline', function() {
let e = {
type: 'touchstart',
target: {
},
stopPropagation: function() {},
timestamp: 3795662,
currentTarget: {
dataset: {
eventtouchstart: ['handleTouchStart', '$event', 1]
}
},
touches: [{
identifier: 'identifier',
pageX: 'pageX',
pageY: 'pageY',
screenX: 'screenX',
screenY: 'screenY'
}],
changedTouches: [{
identifier: 'identifier',
pageX: 'pageX',
pageY: 'pageY',
screenX: 'screenX',
screenY: 'screenY'
}]
}
let thisArg = {
handleTouchStart: function() {
}
}
expect(mixins._cmlInline.call(thisArg, 'handleTouchStart', true, 1, e)).to.be.not.ok
});
it('test _cmlModelEventProxy', function() {
let e = {
type: 'touchstart',
target: {
},
stopPropagation: function() {},
timestamp: 3795662,
currentTarget: {
dataset: {
eventtouchstart: ['handleTouchStart', '$event', 1]
}
}
}
let thisArg = {
key: 'modelKey'
}
expect(mixins._cmlModelEventProxy.call(thisArg, e, 'key')).to.be.not.ok
});
it('test _cmlEventProxy', function() {
let e = {
type: 'touchstart',
target: {
},
stopPropagation: function() {},
timestamp: 3795662,
currentTarget: {
dataset: {
eventtouchstart: ['handleTouchStart', '$event', 1]
}
}
}
let thisArg = {
handleTouchStart: function() {
}
}
expect(mixins._cmlEventProxy.call(thisArg, e, 'handleTouchStart', true)).to.be.not.ok
});
it('test $cmlEmit', function() {
let thisArg = {
$emit: function() {
},
$__checkCmlEmit__: function() {
}
}
expect(mixins.$cmlEmit.call(thisArg, 'handleTouchStart', {detail: 'detail'})).to.be.not.ok
});
it('test styleProxyName function:aimed to transform cssStyle string to cssStyle Object', function() {
expect(mixins._cmlStyleProxy('width:75px; ;height:50px; ')).to.be.deep.equal({ width: '75px', height: '50px' });
expect(mixins._cmlStyleProxy({ width: '75px', height: '50px' })).to.be.deep.equal({ width: '75px', height: '50px' });
......
const mixins = require('../wx-alipay-common-mixins.js').mixins.methods;
const mixins = require('../wx-mixins.js').mixins.methods;
const {expect} = require('chai');
describe('wx-mixins.js', function() {
it('test $cmlEmit', function() {
let thisArg = {
triggerEvent: function() {
},
$__checkCmlEmit__: function() {
}
}
expect(mixins.$cmlEmit.call(thisArg, 'handleTouchStart', {detail: 'detail'})).to.be.not.ok
});
it('test _cmlInline', function() {
let e = {
type: 'touchstart',
currentTarget: {
dataset: {
eventtouchstart: ['handleTouchStart', '$event', 1]
}
}
}
let thisArg = {
handleTouchStart: function() {
}
}
expect(mixins._cmlInline.call(thisArg, e)).to.be.not.ok
});
it('test _cmlModelEventProxy', function() {
let e = {
type: 'touchstart',
currentTarget: {
dataset: {
modelkey: 'key'
}
},
detail: {
value: "detailValue"
}
}
let thisArg = {
key: 'modelKey'
}
expect(mixins._cmlModelEventProxy.call(thisArg, e)).to.be.not.ok
});
it('test _cmlEventProxy', function() {
let e = {
type: 'touchstart',
currentTarget: {
dataset: {
eventtouchstart: ['handleTouchStart']
}
}
}
let thisArg = {
handleTouchStart: function() {
}
}
expect(mixins._cmlEventProxy.call(thisArg, e)).to.be.not.ok
});
it('test styleProxyName function:aimed to transfrom px to rpx', function() {
expect(mixins.$cmlStyle('width:75cpx;height:50cpx;')).to.be.equal(`width:75rpx;height:50rpx`);
expect(mixins.$cmlStyle({ width: '75cpx', height: '50cpx' })).to.be.equal(`width:75rpx;height:50rpx`);
......@@ -13,5 +73,39 @@ describe('wx-mixins.js', function() {
let mergeResult = mixins.$cmlMergeStyle(cssString, cssObj1, cssObj2);
expect(mergeResult).to.be.equal(`background-color:red;width:100px;height:200px;;font-size:30px;color:red;`);
});
// _animationCb
it('test _animationCb', function() {
let e = {
animationValue: 'animationValue'
}
let thisArg = {
animationValue: {
cbs: [function() {}],
index: 0
}
}
expect(mixins._animationCb.call(thisArg, e)).to.be.not.ok
});
it('test _animationCb', function() {
let e = {
animationValue: 'animationValue'
}
let thisArg = {
animationValue: {
index: 1
}
}
expect(mixins._animationCb.call(thisArg, e)).to.be.not.ok
});
it('test _animationCb', function() {
let e = {
animationValue: 'animationValue'
}
let thisArg = {
animationValue: {
cbs: [function() {}]
}
}
expect(mixins._animationCb.call(thisArg, e)).to.be.not.ok
});
})
......@@ -8,4 +8,30 @@ _.getStyleKeyValue = function(declaration) {
key, value
}
}
// 支付宝中的e.type="touchStart"
_.handleEventType = function(eventType) {
let aliEventMap = {
touchStart: "touchstart",
touchEnd: "touchend",
touchMove: "touchmove"
}
if (Object.keys(aliEventMap).includes(eventType)) {
return aliEventMap[eventType]
} else {
return eventType
}
}
// 对于组件上绑定的touchstart事件,在编译之后会处理成 onTouchStart="handleStart",所以需要改为对应的大写
_.handleCompEventType = function(eventType) {
let aliEventMap = {
touchstart: 'touchStart',
touchend: 'touchEnd',
touchmove: 'touchMove'
}
if (Object.keys(aliEventMap).includes(eventType)) {
return aliEventMap[eventType]
} else {
return eventType
}
}
......@@ -2,7 +2,7 @@
const common = require('./common.js');
const wxStyleHandle = require('chameleon-css-loader/proxy/proxyMiniapp.js')
const utils = require('./utils.js')
const deepClone = function(obj) {
if (obj.toString().slice(8, -1) !== "Object") {
return obj;
......@@ -23,23 +23,22 @@ _.mixins = {
// 支持事件传参
[_.inlineStatementEventProxy](e) {
let { dataset } = e.currentTarget;
let originFuncName = dataset && dataset[`event${e.type}`];
let argsStr = dataset && dataset.args;
// 支付宝的e.type = 'touchStart',需要改为小写,否则找不到函数
e.type = utils.handleEventType(e.type);
let eventKey = e.type.toLowerCase();
let originFuncName = dataset && dataset[`event${eventKey}`] && dataset[`event${eventKey}`][0];
let inlineArgs = dataset && dataset[`event${eventKey}`] && dataset[`event${eventKey}`].slice(1);
let argsArr = [];
// 由于百度对于 data-arg="" 在dataset.arg = true 值和微信端不一样所以需要重新处理下这部分逻辑
if (argsStr && typeof argsStr === 'string') {
argsArr = argsStr.split(',').reduce((result, item, index) => {
let arg = dataset[`arg${index}`];
if (inlineArgs) {
argsArr = inlineArgs.reduce((result, arg, index) => {
if (arg === "$event") {
let newEvent = getNewEvent(e);
result.push(newEvent);
} else {
// 这里的值微信已经计算好了;到dateset的时候已经是计算的结果 比如msg = 'sss' data-arg1="{{msg + 1}}"
// dataset[arg1] = 'sss1'
result.push(dataset[`arg${index}`])
result.push(arg)
}
return result;
}, []);
}
if (originFuncName && this[originFuncName] && _.isType(this[originFuncName], 'Function')) {
......@@ -58,7 +57,10 @@ _.mixins = {
},
[_.eventProxyName](e) {
let { dataset } = e.currentTarget;
let originFuncName = dataset && dataset[`event${e.type}`]
// 支付宝的e.type = 'touchStart',需要改为小写,否则找不到函数
e.type = utils.handleEventType(e.type);
let eventKey = e.type.toLowerCase();
let originFuncName = dataset && dataset[`event${eventKey}`] && dataset[`event${eventKey}`][0];
if (originFuncName && this[originFuncName] && _.isType(this[originFuncName], 'Function')) {
let newEvent = getNewEvent(e);
this[originFuncName](newEvent)
......
......@@ -293,3 +293,17 @@ _.miniappVUEClassNodes = function (options) {
}
}
// 转换 $event参数
_.getInlineStatementArgs = function(argsStr) {
// argsStr:"1,'index'+1,$event,'item',index+1,item"
const result = argsStr.split(',').reduce((result, current, index) => {
if (current === '$event') {
result.push("'$event'");
} else {
result.push(current)
}
return result
}, []);
return result.join();// "1,'index'+1,'$event','item',index+1,item"
}
......@@ -11,6 +11,7 @@ parseDirective.tap('web-weex-cml', (args) => {
if (lang === 'cml' && (type === 'web' || type === 'weex')) {
// 以下开始处理指令;
// v-model c-model
// web端因为是自定义组件触发的 input事件的参数不对,所以不能直接用vue的v-model
if (t.isJSXAttribute(node) && node.name.name === 'c-model') {
let modelKey = utils.getModelKey(node.value.value);
path.insertAfter(t.jsxAttribute(t.jsxIdentifier(`v-bind:value`), t.stringLiteral(modelKey)))
......
......@@ -65,7 +65,7 @@ parseEvent.tap('wx-baidu', (args) => {
let value = container.value;
let parentPath = path.parentPath;
let name = node.name.name === 'click' ? 'tap' : node.name.name;
name = utils.dasherise(name);
let eventKey = name.toLowerCase();
let wxName = node.name.name === 'click' ? 'tap' : node.name.name;
let handler = value.value && utils.trim(value.value);
let match = utils.isInlineStatementFn(handler);
......@@ -87,29 +87,18 @@ parseEvent.tap('wx-baidu', (args) => {
}
// ====这里作用是阻止对 origin-tag标签的事件进行代理
if (!match) {
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-event${name}`), t.stringLiteral(handler)))
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-event${eventKey}`), t.stringLiteral(`{{['${handler}']}}`)))
value.value = `${wxEventProxy.eventProxyName}`;
} else {
let index = handler.indexOf('(');
index > 0 && (handler = utils.trim(handler.slice(0, index)));
value.value = `${eventProxy.inlineStatementEventProxy}`;
let args = match && utils.doublequot2singlequot(match[1]).trim();
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-event${name}`), t.stringLiteral(handler)))
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-args`), t.stringLiteral(args)))
if (args) {
args.split(',').forEach((arg, index) => {
arg = utils.trim(arg);
let argMatch = utils.isReactive(arg);
if (!argMatch) {
if (arg === "$event") {
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-arg${index}`), t.stringLiteral(arg)));
} else {
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-arg${index}`), t.stringLiteral(`{{${arg}}}`)))
}
} else { // 字符串形式
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-arg${index}`), t.stringLiteral(argMatch[1])))
}
})
if (args) { // 内联函数传参
let inlineArgs = utils.getInlineStatementArgs(args);
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-event${eventKey}`), t.stringLiteral(`{{['${handler}',${inlineArgs}]}}`)))
} else { // 内联函数不传参
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-event${eventKey}`), t.stringLiteral(`{{['${handler}']}}`)))
}
}
}
......@@ -121,7 +110,9 @@ parseEvent.tap('alipay', (args) => {
let container = path.container;
let value = container.value;
let parentPath = path.parentPath;
let name = node.name && (node.name.name === 'click' ? 'tap' : node.name.name);// alipay需要将事件名称转化成大写;
let name = node.name && (node.name.name === 'click' ? 'tap' : node.name.name);
let eventKey = name.toLowerCase();
// alipay需要将事件名称转化成大写;
let aliName = utils.titleLize(eventMap[name] || name);
let handler = value.value && utils.trim(value.value);
let match = utils.isInlineStatementFn(handler);
......@@ -142,29 +133,18 @@ parseEvent.tap('alipay', (args) => {
}
// ====这里作用是阻止对 origin-tag标签的事件进行代理
if (!match) {
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-event${name}`), t.stringLiteral(handler)))
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-event${eventKey}`), t.stringLiteral(`{{['${handler}']}}`)))
value.value = `${wxEventProxy.eventProxyName}`;
} else {
let index = handler.indexOf('(');
index > 0 && (handler = utils.trim(handler.slice(0, index)));
value.value = `${eventProxy.inlineStatementEventProxy}`;
let args = match && utils.doublequot2singlequot(match[1]).trim();
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-event${name}`), t.stringLiteral(handler)))
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-args`), t.stringLiteral(args)))
if (args) {
args.split(',').forEach((arg, index) => {
arg = utils.trim(arg);
let argMatch = utils.isReactive(arg);
if (!argMatch) {
if (arg === "$event") {
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-arg${index}`), t.stringLiteral(arg)));
} else {
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-arg${index}`), t.stringLiteral(`{{${arg}}}`)))
}
} else { // 字符串形式
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-arg${index}`), t.stringLiteral(argMatch[1])))
}
})
if (args) { // 内联函数传参
let inlineArgs = utils.getInlineStatementArgs(args);
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-event${eventKey}`), t.stringLiteral(`{{['${handler}',${inlineArgs}]}}`)))
} else { // 内联函数不传参
parentPath.insertAfter(t.jsxAttribute(t.jsxIdentifier(`data-event${eventKey}`), t.stringLiteral(`{{['${handler}']}}`)))
}
}
}
......
......@@ -110,5 +110,11 @@ describe('utils', function() {
expect(result).to.equal(`{{'width:' + cpx + 'rpx;' + 'height:' + cpx2 + 'rpx;background-color:red'}}`);
})
});
// getInlineStatementArgs
describe('getInlineStatementArgs', function() {
it('getInlineStatementArgs', function() {
let result = utils.getInlineStatementArgs("1,'index'+1,$event,'item',index+1,item");
expect(result).to.equal(`1,'index'+1,'$event','item',index+1,item`);
})
});
})
const compileTemplate = require('../src/index.js');
const source = `<view c-bind:click="handleClick( )">事件测试-内联事件</view>`
const source = `<view class="demo-com">
<view c-bind:touchstart="handleIndexTouchStart">index-handleTouchStart</view>
<view c-bind:userEvent="handleIndexTap">index-handletap</view>
<view c-bind:userevent="handleIndexTap">index-handletap</view>
</view>`
// <view><text :class="{{true? 'bg-green':''}}" >fafafa</text></view>
// <view><text :class="true? 'bg-green':''" >fafafa</text></view>
//
......@@ -35,11 +39,11 @@ let options = {lang: 'cml',
console.log('before-compile', source);
// let result_web = compileTemplate(source, 'web', options);
// let result_weex = compileTemplate(source, 'weex', options);
let result_wx = compileTemplate(source, 'wx', options);
let result_baidu = compileTemplate(source, 'baidu', options);
// let result_wx = compileTemplate(source, 'wx', options);
// let result_baidu = compileTemplate(source, 'baidu', options);
let result_alipay = compileTemplate(source, 'alipay', options);
// console.log('result_web', result_web)
// console.log('result_weex', result_weex)
console.log('result_wx', result_wx)
console.log('result_baidu', result_baidu)
// console.log('result_wx', result_wx)
// console.log('result_baidu', result_baidu)
console.log('result_alipay', result_alipay)
......@@ -164,10 +164,10 @@ describe('parse-template-cml', function() {
let callback = parseTemplate.parseEventListener;
let result = compileTemplate(source, 'wx', options, callback);
it('test-event-transform', function() {
expect(result).to.equal(`<view><view bindtap="_cmlEventProxy" data-eventtap="tapHandle"></view></view>`)
expect(result).to.equal(`<view><view bindtap="_cmlEventProxy" data-eventtap="{{['tapHandle']}}"></view></view>`)
});
it('test-origin-tag-event-transform', function() {
expect(compileTemplate(originSource, 'wx', options, callback)).to.equal(`<view><origin-tag bindtap="handleClick"></origin-tag><thirdComp1 bindtap="handleClick"></thirdComp1><thirdComp2 bindtap="_cmlEventProxy" data-eventtap="handleClick"></thirdComp2></view>`)
expect(compileTemplate(originSource, 'wx', options, callback)).to.equal(`<view><origin-tag bindtap="handleClick"></origin-tag><thirdComp1 bindtap="handleClick"></thirdComp1><thirdComp2 bindtap="_cmlEventProxy" data-eventtap="{{['handleClick']}}"></thirdComp2></view>`)
});
});
describe('parseEventListener-alipay', function() {
......@@ -177,10 +177,10 @@ describe('parse-template-cml', function() {
let callback = parseTemplate.parseEventListener;
let result = compileTemplate(source, 'alipay', options, callback);
it('test-event-transform', function() {
expect(result).to.equal(`<view><view onTap="_cmlEventProxy" data-eventtap="tapHandle"></view></view>`)
expect(result).to.equal(`<view><view onTap="_cmlEventProxy" data-eventtap="{{['tapHandle']}}"></view></view>`)
});
it('test-origin-tag-event-transform', function() {
expect(compileTemplate(originSource, 'alipay', options, callback)).to.equal(`<view><origin-tag onTap="handleClick"></origin-tag><thirdComp1 onTap="handleClick"></thirdComp1><thirdComp2 onTap="_cmlEventProxy" data-eventtap="handleClick"></thirdComp2></view>`)
expect(compileTemplate(originSource, 'alipay', options, callback)).to.equal(`<view><origin-tag onTap="handleClick"></origin-tag><thirdComp1 onTap="handleClick"></thirdComp1><thirdComp2 onTap="_cmlEventProxy" data-eventtap="{{['handleClick']}}"></thirdComp2></view>`)
});
});
// parseIterationStatement
......
......@@ -806,13 +806,15 @@ _.findComponent = function (filePath, cmlType) {
}
let ext = fileExtMap[cmlType];
if (typeof ext === 'string') {
ext = [ext];
}
for (let i = 0; i < ext.length; i++) {
let extFilePath = filePath + ext[i];
if (_.isFile(extFilePath)) {
return extFilePath;
if (ext) {
if (typeof ext === 'string') {
ext = [ext];
}
for (let i = 0; i < ext.length; i++) {
let extFilePath = filePath + ext[i];
if (_.isFile(extFilePath)) {
return extFilePath;
}
}
}
......
......@@ -5,7 +5,6 @@ const utils = require('../utils.js');
const {MvvmGraphPlugin} = require('mvvm-pack');
const resolve = require('resolve');
module.exports = function(options) {
let {type, media} = options;
let npmName = cml.config.get().extPlatform[type];
......@@ -34,7 +33,7 @@ module.exports = function(options) {
loaders: utils.cssLoaders({type, media}),
cmlType: type,
media,
check: cml.config.get().check,
check: cml.config.get().check
}
}]
}
......@@ -65,6 +64,26 @@ module.exports = function(options) {
})
}
return merge(commonConfig, extendConfig);
if (platformPlugin.miniappExt && platformPlugin.miniappExt.rule) {
extendConfig = merge(extendConfig, {
module: {
rules: [
{
test: platformPlugin.miniappExt.rule,
use: [{
loader: 'mvvm-miniapp-loader',
options: {
loaders: utils.cssLoaders({type, media}),
cmlType: type,
media,
mapping: platformPlugin.miniappExt.mapping
}
}]
}
]
}
})
}
return merge(commonConfig, extendConfig);
}
\ No newline at end of file
......@@ -76,6 +76,7 @@
"minimist": "1.2.0",
"mvvm-cml-loader": "^0.4.0-mvvm.5",
"mvvm-file-loader": "^0.4.0-mvvm.5",
"mvvm-miniapp-loader": "^0.4.0-mvvm.5",
"mvvm-pack": "^0.4.0-mvvm.5",
"mvvm-style-loader": "^0.4.0-mvvm.5",
"node-phpcgi": "0.3.7",
......
......@@ -2,9 +2,8 @@
"name": "mvvm-babel-generator",
"version": "0.4.0-mvvm.5",
"description": "Turns an AST into code.",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"license": "MIT",
"author": "Chameleon-Team",
"license": "Apache",
"publishConfig": {
"access": "public"
},
......
......@@ -16,6 +16,6 @@
"scripts": {
"test": "mocha"
},
"author": "",
"license": "ISC"
"author": "Chameleon-Team",
"license": "Apache"
}
\ No newline at end of file
......@@ -5,8 +5,8 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"author": "Chameleon-Team",
"license": "Apache",
"description": "",
"dependencies": {
"@babel/generator": "^7.3.4",
......
此差异已折叠。
# Editor directories and files
.DS_Store
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
dist/
# ///////////////////////////
const path = require('path');
exports.stringifyLoaders = function (loaders) {
return loaders
.map(
obj =>
obj && typeof obj === 'object' && typeof obj.loader === 'string'
? obj.loader +
(obj.options ? '?' + JSON.stringify(obj.options) : '')
: obj
)
.join('!')
}
exports.getSelector = function() {
return path.resolve(__dirname, './selector.js')
}
exports.getPartLoaders = function({selectorOptions, partType, lang, loaders, resourcePath}) {
selectorOptions.partType = partType;
let resultLoaders = [
{
loader: exports.getSelector(),
options: selectorOptions
}
]
switch (partType) {
case 'style':
var styleLoader = loaders[lang];
if (!(styleLoader instanceof Array)) {
styleLoader = [styleLoader];
}
resultLoaders = styleLoader.concat(resultLoaders);
break;
case 'script':
var jsLoader = loaders.js;
if (!(jsLoader instanceof Array)) {
jsLoader = [jsLoader];
}
resultLoaders = jsLoader.concat(resultLoaders);
break;
default:
break;
}
let stringLoaders = exports.stringifyLoaders(resultLoaders);
return '!' + stringLoaders + '!' + resourcePath;
}
exports.toUpperCase = function (content) {
return content.replace(/-(\w)/ig, function (m, s1) {
return s1.toUpperCase()
})
}
\ No newline at end of file
/**
* 针对小程序的loader 将小程序文件结构变成cml文件结构
*/
const loaderUtils = require('loader-utils');
const helper = require('./helper.js');
module.exports = function(content) {
let output = "";
this._module._nodeType = "component";
const rawOptions = loaderUtils.getOptions(this) || {};
let {loaders, cmlType, media, mapping} = rawOptions;
const resourcePath = this.resourcePath;
let selectorOptions = {
cmlType,
media,
mapping
}
output += `var template = require('${helper.getPartLoaders({selectorOptions, partType: 'template', loaders, resourcePath})}');\n`
output += `var style = require('${helper.getPartLoaders({selectorOptions, partType: 'style', lang: 'css', loaders, resourcePath})}');\n`
output += `var json = require('${helper.getPartLoaders({selectorOptions, partType: 'json', loaders, resourcePath})}');\n`
output += `var script = require('${helper.getPartLoaders({selectorOptions, partType: 'script', loaders, resourcePath})}');\n`
return output;
}
\ No newline at end of file
{
"name": "mvvm-miniapp-loader",
"version": "0.4.0-mvvm.5",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Chameleon-Team",
"license": "Apache",
"dependencies": {
"loader-utils": "^1.2.3"
}
}
const loaderUtils = require('loader-utils');
const path = require('path');
const fs = require('fs');
module.exports = function() {
const self = this;
let output = '';
const rawOptions = loaderUtils.getOptions(this) || {};
const resourcePath = this.resourcePath;
let {mapping, partType} = rawOptions;
this._module._nodeType = 'module';
this._module._moduleType = partType;
this._module._parentNodeType = 'components';
let partFilePath = resourcePath.replace(path.extname(resourcePath), mapping[partType]);
self.addDependency(partFilePath);
switch (partType) {
case 'json':
this._module._cmlSource = JSON.stringify(JSON.parse(fs.readFileSync(partFilePath, {encoding: 'utf8'})) || {}, '', 4);
output = `module.exports = ${this._module._cmlSource}`;
break;
case 'template':
this._module._cmlSource = fs.readFileSync(partFilePath, {encoding: 'utf8'});
output = `module.exports = ${JSON.stringify(this._module._cmlSource)}`;
break;
case 'script':
case 'style':
output = fs.readFileSync(partFilePath, {encoding: 'utf8'});
break;
default:
break;
}
return output;
}
......@@ -3,7 +3,7 @@ const path = require('path');
const Log = require('./log.js');
const EventEmitter = require('events');
const cmlUtils = require('chameleon-tool-utils');
const parser = require('mvvm-babel-parser/lib');
const {cmlparse} = require('mvvm-template-parser');
const amd = require('./lib/amd.js');
const {replaceJsModId, chameleonIdHandle} = require('./lib/replaceJsModId.js');
......@@ -188,9 +188,7 @@ class Compiler {
}
if (options.moduleType === 'template') {
options.convert = parser.parse(options.source, {
plugins: ['jsx']
});
options.convert = cmlparse(options.source);
options.extra = {
nativeComponents: module._nativeComponents,
currentUsedBuildInTagMap: module._currentUsedBuildInTagMap
......@@ -199,7 +197,8 @@ class Compiler {
if (options.moduleType === 'json') {
// cml文件中的json部分
if (module.parent) {
// todo 这里进不来
if (/^\{[\s\S]*\}$/.test(options.source)) {
options.convert = JSON.parse(options.source);
}
// 其他json文件不处理 例如router.config.json
......
......@@ -6,18 +6,19 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"author": "Chameleon-Team",
"license": "Apache",
"dependencies": {
"chameleon-tool-utils": "0.4.0-mvvm.5",
"mvvm-babel-parser": "0.4.0-mvvm.5",
"webpack-merge": "^4.2.1",
"chameleon-webpack-plugin": "0.4.0-mvvm.5",
"runtime-check": "0.4.0-mvvm.5",
"@babel/core": "^7.3.4",
"@babel/generator": "^7.4.0",
"@babel/parser": "^7.3.4",
"@babel/traverse": "^7.3.4",
"@babel/types": "^7.3.4"
"@babel/types": "^7.3.4",
"chameleon-tool-utils": "0.4.0-mvvm.5",
"chameleon-webpack-plugin": "0.4.0-mvvm.5",
"mvvm-babel-parser": "0.4.0-mvvm.5",
"mvvm-template-parser": "^0.4.0-mvvm.5",
"runtime-check": "0.4.0-mvvm.5",
"webpack-merge": "^4.2.1"
}
}
\ No newline at end of file
}
......@@ -19,7 +19,7 @@ exports.assets = function({source, loaderContext}) {
deps.push(realDependPath);
return `__cml${realDependPath}__lmc`;
} else {
return $1;
return `url("${$1}")`;
}
})
}
......
......@@ -4,7 +4,8 @@
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"cover": "istanbul cover --report lcov _mocha -- -R spec --recursive",
"test": "mocha --recursive --reporter spec"
},
"author": "Chameleon-Team",
"license": "Apache",
......
const _ = require('../index.js');
const path = require('path');
var expect = require('chai').expect;
describe('mvvm-style-loader', function() {
it('assets image url', function() {
let loaderContext = {
_module: {},
resourcePath: path.join(__dirname,'index.js')
}
let content = `
.class1 {
color: red;
background: url('./1.png');
}
`
let output = _.call(loaderContext, content);
expect(!!~output.indexOf(path.join(__dirname,'1.png'))).to.be.equal(true);
expect(loaderContext._module._nodeType).to.be.equal('module');
expect(loaderContext._module._moduleType).to.be.equal('style');
expect(!!~loaderContext._module._cmlSource.indexOf(`__cml${path.join(__dirname,'1.png')}__lmc`)).to.be.equal(true);
})
it('assets inline image url', function() {
let loaderContext = {
_module: {},
resourcePath: path.join(__dirname,'index.js')
}
let content = `
.class1 {
color: red;
background: url('./1.png?__inline');
}
`
let output = _.call(loaderContext, content);
console.log(output)
console.log(loaderContext._module)
expect(!!~output.indexOf(path.join(__dirname,'1.png'))).to.be.equal(true);
expect(loaderContext._module._nodeType).to.be.equal('module');
expect(loaderContext._module._moduleType).to.be.equal('style');
expect(!!~loaderContext._module._cmlSource.indexOf(`__cml${path.join(__dirname,'1.png?__inline')}__lmc`)).to.be.equal(true);
})
it('assets not file image url', function() {
let loaderContext = {
_module: {},
resourcePath: path.join(__dirname,'index.js')
}
let content = `
.class1 {
color: red;
background: url('./2.png');
}
`
let output = _.call(loaderContext, content);
console.log(output)
console.log(loaderContext._module)
expect(loaderContext._module._nodeType).to.be.equal('module');
expect(loaderContext._module._moduleType).to.be.equal('style');
expect(!!~loaderContext._module._cmlSource.indexOf(`background: url("./2.png")`)).to.be.equal(true);
})
})
\ No newline at end of file
const {vueToCml} = require('./lib/process-template.js');
const {vueToCml, preDisappearAnnotation} = require('./lib/process-template.js');
const parser = require('mvvm-babel-parser');
const generator = require('mvvm-babel-generator/lib')
const types = require('@babel/types');
const traverse = require('@babel/traverse');
exports.parser = parser;
exports.generator = function(...args) {
let result = generator["default"].apply(this, args);
......@@ -18,6 +17,7 @@ exports.traverse = traverse["default"];
exports.vueToCml = vueToCml;
exports.cmlparse = function(content) {
content = preDisappearAnnotation(content);
return parser.parse(content, {
plugins: ['jsx']
})
......
......@@ -4,10 +4,11 @@
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"cover": "istanbul cover --report lcov _mocha -- -R spec --recursive",
"test": "mocha --recursive --reporter spec"
},
"author": "",
"license": "ISC",
"author": "Chameleon-Team",
"license": "Apache",
"dependencies": {
"@babel/traverse": "^7.3.4",
"@babel/types": "^7.3.4",
......
const {standardParser, generator, types, traverse} = require('../index.js');
// const {standardParser, generator, types, traverse} = require('../index.js');
const template = `
<view c-bind:tap="click1">
<text>{{'名称'+name}}</text>
</view>
`
// const template = `
// <view c-bind:tap="click1">
// <text>{{'名称'+name}}</text>
// </view>
// `
const {ast} = standardParser({
source: template,
lang: 'cml'
})
traverse(ast, {
enter: (path) => {
let node = path.node;
if (types.isJSXOpeningElement(node)) {
if (types.isJSXIdentifier(node.name) && node.name.name === 'view') {
node.name.name = 'div';
}
}
if (types.isJSXClosingElement(node)) {
if (types.isJSXIdentifier(node.name) && node.name.name === 'view') {
node.name.name = 'div';
}
}
}
})
// const {ast} = standardParser({
// source: template,
// lang: 'cml'
// })
// traverse(ast, {
// enter: (path) => {
// let node = path.node;
// if (types.isJSXOpeningElement(node)) {
// if (types.isJSXIdentifier(node.name) && node.name.name === 'view') {
// node.name.name = 'div';
// }
// }
// if (types.isJSXClosingElement(node)) {
// if (types.isJSXIdentifier(node.name) && node.name.name === 'view') {
// node.name.name = 'div';
// }
// }
// }
// })
const output = generator(ast);
// const output = generator(ast);
console.log(output)
// console.log(output)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册