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

Merge pull request #181 from didi/uniform

Uniform
#!/usr/bin/env node
// --inspect-brk
const program = require('commander');
const packageJson = require('../package.json');
const main = require('../index');
......
const jsAstParser = require('./lib/js-ast-parser');
const templateAstParser = require('./lib/template-ast-parser');
const jsonAstParser = require('./lib/json-ast-parser');
const commonEvents = require('../../config/common-events.json');
class TemplateChecker {
......@@ -49,10 +49,17 @@ class TemplateChecker {
if (usingComponents[compName] && usingComponents[compName].isCml) {
let { props, events } = component[compName];
let { props: usingProps, events: usingEvents } = usingComponents[compName];
usingProps = usingProps.map((prop) => prop.name).join('|');
usingEvents = usingEvents.map((event) => event.name).join('|');
props.filter((prop) => usingProps.indexOf(prop.name) === -1).forEach((prop) => {
usingProps = usingProps
.map((prop) => prop.name)
.join('|');
usingEvents = usingEvents
.map((event) => event.name)
.concat(commonEvents.events)
.join('|');
usingProps = `|${usingProps}|`;
usingEvents = `|${usingEvents}|`;
debugger
props.filter((prop) => usingProps.indexOf('|' + prop.name + '|') === -1).forEach((prop) => {
issues.push({
line: prop.pos[0],
column: prop.pos[1],
......@@ -61,7 +68,7 @@ class TemplateChecker {
});
});
events.filter((event) => usingEvents.indexOf(event.name) === -1).forEach((event) => {
events.filter((event) => usingEvents.indexOf('|' + event.name + '|') === -1).forEach((event) => {
issues.push({
line: event.pos[0],
column: event.pos[1],
......
{
"events": ["tap", "click", "touchstart", "touchmove", "touchend"]
}
\ No newline at end of file
const list = [{
name: 'app',
allowAttrs: {
vars: ['store', 'routerConfig'],
vars: ['routerConfig'],
methods: [],
props: [{
name: 'store',
required: true
}, {
name: 'routerConfig',
required: true
}],
......
......@@ -245,7 +245,8 @@ module.exports = function (content) {
let compileResult = ASTcompileTemplate(templateContent, {
lang,
usingComponents,
filePath
filePath,
isInjectBaseStyle
});
let emitPath = entryPath.replace(miniCmlReg, `.${miniappTplExt[cmlType]}`)
......@@ -373,13 +374,21 @@ module.exports = function (content) {
usingComponents = prepareParseUsingComponents(usingComponents);
//有组件在weex.cml中的template写的根标签不是唯一的,进入jsx解析会报错
let before = '<template>\n' +
templateContent + '\n' +
'</template>'
let before = '';
if (type === 'component') { // 组件包裹div
before = '<template>\n<view class="__shadow_root__">' +
templateContent + '\n' +
'</view></template>'
} else { // 其他包裹template
before = '<template>\n' +
templateContent + '\n' +
'</template>'
}
return ASTcompileTemplate(before, {
lang,
usingComponents,
filePath
filePath,
isInjectBaseStyle
});
}
......
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)
......
......@@ -52,8 +52,10 @@ exports.preParseAliComponent = function(source, type, options) {
// 先 push view标签,然后再push组件标签
let isComponent = usingComponents.find((comp) => comp.tagName === item.tagName) || Object.keys(buildInComponents).includes(item.tagName);
let inheritNodes = (item.attrs || []).filter((attr) => {
let inheritAttrsFromComp = ['c-if', 'c-else', 'c-else-if', 'v-if', 'v-else', 'v-else-if', 'class', 'style', 'v-bind:style', 'v-bind:class', ':style', ":class", "c-show", "v-show"]
return inheritAttrsFromComp.includes(attr[1]);
let inheritAttrsFromComp = ['c-if', 'c-else', 'c-else-if', 'v-if', 'v-else', 'v-else-if', 'class', 'style', 'v-bind:style', 'v-bind:class', ':style', ":class", "c-show", "v-show"];
let inheritEvent = ['c-bind:click', 'c-bind:tap', 'c-bind:touchstart', 'c-bind:touchmove', 'c-bind:touchend', 'c-bind:touchcancel', 'c-catch:click', 'c-catch:tap', 'c-catch:touchstart', 'c-catch:touchmove', 'c-catch:touchend', 'c-catch:touchcancel'];
let isInherit = inheritAttrsFromComp.includes(attr[1]) || inheritEvent.includes(attr[1]) || /^data-/.test(attr[1])
return isInherit;
});
let inheritString = inheritNodes.reduce((result, styleClassNode) => result = result + (styleClassNode[0] || ''), '');
if (isComponent && !isExpectTags) { // 如果是组件需要从组件继承一些属性过来
......@@ -98,7 +100,6 @@ exports.preParseHTMLtoArray = function(html, type, options, callbacks) {
const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`)
let index = 0;
while (html) {
last = html;
let textEnd = html.indexOf('<')
// 解析标签内容,包括开始标签以及结束标签
if (textEnd === 0) { // 以 < 开头的html
......@@ -255,10 +256,8 @@ exports.preParseVueEvent = function (content) {
content = content.replace(reg, (m, $1) => {
if (typeof $1 === "string" && $1.endsWith('.stop')) {
$1 = $1.replace('.stop', '');
$1 = $1 === 'click' ? 'tap' : $1;
return `c-catch:${$1}=`;
} else {
$1 = $1 === 'click' ? 'tap' : $1;
return `c-bind:${$1}=`
}
});
......@@ -532,3 +531,7 @@ exports._deOperationGtLt = function(content) {
return match;
})
}
exports.transformNativeEvent = function(source) {
let reg = /__CML_NATIVE_EVENTS__/g;
return source.replace(reg, '.native');
}
......@@ -29,7 +29,7 @@ _.analysisFor = function (nodeValue) {
let reg1 = /\s*(.+?)\s+(?:in|of)\s+(.+)\s*/;
// v-for="(item, index) in items"
let reg2 = /\s*\(([^\,\s]+?)\s*\,\s*([^\,\s]+?)\s*\)\s*(?:in|of)\s+(.+)\s*/
let reg2 = /\s*\(\s*([^\,\s]+?)\s*\,\s*([^\,\s]+?)\s*\)\s*(?:in|of)\s+(.+)\s*/
let item, index, list;
let matches1 = nodeValue.match(reg1);
let matches2 = nodeValue.match(reg2);
......@@ -203,14 +203,11 @@ _.handleVUEClassNodes = function (options) {
_.webVUEClassNodes = function (options) {
let { classNodes, attributes, extraClass } = options;
if (classNodes.length === 0) {
attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
extraClass && attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
} else if (classNodes.length === 1) { // 可能是动态class或者静态class
classNodes.forEach((itemNode) => {
if (t.isJSXNamespacedName(itemNode.name)) { // 动态的
attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
// itemNode.name.name = `:${itemNode.name.name}`
// let newClassNodeValue = utils.getReactiveValue(itemNode.value.value);
// itemNode.value.value = `${newClassNodeValue}`;
extraClass && attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
} else {// 静态的
itemNode.value.value = `${itemNode.value.value} ${extraClass}`
}
......@@ -218,9 +215,7 @@ _.webVUEClassNodes = function (options) {
} else if (classNodes.length === 2) {
classNodes.forEach((itemNode) => {
if (t.isJSXNamespacedName(itemNode.name)) { // 动态的
// itemNode.name.name = `:${itemNode.name.name}`
// let newClassNodeValue = utils.getReactiveValue(itemNode.value.value);
// itemNode.value.value = `${newClassNodeValue}`;
} else { // 静态的
itemNode.value.value = `${itemNode.value.value} ${extraClass}`
}
......@@ -230,13 +225,11 @@ _.webVUEClassNodes = function (options) {
_.weexVUEClassNodes = function (options) {
let { classNodes, attributes, extraClass } = options;
if (classNodes.length === 0) {
attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
extraClass && attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
} else if (classNodes.length === 1) { // 可能是动态class或者静态class
classNodes.forEach((itemNode) => {
if (t.isJSXNamespacedName(itemNode.name)) { // 动态的
attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
// itemNode.value.value = `[${newClassNodeValue}]`;
extraClass && attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)));
let newClassNodeValue = utils.trimCurly(itemNode.value.value);
itemNode.value.value = `${weexMixins.weexClassProxy}((${newClassNodeValue}))`
} else {// 静态的
......@@ -259,8 +252,7 @@ _.weexVUEClassNodes = function (options) {
_.miniappVUEClassNodes = function (options) {
let { classNodes, attributes, extraClass } = options;
if (classNodes.length === 0) {
// t.jsxAttribute(t.jsxIdentifier('data-cmlref'),t.stringLiteral(value))
attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
extraClass && attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
} else if (classNodes.length === 1) { // 可能是动态class或者静态class
classNodes.forEach((itemNode) => {
// itemNode.value.value = `${itemNode.value.value} ${extraClass}`
......@@ -293,3 +285,43 @@ _.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"
}
_.isOriginTagOrNativeComp = function(tagName, options) {
let usedComponentInfo = (options.usingComponents || []).find((item) => item.tagName === tagName)
let isNative = usedComponentInfo && usedComponentInfo.isNative;
let isOrigin = (tagName && typeof tagName === 'string' && tagName.indexOf('origin-') === 0);
if (isOrigin || isNative) {
return true
}
return false;
}
// 判断是否是原生组件
_.isNativeComp = function(tagName, options) {
let usedComponentInfo = (options.usingComponents || []).find((item) => item.tagName === tagName)
let isNative = usedComponentInfo && usedComponentInfo.isNative;
return isNative
}
// 判断是否是组件,不包括第三方原生组件
// {button: "cml-buildin-button"},
_.isNotNativeComponent = function(tagName, options) {
let usingComponents = options.usingComponents || [];
let buildInComponents = options.buildInComponents || {};
let isComponent = usingComponents.find((comp) =>
((comp.tagName === tagName) && !comp.isNative)
) || Object.values(buildInComponents).includes(tagName);
return isComponent
}
......@@ -52,6 +52,8 @@ exports.compileTemplateForCml = function (source, type, options) {
source = processTemplate.postParseMustache(source)
// 后置处理:用于处理 \u ,便于解析unicode 中文
source = processTemplate.postParseUnicode(source);
// 后置处理,所有的 __CML_NATIVE_EVENTS__ ==> .native
source = processTemplate.transformNativeEvent(source)
return {
source,
usedBuildInTagMap: options.usedBuildInTagMap
......
......@@ -53,6 +53,8 @@ exports.compileTemplateForVue = function (source, type, options) {
source = processTemplate.postParseMustache(source)
// 后置处理:用于处理 \u ,便于解析unicode 中文
source = processTemplate.postParseUnicode(source);
// 后置处理,所有的 __CML_NATIVE_EVENTS__ ==> .native
source = processTemplate.transformNativeEvent(source)
return {
source,
usedBuildInTagMap: options.usedBuildInTagMap
......
......@@ -13,16 +13,19 @@ const hash = require('hash-sum');
<view><text class="cls1 cls2 {{true ? 'cls1':'cls2'}}">test class1</text></view>
*/
parseClass.tap('web-cml', (args) => {
let { node, type, options: {lang} } = args;
let { node, type, options: {lang, isInjectBaseStyle} } = args;
if (lang === 'cml' && type === 'web') {
let tagName = node.openingElement.name.name;
let attributes = node.openingElement.attributes;
let classNodes = attributes.filter((attr) => // 如果没有符合条件的classNodes则返回一个空数组
attr.name.name === 'class'
);
let extraClass = ` cml-base cml-${tagName}`;
let extraClass = '';
if (isInjectBaseStyle) {
extraClass = ` cml-base cml-${tagName}`;
}
if (classNodes.length === 0) {
attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
extraClass && attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
} else if (classNodes.length === 1) {
classNodes.forEach((itemNode) => {
const dealedClassNodeValue = `${itemNode.value.value} ${extraClass}`;
......@@ -41,16 +44,19 @@ parseClass.tap('web-cml', (args) => {
})
parseClass.tap('weex-cml', (args) => {
let { node, type, options: {lang} } = args;
let { node, type, options: {lang, isInjectBaseStyle} } = args;
if (lang === 'cml' && type === 'weex') {
let tagName = node.openingElement.name.name;
let attributes = node.openingElement.attributes;
let classNodes = attributes.filter((attr) => // 如果没有符合条件的classNodes则返回一个空数组
attr.name.name === 'class'
);
let extraClass = ` cml-base cml-${tagName}`;
let extraClass = '';
if (isInjectBaseStyle) {
extraClass = ` cml-base cml-${tagName}`;
}
if (classNodes.length === 0) {
attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
extraClass && attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
} else if (classNodes.length === 1) {
classNodes.forEach((itemNode) => {
if (utils.isMustacheReactive(itemNode.value.value)) { // 动态的
......@@ -73,7 +79,7 @@ parseClass.tap('weex-cml', (args) => {
})
parseClass.tap('wx-alipay-baidu-cml', (args) => {
let { node, type, options: {lang, filePath, usingComponents} } = args;
let { node, type, options: {lang, filePath, usingComponents, isInjectBaseStyle} } = args;
if (lang === 'cml' && (type === 'wx' || type === 'alipay' || type === 'baidu')) {
let tagName = node.openingElement.name.name;
let attributes = node.openingElement.attributes;
......@@ -81,16 +87,27 @@ parseClass.tap('wx-alipay-baidu-cml', (args) => {
attr.name.name === 'class'
);
let isUsingComponents = (usingComponents || []).find((comp) => comp.tagName === tagName);
let extraClass = ` cml-base cml-${tagName}`;
if (isUsingComponents && (type === 'wx' || type === 'baidu')) {
extraClass = ` cml-view cml-${tagName}`;
let extraClass = '';
if ((type === 'wx' || type === 'baidu')) {
if (isInjectBaseStyle) {
extraClass = ` cml-base cml-${tagName}`;
if (isUsingComponents && (type === 'wx' || type === 'baidu')) {
extraClass = ` cml-view cml-${tagName}`;
}
}
}
if (type === 'alipay') {
let randomClassName = hash(filePath);
extraClass = `${extraClass} cml-${randomClassName}`
if (isInjectBaseStyle) {
extraClass = ` cml-base cml-${tagName}`;
extraClass = `${extraClass} cml-${randomClassName}`
} else {
extraClass = `${extraClass} cml-${randomClassName}` // 不插入全局样式的时候也要插入样式隔离
}
}
if (classNodes.length === 0) {
attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
extraClass && attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral(extraClass)))
} else if (classNodes.length === 1) {
classNodes.forEach((itemNode) => {
const dealedClassNodeValue = `${itemNode.value.value} ${extraClass}`
......@@ -104,49 +121,63 @@ parseClass.tap('wx-alipay-baidu-cml', (args) => {
})
// vue语法:class='cls1 cls2' :class="true ? 'cls1 cls2 cls3' : 'cls4 cls5 cls6'"
parseClass.tap('web-vue', (args) => {
let { node, type, options: {lang} } = args;
let { node, type, options: {lang, isInjectBaseStyle} } = args;
if (lang === 'vue' && type === 'web') {
let tagName = node.openingElement.name.name;
let attributes = node.openingElement.attributes;
let classNodes = attributes.filter((attr) => // 如果没有符合条件的classNodes则返回一个空数组
attr.name.name === 'class' || attr.name.name.name === 'class'
);
let extraClass = ` cml-base cml-${tagName}`;
let extraClass = '';
if (isInjectBaseStyle) {
extraClass = ` cml-base cml-${tagName}`;
}
utils.handleVUEClassNodes({classNodes, attributes, extraClass, lang, type})
}
})
parseClass.tap('weex-vue', (args) => {
let { node, type, options: {lang} } = args;
let { node, type, options: {lang, isInjectBaseStyle} } = args;
if (lang === 'vue' && type === 'weex') {
let tagName = node.openingElement.name.name;
let attributes = node.openingElement.attributes;
let classNodes = attributes.filter((attr) => // 如果没有符合条件的classNodes则返回一个空数组
attr.name.name === 'class' || attr.name.name.name === 'class'
);
let extraClass = ` cml-base cml-${tagName}`;
let extraClass = '';
if (isInjectBaseStyle) {
extraClass = ` cml-base cml-${tagName}`;
}
utils.handleVUEClassNodes({classNodes, attributes, extraClass, lang, type})
}
})
parseClass.tap('wx-alipay-baidu-vue', (args) => {
let { node, type, options: {lang, filePath, usingComponents} } = args;
let { node, type, options: {lang, filePath, usingComponents, isInjectBaseStyle} } = args;
if (lang === 'vue' && (type === 'wx' || type === 'alipay' || type === 'baidu')) {
let tagName = node.openingElement.name.name;
let attributes = node.openingElement.attributes;
let classNodes = attributes.filter((attr) => // 如果没有符合条件的classNodes则返回一个空数组
attr.name.name === 'class' || attr.name.name.name === 'class'
);
let extraClass = ` cml-base cml-${tagName}`;
let isUsingComponents = (usingComponents || []).find((comp) => comp.tagName === tagName);
if (isUsingComponents && (type === 'wx' || type === 'baidu')) {
extraClass = ` cml-view cml-${tagName}`;
let extraClass = '';
if ((type === 'wx' || type === 'baidu')) {
if (isInjectBaseStyle) {
extraClass = ` cml-base cml-${tagName}`;
if (isUsingComponents && (type === 'wx' || type === 'baidu')) {
extraClass = ` cml-view cml-${tagName}`;
}
}
}
if (type === 'alipay') {
let randomClassName = hash(filePath);
extraClass = `${extraClass} cml-${randomClassName}`
if (isInjectBaseStyle) {
extraClass = ` cml-base cml-${tagName}`;
extraClass = `${extraClass} cml-${randomClassName}`
} else {
extraClass = `${extraClass} cml-${randomClassName}` // 不插入全局样式的时候也要插入样式隔离
}
}
utils.handleVUEClassNodes({classNodes, attributes, extraClass, lang, type: 'miniapp'})
}
......
......@@ -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)))
......
......@@ -14,24 +14,40 @@ parseEvent.tap('web-weex', (args) => {
if (type === 'web' || type === 'weex') {
let container = path.container;
let value = container.value;
let isStopBubble = false;// 默认都是冒泡
let isStopBubble = false;// 默认都是冒泡
if (node.namespace.name === 'c-catch') {
node.name.name === 'tap' && (node.name.name = 'click');
isStopBubble = true;
// node.name.name = `${node.name.name}.stop`;
} else {
node.name.name === 'tap' && (node.name.name = 'click');
isStopBubble = false;
}
node.namespace.name = 'v-on';
// ====这里作用是阻止对 origin-tag标签的事件进行代理
let jsxElementNodePath = path.findParent((path) => t.isJSXElement(path.node));
let jsxElementNode = jsxElementNodePath.node;
let usedComponentInfo = (options.usingComponents || []).find((item) => item.tagName === jsxElementNode.openingElement.name.name)
let isNative = usedComponentInfo && usedComponentInfo.isNative;
let isOrigin = (jsxElementNode.openingElement.name && typeof jsxElementNode.openingElement.name.name === 'string' && jsxElementNode.openingElement.name.name.indexOf('origin-') === 0);
if (isOrigin || isNative) {
return;
let tagName = jsxElementNode.openingElement.name.name;
let isOriginOrNative = utils.isOriginTagOrNativeComp(tagName, options);
let isNotNativeComp = utils.isNotNativeComponent(tagName, options);
let isNativeComp = utils.isNativeComp(tagName, options);
let originEvents = ['click', 'touchstart', 'touchmove', 'touchend', 'touchcancel'];
if (type === 'web') { // cml标签或者cml组件
// web端非第三方UI库的上的tap和click都处理成tap;
if (isNotNativeComp || tagName === 'component') { // cml组件上的tap和click都处理成 click.native
node.name.name === 'tap' && (node.name.name = 'click');
originEvents.includes(node.name.name) && (node.name.name = `${node.name.name}__CML_NATIVE_EVENTS__`);
} else if (isNativeComp) {
// native组件不处理名字
} else { // 普通标签都处理成tap
node.name.name === 'click' && (node.name.name = 'tap');
}
}
if (type === 'weex') { // weex端 还是原来的逻辑
node.name.name === 'tap' && (node.name.name = 'click');
if (isNotNativeComp || tagName === 'component') {
originEvents.includes(node.name.name) && (node.name.name = `${node.name.name}__CML_NATIVE_EVENTS__`);
}
}
if (isOriginOrNative) {
return // 原生标签和原生组件直接不解析
}
// ====这里作用是阻止对 origin-tag标签的事件进行代理
......@@ -65,7 +81,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);
......@@ -78,38 +94,24 @@ parseEvent.tap('wx-baidu', (args) => {
// ====这里作用是阻止对 origin-tag标签的事件进行代理
let jsxElementNodePath = path.findParent((path) => t.isJSXElement(path.node));
let jsxElementNode = jsxElementNodePath.node;
let usedComponentInfo = (options.usingComponents || []).find((item) => item.tagName === jsxElementNode.openingElement.name.name)
let isNative = usedComponentInfo && usedComponentInfo.isNative;
let isOrigin = (jsxElementNode.openingElement.name && typeof jsxElementNode.openingElement.name.name === 'string' && jsxElementNode.openingElement.name.name.indexOf('origin-') === 0);
if (isOrigin || isNative) {
return;
let tagName = jsxElementNode.openingElement.name.name
if (utils.isOriginTagOrNativeComp(tagName, options)) {
return // 原生标签和原生组件直接不解析
}
// ====这里作用是阻止对 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 +123,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);
......@@ -134,37 +138,24 @@ parseEvent.tap('alipay', (args) => {
// ====这里作用是阻止对 origin-tag标签的事件进行代理
let jsxElementNodePath = path.findParent((path) => t.isJSXElement(path.node));
let jsxElementNode = jsxElementNodePath.node;
let usedComponentInfo = (options.usingComponents || []).find((item) => item.tagName === jsxElementNode.openingElement.name.name)
let isNative = usedComponentInfo && usedComponentInfo.isNative;
let isOrigin = (jsxElementNode.openingElement.name && typeof jsxElementNode.openingElement.name.name === 'string' && jsxElementNode.openingElement.name.name.indexOf('origin-') === 0);
if (isOrigin || isNative) {
return;
let tagName = jsxElementNode.openingElement.name.name
if (utils.isOriginTagOrNativeComp(tagName, options)) {
return // 原生标签和原生组件直接不解析
}
// ====这里作用是阻止对 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}']}}`)))
}
}
}
......
......@@ -53,7 +53,7 @@ describe('process-template', function() {
});
describe('preParseVueEvent', function() {
it('support @ v-on', function() {
expect(processTemplate.preParseVueEvent(`<view v-on:touch="handle1" @click="handle2"></view>`)).to.equal(`<view c-bind:touch="handle1" c-bind:tap="handle2"></view>`)
expect(processTemplate.preParseVueEvent(`<view v-on:touch="handle1" @tap="handle2"></view>`)).to.equal(`<view c-bind:touch="handle1" c-bind:tap="handle2"></view>`)
})
});
describe('preParseGtLt', function() {
......@@ -131,4 +131,9 @@ describe('process-template', function() {
expect(processTemplate._operationGtLt(`{{value}}`)).to.equal(`{{value}}`)
})
});
describe('transformNativeEvent', function() {
it('transform transformNativeEvent', function() {
expect(processTemplate.transformNativeEvent(`<view v-on:click__CML_NATIVE_EVENTS__="handleClick"=></view>`)).to.equal(`<view v-on:click.native="handleClick"=></view>`)
})
});
})
const utils = require('../../src/common/utils');
var expect = require('chai').expect;
let options = {lang: 'cml',
buildInComponents: {button: "cml-buildin-button", 'c-tab-item': 'cml-buildin-tab'},
filePath: '/User/Jim-W/didi/component/button.cml',
cmss: {
rem: true,
scale: 0.5,
remOptions: {
// base on 750px standard.
rootValue: 75,
// to leave 1px alone.
minPixelValue: 1.01
},
autoprefixOptions: {
browsers: ['> 0.1%', 'ios >= 8', 'not ie < 12']
}
},
usingComponents: [{
tagName: 'thirdComp1',
refUrl: '/path/to/ref1',
filePath: 'path/to/real1',
isNative: true
}, {
tagName: 'thirdComp2',
refUrl: '/path/to/ref2',
filePath: 'path/to/real2',
isNative: false
}]
};
describe('utils', function() {
describe('trimCurly', function() {
it('trim {{variable}} to variable', function() {
......@@ -110,5 +138,67 @@ 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`);
})
});
describe('isOriginTagOrNativeComp', function() {
it('isOriginTagOrNativeComp-nativecomp', function() {
let result = utils.isOriginTagOrNativeComp('thirdComp1', options);
expect(result).to.be.ok;
});
it('isOriginTagOrNativeComp-origin-tag', function() {
let result = utils.isOriginTagOrNativeComp('origin-tag', options);
expect(result).to.be.ok;
});
it('isOriginTagOrNativeComp-not-nativecomp', function() {
let result = utils.isOriginTagOrNativeComp('thirdComp2', options);
expect(result).to.be.not.ok;
});
it('isusualComp', function() {
let result = utils.isOriginTagOrNativeComp('view', options);
expect(result).to.be.not.ok;
});
});
describe('isNativeComp', function() {
it('isOriginTagOrNativeComp-nativecomp', function() {
let result = utils.isOriginTagOrNativeComp('thirdComp1', options);
expect(result).to.be.ok;
});
it('isOriginTagOrNativeComp-origin-tag', function() {
let result = utils.isNativeComp('origin-tag', options);
expect(result).to.be.not.ok;
});
it('isOriginTagOrNativeComp-not-nativecomp', function() {
let result = utils.isNativeComp('thirdComp2', options);
expect(result).to.be.not.not.ok;
});
it('isusualComp', function() {
let result = utils.isNativeComp('view', options);
expect(result).to.be.not.ok;
});
});
// 不是对应端的原生组件
describe('isNotNativeComponent', function() {
it('isNotNativeComponent-nativecomp', function() {
let result = utils.isNotNativeComponent('cml-buildin-button', options);
expect(result).to.be.ok;
});
it('isNotNativeComponent-not-nativecomp', function() {
let result = utils.isNotNativeComponent('thirdComp1', options);
expect(result).to.be.not.ok;
});
it('isNotNativeComponent', function() {
let result = utils.isNotNativeComponent('thirdComp2', options);
expect(result).to.be.ok;
});
it('isNotNativeComponent', function() {
let result = utils.isNotNativeComponent('view', options);
console.log('result-isNotNativeComponent', result)
expect(result).to.be.not.ok;
});
});
})
const compileTemplate = require('../src/index.js');
const source = `<view c-bind:click="handleClick( )">事件测试-内联事件</view>`
const source = `<view class="demo-com" c-bind:click="handleClick" c-bind:tap="handleTap">
<thirdComp2 c-bind:click="handleClick" c-bind:tap="handleTap">index-handleTouchStart</thirdComp2>
<cube-button c-bind:click="handleClick" c-bind:tap="handleTap">index-handleTouchStart</cube-button>
</view>`
// <view><text :class="{{true? 'bg-green':''}}" >fafafa</text></view>
// <view><text :class="true? 'bg-green':''" >fafafa</text></view>
//
......@@ -7,6 +10,7 @@ const source = `<view c-bind:click="handleClick( )">事件测试-内联事件</
let options = {lang: 'cml',
filePath: '/Users/didi/components.cml',
buildInComponents: {button: "cml-buildin-button"},
isInjectBaseStyle: false,
cmss: {
rem: true,
scale: 0.5,
......@@ -24,7 +28,7 @@ let options = {lang: 'cml',
tagName: 'cube-button',
refUrl: '/path/to/ref1',
filePath: 'path/to/real1',
isNative: false
isNative: true
}, {
tagName: 'thirdComp2',
refUrl: '/path/to/ref2',
......@@ -33,13 +37,13 @@ let options = {lang: 'cml',
}]
};
console.log('before-compile', source);
// let result_web = compileTemplate(source, 'web', options);
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_alipay = compileTemplate(source, 'alipay', options);
// console.log('result_web', result_web)
// 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_alipay', result_alipay)
// console.log('result_wx', result_wx)
// console.log('result_baidu', result_baidu)
// console.log('result_alipay', result_alipay)
......@@ -10,6 +10,7 @@ const expect = require('chai').expect;
let options = {lang: 'cml',
buildInComponents: {button: "cml-buildin-button"},
filePath: '/User/Jim-W/didi/component/button.cml',
isInjectBaseStyle: true,
cmss: {
rem: true,
scale: 0.5,
......@@ -150,11 +151,11 @@ describe('parse-template-cml', function() {
let callback = parseTemplate.parseEventListener;
let result = compileTemplate(source, 'web', options, callback);
it('test-event-transform', function() {
expect(result).to.equal(`<view><view v-on:click="_cmlEventProxy($event,\'tapHandle\',false)"></view></view>`)
expect(result).to.equal(`<view><view v-on:tap="_cmlEventProxy($event,'tapHandle',false)"></view></view>`)
});
// 原生组件事件不进行代理
it('test-origin-tag-event-transform', function() {
expect(compileTemplate(originSource, 'web', options, callback)).to.equal(`<view><origin-tag v-on:click="handleClick"></origin-tag><thirdComp1 v-on:click="handleClick"></thirdComp1><thirdComp2 v-on:click="_cmlEventProxy($event,\'handleClick\',false)"></thirdComp2></view>`)
expect(compileTemplate(originSource, 'web', options, callback)).to.equal(`<view><origin-tag v-on:tap="handleClick"></origin-tag><thirdComp1 v-on:click="handleClick"></thirdComp1><thirdComp2 v-on:click__CML_NATIVE_EVENTS__="_cmlEventProxy($event,'handleClick',false)"></thirdComp2></view>`)
});
});
describe('parseEventListener-wx-baidu', function() {
......@@ -164,10 +165,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 +178,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
......
......@@ -9,6 +9,7 @@ const expect = require('chai').expect;
let options = {lang: 'vue',
buildInComponents: {button: "cml-buildin-button"},
filePath: '/User/Jim-W/didi/component/button.cml',
isInjectBaseStyle: true,
cmss: {
rem: true,
scale: 0.5,
......
......@@ -123,9 +123,8 @@ function bindEvents(evts, el, attrs, cmlEvents, appearAttached) {
* - click -> cml$tap
* - scroll -> cml$scroll
*/
if (evts.click) {
evts['cml$tap'] = extend({}, evts.click);
delete evts.click;
if (evts.tap) { //这里取到tap事件进行代理,而不是原来的click事件,区分了tap和click
evts['cml$tap'] = extend({}, evts.tap);
if (!hasBubbleParent) {
evts.click = {
value: '$stopOuterA'
......
const commonEvents = ['tap', 'touchstart', 'touchmove', 'touchend'];
const commonEvents = ['tap', 'click', 'touchstart', 'touchmove', 'touchend'];
module.exports.isCommonEvent = function(eventName) {
return ~commonEvents.indexOf(eventName);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册