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

Master bugfix (#47)

* window下数组目录多态校验报错

* bug-fix c-show component-is {{}}

* add path

* fix c-model space bug

* add keywords

* babelpolyfill

* fix 单元测试

* 模板编译单元测试

* bugfix: using builtin components to check allowed tags

* 修复window上删除小程序文件夹失败

* window删除小程序文件夹

* lines

* lines

* css-loader 单元测试

* lines

* packages添加chameleon-tool

* add comment

* 单元测试

* delete debugger

* update lerna.json

* add package.json

* 单测完善

* c-animation 代理事件值得trim,小程序端动态style cpx->rpx修复

* 增加配置重置

* v-animation,cml和vue语法下整体单测的完善

* 修复按需加载某些case下报错的问题

* vue语法下ref加强,整体单元测试增加

* 继续完善单测到90%

* 继续完善单测到90%

* unit test

* preview

* 异步删除dist目录

* 异步删除dist

* remove denpendence

* Revert "增加配置重置"

This reverts commit ba3c84cf.

* Revert "add package.json"

This reverts commit 1d95e3d8.

* Revert "bugfix: using builtin components to check allowed tags"

This reverts commit ebd8a429.
上级 85d141f3
......@@ -188,7 +188,13 @@ class Plugin {
if (pluginState.libraryObjs[node.object.name]) {
// antd.Button -> _Button
path.replaceWith(this.importMethod(node.property.name, file, pluginState));
if (node.property.type === 'Identifier') {
//antd.Button
path.replaceWith(this.importMethod(node.property.name, file, pluginState));
} else if (node.property.type === 'Literal') {
//antd['Button']
path.replaceWith(this.importMethod(node.property.value, file, pluginState));
}
} else if (pluginState.specified[node.object.name]) {
node.object = this.importMethod(pluginState.specified[node.object.name], file, pluginState);
}
......
// 静态编译和运行时 web和小程序端对lines属性特殊处理
module.exports = function(linesNumber) {
// 作为一个属性注意最后不能添加分号
return `display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: ${linesNumber}; overflow: hidden`
}
const cpx = require('../postcss/cpx.js');
const weexPlus = require('../postcss/weex-plus');
const postcss = require('postcss');
module.exports = function(source, options = {}) {
options.cpxType = 'rpx';
return cpx(source, options);
return postcss([cpx(options), weexPlus()]).process(source).css;
}
const rem = require('../postcss/rem.js');
const cpx = require('../postcss/cpx.js');
const postcss = require('postcss');
const px2rem = require('postcss-plugin-px2rem');
const weexPlus = require('../postcss/weex-plus');
module.exports = function(source, options = {}) {
if (options.rem === true) {
return rem(source, options);
return postcss([px2rem(options.remOptions), weexPlus()]).process(source).css;
} else {
options.cpxType = 'scale';
return cpx(source, options);
return postcss([cpx(options), weexPlus()]).process(source).css;
}
}
const autoprefixer = require('autoprefixer');
const postcss = require('postcss');
module.exports = function (content, options) {
let ret = postcss(autoprefixer(options.autoprefixOptions)).process(content).css;
return ret;
}
const postcss = require('postcss');
// 非rem的cpx处理,rem的利用postcss-plugin-px2rem插件即可实现
let scalePlugin = postcss.plugin('postcss-plugin-cpx-scale', function (options) {
module.exports = postcss.plugin('postcss-plugin-cpx', function (options) {
// parseType 参数决定cpx的转换
let { unitPrecision = 5, scale = 1, cpxType = 'scale'} = options;
const pxRegex = /(\d*\.?\d+)cpx/gi;
......@@ -40,8 +40,3 @@ let scalePlugin = postcss.plugin('postcss-plugin-cpx-scale', function (options)
});
};
});
module.exports = function (content, options) {
let ret = postcss(scalePlugin(options)).process(content).css;
return ret;
}
const pxtorem = require('postcss-plugin-px2rem');
const postcss = require('postcss');
module.exports = function (content, options) {
let ret = postcss(pxtorem(options.remOptions)).process(content).css;
return ret;
}
// 为web和小程序提供编译weex为标准的特殊样式
const postcss = require('postcss');
module.exports = postcss.plugin('postcss-weex-plus', function(options) {
return (root, result) => {
root.walkDecls((decl, i) => {
if (decl.prop === 'lines') {
const decllist = [
postcss.decl({prop: 'overflow', value: 'hidden'}),
postcss.decl({prop: 'text-overflow', value: 'ellipsis'}),
postcss.decl({prop: 'display', value: '-webkit-box'}),
postcss.decl({prop: '-webkit-line-clamp', value: decl.value}),
postcss.decl({prop: '-webkit-box-orient', value: 'vertical'})
];
decl.parent.append(...decllist)
}
// decl.parent.removeChild(decl);
})
}
})
const utils = require('../utils');
const lines = require('../handler/lines');
// 运行时的cpx2rpx不能使用postcss处理,因为$cmlStyle方法用到了该方法,在运行时使用postcss 会出现Cannot find module "fs"的错误
module.exports = function(content) {
content = utils.disappearCssComment(content);
......@@ -16,6 +16,9 @@ module.exports = function(content) {
};
})
.map(declaration => {
if (declaration.property === 'lines') {
return lines(declaration.value);
}
declaration.value = handle(declaration.value);
return declaration.property + ':' + declaration.value;
})
......
/** 提供编译时样式处理的方法 */
// 运行时不能使用postcss 体积过大
const lines = require('../handler/lines');
const utils = require('../utils');
module.exports = function(content, options) {
if (typeof options === 'string') {
options = JSON.parse(utils.singlequot2doublequot(options))
......@@ -24,6 +25,9 @@ module.exports = function(content, options) {
};
})
.map(declaration => {
if (declaration.property === 'lines') {
return lines(declaration.value);
}
declaration.value = handle(declaration.value, options);
return declaration.property + ':' + declaration.value;
})
......
......@@ -17,4 +17,97 @@ describe('parse/weex', function() {
})
describe('parse/weex', function() {
let css = `
.a {
border: solid 1px red;
}
.b {
border: dotted 0 rgb(255,255, 255);
}
.c {
border-left: solid 1px #ccc;
}
`;
it('border', function() {
let result = parseCss(css);// body {width:1rem;}
console.log(result);
expect(result).to.equal(`.a {\n border-style: solid;\n border-width: 1px;\n border-color: #ff0000;\n}\n\n.b {\n border-style: dotted;\n border-width: 0;\n border-color: rgb(255,255,255);\n}\n\n.c {\n border-left-style: solid;\n border-left-width: 1px;\n border-left-color: #ccc;\n}`);
})
})
describe('parse/weex', function() {
let css = `
.a {
margin-left: 10px;
}
.b {
margin: 10px;
}
.c {
margin: 10px 20px;
}
.d {
margin: 10px 20px 10px;
}
.e {
margin: 10px 20px 5px 15px;
}
`;
it('margin', function() {
let result = parseCss(css);// body {width:1rem;}
console.log(result);
expect(result).to.equal(`.a {\n margin-left: 10px;\n}\n\n.b {\n margin-top: 10px;\n margin-right: 10px;\n margin-bottom: 10px;\n margin-left: 10px;\n}\n\n.c {\n margin-top: 10px;\n margin-right: 20px;\n margin-bottom: 10px;\n margin-left: 20px;\n}\n\n.d {\n margin-top: 10px;\n margin-right: 20px;\n margin-bottom: 10px;\n margin-left: 20px;\n}\n\n.e {\n margin-top: 10px;\n margin-right: 20px;\n margin-bottom: 5px;\n margin-left: 15px;\n}`);
})
})
describe('parse/weex', function() {
let css = `
.a {
padding-left: 10px;
}
.b {
padding: 10px;
}
`;
it('padding', function() {
let result = parseCss(css);// body {width:1rem;}
console.log(result);
expect(result).to.equal(`.a {\n padding-left: 10px;\n}\n\n.b {\n padding-top: 10px;\n padding-right: 10px;\n padding-bottom: 10px;\n padding-left: 10px;\n}`);
})
})
describe('parse/weex', function() {
let css = `
.a {
background: #ccc
url(img.png)
no-repeat
scroll
center center / 50%
content-box border-box;
}
.b {
background: url(img.png) #ccc;
}
`;
it('background', function() {
let result = parseCss(css);// body {width:1rem;}
console.log(result);
expect(result).to.equal(`.a {\n background-color: #ccc;\n background-position: center center;\n background-size: 50%;\n background-repeat: no-repeat;\n background-origin: content-box;\n background-clip: border-box;\n background-attachment: scroll;\n background-image: url(img.png);\n}\n\n.b {\n background-color: #ccc;\n background-image: url(img.png);\n}`);
})
})
const parseCss = require('../../postcss/rem.js');
const expect = require('chai').expect;
let source = `width:75cpx;font-size:26cpx;/* height:200cpx; */`;
describe('postcss/rem', function() {
it('web-cssvalue : if options.rem to be truthy ,parse cpx to rem', function() {
let options = {
rem: true,
scale: 0.5,
remOptions: {
// base on 750px standard.
rootValue: {cpx: 75},
// to leave 1px alone.
minPixelValue: 1.01
}
}
let result = parseCss(source, options);
expect(/1rem/.test(result)).to.be.ok;
})
})
var postcss = require('postcss');
var weexPlus = require('../../postcss/weex-plus');
var content = `
.class1 {
lines: 1;
}
`
const expect = require('chai').expect;
describe('postcss/weex-plus', function() {
it('convert lines', function() {
let ret = postcss(weexPlus()).process(content).css;
console.log(ret)
expect(ret).to.equal(`\n.class1 {\n lines: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 1;\n -webkit-box-orient: vertical;\n}\n`);
})
})
......@@ -7,6 +7,11 @@ describe('proxy/miniapp', function() {
let result = parseCss(source);
expect(/75rpx/.test(result)).to.be.ok;
})
it('lines', function() {
let result = parseCss('lines:1;');
expect(result).to.equal('display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; overflow: hidden');
})
})
......@@ -31,6 +31,12 @@ describe('parse/web', function() {
expect(/1rem/.test(result1)).to.be.ok;
expect(/37.5px/.test(result2)).to.be.ok;
})
it('lines', function() {
let result = parseCss('lines:1;');
expect(result).to.equal('display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; overflow: hidden');
})
})
const parseCss = require('../../transform/weex.js');
const expect = require('chai').expect;
let source = `width:75cpx;border:1cpx solid red;`;
describe('parse/weex', function() {
it('if options.rem to be truthy ,parse px to rem,else multiply the px value by options.scale', function() {
let result = parseCss.parse(source);// body {width:1rem;}
console.log(result);
expect(/75px/.test(result)).to.be.ok;
expect(/1px/.test(result)).to.be.ok;
})
})
......@@ -73,7 +73,7 @@ exports.preParseGtLt = function(content) {
return exports._operationGtLt(match);
})
}
// 预处理 标签内的 {{item.id}} 这种语法jsx无法识别,转化为 _cml{item.id}lmc_
exports.preParseMustache = function (content) {
let reg = />([\s\S]*?)<[a-zA-Z\/\-_]+?/g;
return content.replace(reg, function (match, key) {
......@@ -103,8 +103,8 @@ exports.preParseAnimation = function(source, type) {
traverse(ast, {
enter(path) {
let node = path.node;
if (t.isJSXAttribute(node) && node.name.name === 'c-animation') {
let value = utils.trimCurly(node.value.value);
if (t.isJSXAttribute(node) && (node.name.name === 'c-animation' || node.name.name === 'v-animation')) {
let value = utils.trimCurly(node.value.value).trim();
path.insertAfter(t.jsxAttribute(t.jsxIdentifier(`c-bind:transitionend`), t.stringLiteral(`_animationCb('${value}',$event)`)))
}
}
......
......@@ -163,15 +163,18 @@ _.transformWxDynamicStyleCpxToRpx = function(value) {
return value;
}
_.transformNotInMustacheCpxToRpx = function(value) {
// 第一步
let isNotMustacheCpxToRpxReg = /}}[^{}]*?(cpx)/g;
return value.replace(isNotMustacheCpxToRpxReg, (match, key) => {
if (key === 'cpx') {
return match.replace(/cpx/, 'rpx')
let isNotMustacheCpxToRpxReg = /([^{}]+)?(\{\{[^{}]+\}\})?/g;
let temp = '';
const matches = value.match(isNotMustacheCpxToRpxReg);
value.replace(isNotMustacheCpxToRpxReg, (match, $1, $2, $3) => {
if ($1) {
temp += $1.replace(/cpx/g, 'rpx');
}
if ($2) {
temp += $2;
}
return match;
});
return temp
}
_.transformMustacheCpxToRpx = function(source) {
const ast = babylon.parse(source, {
......
......@@ -105,10 +105,10 @@ exports.parseTextContentStatement = function parseTextContentStatement(path, typ
// parseTextContent.call({path,type,node})
// }
}
exports.parseRefStatement = function parseRefStatement(path, type) {
exports.parseRefStatement = function parseRefStatement(path, type, options) {
let node = path.node;
if (t.isJSXAttribute(node) && node.name.name === 'ref') {
parseRef.call({path, type, node});
if (t.isJSXAttribute(node) && (node.name.name === 'ref' || node.name.name.name === 'ref')) {
parseRef.call({path, type, node, options});
}
}
// web weex wx ...只处理cml语法 c-if c-else-if c-else
......
......@@ -37,7 +37,7 @@ parseCondition.tap('baidu', (args) => {
let targetCondition = conditionMap[currentCondition] && conditionMap[currentCondition][type];
if (targetCondition && currentCondition !== targetCondition) {
node.name.name = targetCondition;
node.value.value = utils.trimCurly(node.value.value);
node.value && t.isStringLiteral(node.value) && (node.value.value = utils.trimCurly(node.value.value));
}
}
})
......
......@@ -3,9 +3,9 @@ const t = require('@babel/types');
const { SyncHook } = require("tapable");
let parseRef = new SyncHook(['args'])
parseRef.tap('wx', (args) => {
let { path, type } = args;
if (type === 'wx' || type === 'alipay' || type === 'baidu') {
parseRef.tap('wx-cml', (args) => {
let { path, type, options: { lang } } = args;
if (lang === 'cml' && (type === 'wx' || type === 'alipay' || type === 'baidu')) {
let parentPath = path.parentPath;
let attributes = parentPath.node.attributes;
let idNode = attributes.find((attr) => attr.name.name === 'id');
......@@ -23,6 +23,34 @@ parseRef.tap('wx', (args) => {
}
path.remove();
}
});
parseRef.tap('wx-vue', (args) => {
let { path, type, options: { lang } } = args;
if (lang === 'vue' && (type === 'wx' || type === 'alipay' || type === 'baidu')) {
debugger;
let parentPath = path.parentPath;
let attributes = parentPath.node.attributes;
let idNode = attributes.find((attr) => attr.name.name === 'id');
let refNode = attributes.find((attr) => (attr.name.name === 'ref' || attr.name.name.name === 'ref'));
let isDynamicRef = t.isJSXNamespacedName(refNode.name);
let refNodeValue = isDynamicRef ? `{{${refNode.value.value}}}` : refNode.value.value
let classNode = attributes.find((attr) => attr.name.name === 'class');
if (idNode) {
idNode.value.value = refNodeValue;
} else {
attributes.push(t.jsxAttribute(t.jsxIdentifier('id'), t.stringLiteral(refNodeValue)))
}
if (!classNode) { // 不存在class节点
attributes.push(t.jsxAttribute(t.jsxIdentifier('class'), t.stringLiteral('_cml_ref_lmc_')))
} else {
classNode.value.value = `${classNode.value.value} _cml_ref_lmc_`
}
path.remove();
}
......
......@@ -29,7 +29,7 @@ describe('process-template', function() {
// preParseAnimation
describe('preParseAnimation', function() {
it(`preParse Animation add c-bind:transitionend="_animationCb(...)"`, function() {
expect(processTemplate.preParseAnimation(`<view><text c-animation="{{sss}}" c-bind:transitionend="_animationCb('sss',$event)">click</text></view>;`))
expect(processTemplate.preParseAnimation(`<view><text c-animation="{{ sss }}">click</text></view>`)).to.equal(`<view><text c-animation="{{ sss }}" c-bind:transitionend="_animationCb('sss',$event)">click</text></view>;`)
})
});
describe('postParseMustache', function() {
......@@ -47,4 +47,15 @@ describe('process-template', function() {
expect(processTemplate.postParseUnicode(`\\u`)).to.equal(`%u`)
})
});
describe('postParseOriginTag', function() {
it('transform <origin-tag></origin-tag> to <tag></tag>', function() {
expect(processTemplate.postParseOriginTag(`<view><origin-input></origin-input></view>`)).to.equal(`<view><input></input></view>;`)
})
});
describe('analyzeTemplate', function() {
it('collect which build-in-tag is used in template', function() {
let options = {buildInComponents: {button: "cml-buildin-button"}};
expect(processTemplate.analyzeTemplate(`<view><button></button></view>`, options)).to.include.keys('usedBuildInTagMap')
})
});
})
......@@ -57,19 +57,39 @@ describe('utils', function() {
expect(utils.isOnlySpaceContent(' ')).to.be.ok;
})
});
describe('getReactiveValue', function() {
it('getReactiveValue for vue:such as {{value}} to (value)', function() {
expect(utils.getReactiveValue(`{{value1+value2}}`)).to.equal(`(value1+value2)`);
})
});
describe('getReactiveValue', function() {
it(`getReactiveValue for vue:such as main-{{index}} to 'main-'+(value)`, function() {
expect(utils.getReactiveValue(`main-{{value1+value2}}`)).to.equal(`'main-'+(value1+value2)`);
})
});
describe('getStaticValueFromMixinValue', function() {
it('getStaticValueFromMixinValue for cml', function() {
let result = utils.getStaticValueFromMixinValue(`a b{{true? 'cls1':'cls2'}} {{variable}}b c `);
console.log('result', result)
expect(result).to.equal(`a b b c `);
})
});
describe('getDynamicValuefromMixinValue', function() {
it('getDynamicValuefromMixinValue for cml', function() {
let result = utils.getDynamicValuefromMixinValue(`a b{{true? 'cls1':'cls2'}} {{variable}}b c `);
console.log('result', result)
expect(result).to.equal(`{{true? 'cls1':'cls2'}}{{variable}}`);
})
});
describe('transformWxDynamicStyleCpxToRpx', function() {
it('cml-syanx:transformWxDynamicStyleCpxToRpx for wx dynamic style', function() {
let result = utils.transformWxDynamicStyleCpxToRpx(`height:100cpx;{{'width:'+cpx+'cpx;'+'height:'+cpx2+'cpx;background-color:red;'}}height:200cpx;width:100cpx;`);
expect(result).to.equal(`height:100rpx;{{'width:' + cpx + 'rpx;' + 'height:' + cpx2 + 'rpx;background-color:red;'}}height:200rpx;width:100rpx;`);
})
});
describe('transformWxDynamicStyleCpxToRpx', function() {
it('vue-syanx:ransformWxDynamicStyleCpxToRpx for wx dynamic style', function() {
let result = utils.transformWxDynamicStyleCpxToRpx(`{{'width:'+cpx+'cpx;'+'height:'+cpx2+'cpx;background-color:red'}}`);
expect(result).to.equal(`{{'width:' + cpx + 'rpx;' + 'height:' + cpx2 + 'rpx;background-color:red'}}`);
})
});
})
// cml语法的单元测试
// cml单个语法的单元测试
const babylon = require('babylon');
......@@ -37,6 +37,35 @@ describe('parse-template-cml', function() {
expect(result).to.equal(`<div></div>`)
});
});
describe('afterParseTag', function() { // 各个端的标签转化单元测试不做全覆盖,逻辑相对简单
let source = `<block></block>`;
let options = {lang: 'cml'};
let callback = parseTemplate.afterParseTag;
it('test-after-tag-transform-web-weex', function() {
expect(compileTemplate(source, 'web', options, callback)).to.equal(`<template></template>`)
});
it('test-after-tag-transform-miniapp', function() {
expect(compileTemplate(source, 'wx', options, callback)).to.equal(`<block></block>`)
});
});
describe('parseBuildTag', function() { // 各个端的标签转化单元测试不做全覆盖,逻辑相对简单
let source = `<button></button>`;
let options = {lang: 'cml', buildInComponents: {button: "cml-buildin-button"} };
let callback = parseTemplate.parseBuildTag;
let result = compileTemplate(source, 'web', options, callback);
it('test-build-tag-transform', function() {
expect(result).to.equal(`<cml-buildin-button></cml-buildin-button>`)
});
});
describe('parseTagForSlider', function() {
let source = `<carousel><carousel-item></carousel-item></carousel>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseTagForSlider;
let result = compileTemplate(source, 'wx', options, callback);
it('parseTagForSlider for wx', function() {
expect(result).to.equal(`<swiper><swiper-item></swiper-item></swiper>`)
});
});
// parseRefStatement:仅在所有的小程序端进行处理
describe('parseRefStatement-wx-alipay-baidu', function() {
let source = `<view ref="flag"></view>`;
......@@ -49,68 +78,120 @@ describe('parse-template-cml', function() {
});
// parseConditionalStatement
describe('parseConditionalStatement-web-weex', function() {
let source = `<view><view c-if="true"></view><view c-else-if="true"></view><view c-else="true"></view></view>`;
let source = `<view><view c-if="{{value1}}"></view><view c-else-if="{{value2}}"></view><view c-else></view></view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseConditionalStatement;
let result = compileTemplate(source, 'web', options, callback);
it('test-condition-web-transform', function() {
expect(result).to.equal(`<view><view v-if="true"></view><view v-else-if="true"></view><view v-else="true"></view></view>`)
expect(result).to.equal(`<view><view v-if="value1"></view><view v-else-if="value2"></view><view v-else></view></view>`)
});
});
describe('parseConditionalStatement-wx', function() {
let source = `<view><view c-if="true"></view><view c-else-if="true"></view><view c-else="true"></view></view>`;
let source = `<view><view c-if="{{value1}}"></view><view c-else-if="{{value2}}"></view><view c-else></view></view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseConditionalStatement;
let result = compileTemplate(source, 'wx', options, callback);
it('test-condition-wx-transform', function() {
expect(result).to.equal(`<view><view wx:if="true"></view><view wx:elif="true"></view><view wx:else="true"></view></view>`)
expect(result).to.equal(`<view><view wx:if="{{value1}}"></view><view wx:elif="{{value2}}"></view><view wx:else></view></view>`)
});
});
describe('parseConditionalStatement-alipay', function() {
let source = `<view><view c-if="true"></view><view c-else-if="true"></view><view c-else="true"></view></view>`;
let source = `<view><view c-if="{{value1}}"></view><view c-else-if="{{value2}}"></view><view c-else></view></view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseConditionalStatement;
let result = compileTemplate(source, 'alipay', options, callback);
it('test-condition-alipay-transform', function() {
expect(result).to.equal(`<view><view a:if="true"></view><view a:elif="true"></view><view a:else="true"></view></view>`)
expect(result).to.equal(`<view><view a:if="{{value1}}"></view><view a:elif="{{value2}}"></view><view a:else></view></view>`)
});
});
describe('parseConditionalStatement-baidu', function() {
let source = `<view><view c-if="true"></view><view c-else-if="true"></view><view c-else="true"></view></view>`;
let source = `<view><view c-if="{{value1}}"></view><view c-else-if="{{value2}}"></view><view c-else></view></view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseConditionalStatement;
let result = compileTemplate(source, 'baidu', options, callback);
it('test-condition-baidu-transform', function() {
expect(result).to.equal(`<view><view s-if="true"></view><view s-elif="true"></view><view s-else="true"></view></view>`)
expect(result).to.equal(`<view><view s-if="value1"></view><view s-elif="value2"></view><view s-else></view></view>`)
});
});
// parseEventListener
describe('parseEventListener-web-weex', function() {
let source = `<view><view c-bind:tap="tapHandle"></view></view>`;
let options = {lang: 'cml'};
let originSource = `<view><origin-tag c-bind:click="handleClick"></origin-tag><thirdComp1 c-bind:click="handleClick"></thirdComp1><thirdComp2 c-bind:click="handleClick"></thirdComp2></view> `
let options = {lang: 'cml',
buildInComponents: {button: "cml-buildin-button"},
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
}]
};
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')"></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')"></thirdComp2></view>`)
});
});
describe('parseEventListener-wx-baidu', function() {
let source = `<view><view c-bind:tap="tapHandle"></view></view>`;
let options = {lang: 'cml'};
let originSource = `<view><origin-tag c-bind:click="handleClick"></origin-tag><thirdComp1 c-bind:click="handleClick"></thirdComp1><thirdComp2 c-bind:click="handleClick"></thirdComp2></view> `
let options = {lang: 'cml',
buildInComponents: {button: "cml-buildin-button"},
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
}]
};
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>`)
});
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>`)
});
});
describe('parseEventListener-alipay', function() {
let source = `<view><view c-bind:tap="tapHandle"></view></view>`;
let options = {lang: 'cml'};
let originSource = `<view><origin-tag c-bind:click="handleClick"></origin-tag><thirdComp1 c-bind:click="handleClick"></thirdComp1><thirdComp2 c-bind:click="handleClick"></thirdComp2></view> `
let options = {lang: 'cml',
buildInComponents: {button: "cml-buildin-button"},
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
}]
};
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>`)
});
it('test-origin-tag-event-transform', function() {
expect(compileTemplate(originSource, 'alipay', options, callback)).to.equal(`<view><origin-tag onClick="handleClick"></origin-tag><thirdComp1 onClick="handleClick"></thirdComp1><thirdComp2 onClick="_cmlEventProxy" data-eventclick="handleClick"></thirdComp2></view>`)
});
});
// parseIterationStatement
describe('parseIterationStatement-web-weex', function() {
......@@ -122,14 +203,21 @@ describe('parse-template-cml', function() {
expect(result).to.equal(`<view><view v-for="(item, index) in array"></view></view>`)
});
});
describe('parseIterationStatement-wx-alipay', function() {
describe('parseIterationStatement-wx', function() {
let source = `<view><view c-for="{{array}}"></view></view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseIterationStatement;
let result1 = compileTemplate(source, 'wx', options, callback);
let result2 = compileTemplate(source, 'alipay', options, callback);
it('test-Iteration-transform', function() {
expect(result1).to.equal(`<view><view wx:for="{{array}}"></view></view>`)
});
});
describe('parseIterationStatement-alipay', function() {
let source = `<view><view c-for="{{array}}"></view></view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseIterationStatement;
let result2 = compileTemplate(source, 'alipay', options, callback);
it('test-Iteration-transform', function() {
expect(result2).to.equal(`<view><view a:for="{{array}}"></view></view>`)
});
});
......@@ -142,6 +230,43 @@ describe('parse-template-cml', function() {
expect(result).to.equal(`<view><view s-for="array"></view></view>`)
});
});
// parseIterationStatement c-for-inde c-for-item c-key的测试
describe('parseIterationStatement-web-weex', function() {
let source = `<view><view c-for="{{array}}" c-for-index="idx" c-for-item="item" c-key="id"></view></view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseIterationStatement;
let result = compileTemplate(source, 'web', options, callback);
it('test-Iteration-transform', function() {
expect(result).to.equal(`<view><view v-for="(item, idx) in array" :key="item.id"></view></view>`)
});
});
describe('parseIterationStatement-wx', function() {
let source = `<view><view c-for="{{array}}" c-for-index="idx" c-for-item="item" c-key="id"></view></view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseIterationStatement;
let result1 = compileTemplate(source, 'wx', options, callback);
it('test-Iteration-transform', function() {
expect(result1).to.equal(`<view><view wx:for="{{array}}" wx:for-index="idx" wx:for-item="item" wx:key="id"></view></view>`)
});
});
describe('parseIterationStatement-alipay', function() {
let source = `<view><view c-for="{{array}}" c-for-index="idx" c-for-item="item" c-key="id"></view></view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseIterationStatement;
let result2 = compileTemplate(source, 'alipay', options, callback);
it('test-Iteration-transform', function() {
expect(result2).to.equal(`<view><view a:for="{{array}}" a:for-index="idx" a:for-item="item" a:key="id"></view></view>`)
});
});
describe('parseIterationStatement-baidu', function() {
let source = `<view><view c-for="{{array}}" c-for-index="idx" c-for-item="item" c-key="id"></view></view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseIterationStatement;
let result = compileTemplate(source, 'baidu', options, callback);
it('test-Iteration-transform', function() {
expect(result).to.equal(`<view><view s-for="array" s-for-index="idx" s-for-item="item" s-key="id"></view></view>`)
});
});
// parseAttributeStatement
describe('parseAttributeStatement-web-weex', function() {
let source = `<view><view prop1="static" prop2="{{dynamic}}"></view></view>`;
......@@ -278,7 +403,7 @@ describe('parse-template-cml', function() {
});
// parseDirectiveStatement:c-model
describe('parseDirectiveStatement-web-weex', function() {
let source = `<view><input c-model="{{searchText}}" /><custom-input c-model="{{search}}"></custom-input></view>`;
let source = `<view><input c-model="{{ searchText }}" /><custom-input c-model="{{ search }}"></custom-input></view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseDirectiveStatement;
let result = compileTemplate(source, 'web', options, callback);
......@@ -328,13 +453,27 @@ describe('parse-template-cml', function() {
let result_baidu = compileTemplate(source, 'baidu', options, callback);
let result_alipay = compileTemplate(source, 'alipay', options, callback);
it('test-class-transform', function() {
it('test-c-show-transform', function() {
expect(result_wx).to.equal(`<view style="display:{{true?'':'none'}};{{true?'':'height:0px;width:0px;overflow:hidden'}}"></view>`)
expect(result_baidu).to.equal(`<view style="display:{{true?'':'none'}};{{true?'':'height:0px;width:0px;overflow:hidden'}}"></view>`)
expect(result_alipay).to.equal(`<view style="display:{{true?'':'none'}};{{true?'':'height:0px;width:0px;overflow:hidden'}}"></view>`)
});
});
// c-text
describe('parseDirectiveStatement-web-miniapp', function() {
let source = `<view c-text="{{value1}}">everything will be replaced</view>`;
let options = {lang: 'cml'};
let callback = parseTemplate.parseDirectiveStatement;
it('test-c-text-transform', function() {
expect(compileTemplate(source, 'web', options, callback)).to.equal(`<view>{{value1}}</view>`)
});
it('test-c-text-transform', function() {
expect(compileTemplate(source, 'wx', options, callback)).to.equal(`<view>{{value1}}</view>`)
});
it('test-c-text-transform', function() {
expect(compileTemplate(source, 'weex', options, callback)).to.equal(`<view>{{value1}}</view>`)
});
});
describe('parse-vue2wx-wx', function() {
let source = `<component is="{{comp}}" shrinkComponents="comp,comp1"></component>`;
let options = {lang: 'cml'};
......
// vue语法的单元测试
// vue单个语法的单元测试
const babylon = require('babylon');
const t = require('@babel/types');
const traverse = require('@babel/traverse')["default"];
......@@ -25,6 +25,44 @@ function compileTemplate(source, type, options, callback) {
}
// cml语法的单元测试
describe('parse-template-vue', function() {
describe('parseTag', function() { // 各个端的标签转化单元测试不做全覆盖,逻辑相对简单
let source = `<view></view>`;
let options = {lang: 'vue'};
let callback = parseTemplate.parseTag;
let result = compileTemplate(source, 'web', options, callback);
it('test-tag-transform', function() {
expect(result).to.equal(`<div></div>`)
});
});
describe('afterParseTag', function() { // 各个端的标签转化单元测试不做全覆盖,逻辑相对简单
let source = `<block></block>`;
let options = {lang: 'vue'};
let callback = parseTemplate.afterParseTag;
it('test-after-tag-transform-web-weex', function() {
expect(compileTemplate(source, 'web', options, callback)).to.equal(`<template></template>`)
});
it('test-after-tag-transform-miniapp', function() {
expect(compileTemplate(source, 'wx', options, callback)).to.equal(`<block></block>`)
});
});
describe('parseBuildTag', function() { // 各个端的标签转化单元测试不做全覆盖,逻辑相对简单
let source = `<button></button>`;
let options = {lang: 'vue', buildInComponents: {button: "cml-buildin-button"} };
let callback = parseTemplate.parseBuildTag;
let result = compileTemplate(source, 'web', options, callback);
it('test-build-tag-transform', function() {
expect(result).to.equal(`<cml-buildin-button></cml-buildin-button>`)
});
});
describe('parseTagForSlider', function() {
let source = `<carousel><carousel-item></carousel-item></carousel>`;
let options = {lang: 'vue'};
let callback = parseTemplate.parseTagForSlider;
let result = compileTemplate(source, 'wx', options, callback);
it('parseTagForSlider for wx', function() {
expect(result).to.equal(`<swiper><swiper-item></swiper-item></swiper>`)
});
});
// parseRefStatement:仅在所有的小程序端进行处理
describe('parseRefStatement-miniapp', function() {
let source = `<view ref="flag"></view>`;
......@@ -50,19 +88,52 @@ describe('parse-template-vue', function() {
});
});
// parseVue2WxStatement:测试v-for语法转化为小程序
describe('parseVue2WxStatement-miniapp', function() {
let source = `<view v-for="(m,i) in array"><view v-for="item in array"></view></view>`;
describe('parseVue2WxStatement-web', function() {
let source = `<view v-for="(m,i) in array" v-bind:key="item.id"><view v-for="item in array"></view></view>`;
let options = {lang: 'vue'};
let callback = parseTemplate.parseVue2WxStatement;
let result_wx = compileTemplate(source, 'wx', options, callback);
let result_alipay = compileTemplate(source, 'alipay', options, callback);
let result_baidu = compileTemplate(source, 'baidu', options, callback);
let result = compileTemplate(source, 'web', options, callback);
it('test-Iteration-transform', function() {
expect(result).to.equal(`<view v-for="(m,i) in array" v-bind:key="item.id"><view v-for="item in array"></view></view>`)
});
});
describe('parseVue2WxStatement-weex', function() {
let source = `<view v-for="(m,i) in array" v-bind:key="id"><view v-for="item in array"></view></view>`;
let options = {lang: 'vue'};
let callback = parseTemplate.parseVue2WxStatement;
let result = compileTemplate(source, 'weex', options, callback);
it('test-Iteration-transform', function() {
expect(result_wx).to.equal(`<view wx:for-item="m" wx:for-index="i" wx:for="{{array}}"><view wx:for-item="item" wx:for-index="index" wx:for="{{array}}"></view></view>`)
expect(result_alipay).to.equal(`<view a:for-item="m" a:for-index="i" a:for="{{array}}"><view a:for-item="item" a:for-index="index" a:for="{{array}}"></view></view>`)
expect(result_baidu).to.equal(`<view s-for-item="m" s-for-index="i" s-for="array"><view s-for-item="item" s-for-index="index" s-for="array"></view></view>`)
expect(result).to.equal(`<view v-for="(m,i) in array" v-bind:key="id"><view v-for="item in array"></view></view>`)
});
});
describe('parseVue2WxStatement-wx', function() {
let source = `<view v-for="(m,i) in array" v-bind:key="id"><view v-for="item in array"></view></view>`;
let options = {lang: 'vue'};
let callback = parseTemplate.parseVue2WxStatement;
let result = compileTemplate(source, 'wx', options, callback);
it('test-Iteration-transform', function() {
expect(result).to.equal(`<view wx:for-item="m" wx:for-index="i" wx:for="{{array}}" wx:key="id"><view wx:for-item="item" wx:for-index="index" wx:for="{{array}}"></view></view>`)
});
});
describe('parseVue2WxStatement-alipay', function() {
let source = `<view v-for="(m,i) in array" v-bind:key="id"><view v-for="item in array"></view></view>`;
let options = {lang: 'vue'};
let callback = parseTemplate.parseVue2WxStatement;
let result = compileTemplate(source, 'alipay', options, callback);
it('test-Iteration-transform', function() {
expect(result).to.equal(`<view a:for-item="m" a:for-index="i" a:for="{{array}}" a:key="id"><view a:for-item="item" a:for-index="index" a:for="{{array}}"></view></view>`)
});
});
describe('parseVue2WxStatement-baidu', function() {
let source = `<view v-for="(m,i) in array" v-bind:key="id"><view v-for="item in array"></view></view>`;
let options = {lang: 'vue'};
let callback = parseTemplate.parseVue2WxStatement;
let result = compileTemplate(source, 'baidu', options, callback);
it('test-Iteration-transform', function() {
expect(result).to.equal(`<view s-for-item="m" s-for-index="i" s-for="array" s-key="id"><view s-for-item="item" s-for-index="index" s-for="array"></view></view>`)
});
});
// parseVue2WxStatement:测试 v-bind转化为小程序端的响应值
describe('parseVue2WxStatement-miniapp', function() {
let source = `<view><view prop1="static" v-bind:prop2="dynamic"></view></view>`;
......@@ -77,6 +148,15 @@ describe('parse-template-vue', function() {
expect(result_baidu).to.equal(`<view><view prop1="static" prop2="{{dynamic}}"></view></view>`)
});
});
describe('parseAttributeStatement-web-weex', function() {
let source = `<view><view prop1="static" v-bind:prop2="dynamic"></view></view>`;
let options = {lang: 'vue'};
let callback = parseTemplate.parseAttributeStatement;
let result = compileTemplate(source, 'web', options, callback);
it('test-attribute-transform', function() {
expect(result).to.equal(`<view><view prop1="static" v-bind:prop2="dynamic"></view></view>`)
});
});
// vue语法下style只支持一个style;parseStyleStatement
describe('parseStyleStatement-web', function() {
let source = `<view v-bind:style="dynamicColor"><view style="color:red"></view></view>`;
......@@ -176,7 +256,7 @@ describe('parse-template-vue', function() {
});
// parseDirectiveStatement
describe('parseDirectiveStatement-web-weex', function() {
let source = `<view><input v-model="searchText" /><custom-input v-model="search"></custom-input></view>`;
let source = `<view><input v-model=" searchText " /><custom-input v-model="search"></custom-input></view>`;
let options = {lang: 'vue'};
let callback = parseTemplate.parseDirectiveStatement;
let result = compileTemplate(source, 'web', options, callback);
......@@ -185,16 +265,16 @@ describe('parse-template-vue', function() {
});
});
describe('parseDirectiveStatement-wx-alipay-baidu', function() {
let source = `<view><input v-model="searchText" /><custom-input v-model="search"></custom-input></view>`;
let source = `<view><input v-model=" searchText " /><custom-input v-model="search"></custom-input></view>`;
let options = {lang: 'vue'};
let callback = parseTemplate.parseDirectiveStatement;
let result_wx = compileTemplate(source, 'wx', options, callback);
let result_baidu = compileTemplate(source, 'baidu', options, callback);
let result_alipay = compileTemplate(source, 'alipay', options, callback);
it('test-class-transform', function() {
expect(result_wx).to.equal(`<view><input data-modelkey="searchText" bindinput="_cmlModelEventProxy" value="{{searchText}}" /><custom-input data-modelkey="search" bindinput="_cmlModelEventProxy" value="{{search}}"></custom-input></view>`)
expect(result_baidu).to.equal(`<view><input data-modelkey="searchText" bindinput="_cmlModelEventProxy" value="{{searchText}}" /><custom-input data-modelkey="search" bindinput="_cmlModelEventProxy" value="{{search}}"></custom-input></view>`)
expect(result_alipay).to.equal(`<view><input data-modelkey="searchText" bindInput="_cmlModelEventProxy" value="{{searchText}}" /><custom-input data-modelkey="search" bindInput="_cmlModelEventProxy" value="{{search}}"></custom-input></view>`)
it('test-v-model', function() {
expect(result_wx).to.equal(`<view><input data-modelkey="searchText" bindinput="_cmlModelEventProxy" value="{{ searchText }}" /><custom-input data-modelkey="search" bindinput="_cmlModelEventProxy" value="{{search}}"></custom-input></view>`)
expect(result_baidu).to.equal(`<view><input data-modelkey="searchText" bindinput="_cmlModelEventProxy" value="{{ searchText }}" /><custom-input data-modelkey="search" bindinput="_cmlModelEventProxy" value="{{search}}"></custom-input></view>`)
expect(result_alipay).to.equal(`<view><input data-modelkey="searchText" bindInput="_cmlModelEventProxy" value="{{ searchText }}" /><custom-input data-modelkey="search" bindInput="_cmlModelEventProxy" value="{{search}}"></custom-input></view>`)
});
});
// c-show
......@@ -208,7 +288,21 @@ describe('parse-template-vue', function() {
expect(result).to.equal(`<view v-show="true"></view>`)
});
});
// c-text
describe('parseDirectiveStatement-web-miniapp', function() {
let source = `<view v-text="value1">everything will be replaced</view>`;
let options = {lang: 'vue'};
let callback = parseTemplate.parseDirectiveStatement;
it('test-c-text-transform', function() {
expect(compileTemplate(source, 'web', options, callback)).to.equal(`<view>{{value1}}</view>`)
});
it('test-c-text-transform', function() {
expect(compileTemplate(source, 'wx', options, callback)).to.equal(`<view>{{value1}}</view>`)
});
it('test-c-text-transform', function() {
expect(compileTemplate(source, 'weex', options, callback)).to.equal(`<view>{{value1}}</view>`)
});
});
describe('parseDirectiveStatement-weex', function() {
let source = `<view v-show="true"></view>`;
let options = {lang: 'vue'};
......
......@@ -36,4 +36,4 @@
"break-test": "./node_modules/.bin/mocha --inspect-brk --recursive --reporter spec"
},
"version": "0.0.15-alpha.0"
}
\ No newline at end of file
}
......@@ -215,6 +215,8 @@ _.isDirectory = function (filePath) {
}
}
/**
* @param {String} filePath cml文件位置 已经不再支持json文件
* @param {String} confType 获取的类型 wx|web|weex
......
......@@ -5,7 +5,7 @@ const {startServer: startWeexLiveLoad, broadcast} = require('./weex/socket-serve
const previewSocket = require('./web/web-socket.js');
const cmlLinter = require('chameleon-linter');
const watch = require('glob-watcher');
const fse = require('fs-extra');
/**
* 非web端构建
......@@ -15,7 +15,24 @@ const watch = require('glob-watcher');
exports.getBuildPromise = async function (media, type) {
let options = exports.getOptions(media, type);
let webpackConfig = await getConfig(options)
let webpackConfig = await getConfig(options);
if (~['wx', 'baidu', 'alipay'].indexOf(type)) {
// 异步删除output目录
var outputpath = webpackConfig.output.path;
await new Promise(function(resolve, reject) {
fse.remove(outputpath, function(err) {
if (err) {
reject(err);
}
resolve();
})
})["catch"](e => {
let message = `clear file error! please remove direction ${outputpath} by yourself!`
cml.log.error(message);
throw new Error(e)
})
}
return new Promise(function(resolve, reject) {
// watch模式
if (media === 'dev') {
......@@ -43,7 +60,7 @@ exports.getBuildPromise = async function (media, type) {
if (err) {
reject(err);
}
resolve();
resolve();
});
}
})
......
......@@ -89,7 +89,6 @@ function replaceCmlPath(content, filename, options) {
}
function replaceCmss(content, options) {
debugger
let style = cml.utils.splitParts({
content
}).style;
......
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var utils = require('./utils.js');
var path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin')
var webpack = require('webpack')
var merge = require('webpack-merge')
const getCommonConfig = require('./getCommonConfig');
......@@ -78,7 +77,6 @@ module.exports = function (options) {
filename: `[name].${targetObj.css}`,
allChunks: true
}),
new CleanWebpackPlugin(['./*'], {root: outputPath, verbose: false}),
new webpack.optimize.CommonsChunkPlugin({
name: ['common', 'manifest'],
filename: 'static/js/[name].js',
......
......@@ -3,7 +3,6 @@ let defaultConfig = {
"plugins": {
// to edit target browsers: use "browserslist" field in package.json
"postcss-import": {},
"postcss-plugin-weex":{},
"autoprefixer": cml.config.get().cmss.autoprefixOptions
}
}
......
......@@ -539,7 +539,7 @@
</div>
<p class="no-dev-content">
未启动Weex端构建
</p>
</div>
</div>
......@@ -558,12 +558,12 @@
</div>
<p class="no-dev-content">
未启动web端构建
</p>
</div>
</div>
</div>
<div class="qrcode-box qrcode-box-bottom" id="qrcodeBox">
<div class='qrcode-item'>
......@@ -623,7 +623,6 @@
</div>
</div>
</div>
</div>
</main>
</div>
......@@ -635,8 +634,8 @@
var jsbundle = '';
var routerConfig = {
mode: 'history',
routes:[],
};
routes:[]
};
var activeIndex = 0;
var routeListDom;
var selectInput = document.getElementById('routes-select');
......@@ -648,16 +647,16 @@
jsbundle = params.jsbundle;
}
function activeBuildType(params){
let buildType = params.buildType;
if (buildType.includes('weex')) {
var buildType = params.buildType;
if (~buildType.indexOf('weex')) {
Array.isArray(buildType) && buildType.push('sfc');
};
if (buildType.includes('web')) {
if (~buildType.indexOf('web')) {
Array.isArray(buildType) && buildType.push('h5');
};
buildType.forEach((type) => {
var activeDom = document.getElementById(`${type}-dev`);
var hideDom = document.getElementById(`${type}-no-dev`);
buildType.forEach(function (type) {
var activeDom = document.getElementById(type + '-dev');
var hideDom = document.getElementById(type + '-no-dev');
if(activeDom){
activeDom.style.display = 'block';
}
......@@ -683,7 +682,7 @@
QR.addData(url)
QR.make()
$QR.innerHTML = QR.createImgTag(6, 12)
}
//创建beatles的二维码
......@@ -696,7 +695,7 @@
pageUrl += subpath
}
var beatlesUrl = pageUrl + '?wx_addr=' +
encodeURIComponent(`${url}?t=` + Date.now());
encodeURIComponent(url + '?t=' + Date.now());
if (path) {
beatlesUrl += '&path=' + encodeURIComponent(path);
......@@ -761,12 +760,12 @@
if (routes) {
var fragment = document.createDocumentFragment();
routeListDom = document.createElement('ul');
routeListDom.setAttribute('id','routeList')
for (var i = 0; i < routes.length; i++) {
var li = document.createElement('li');
li.setAttribute('index', i);
li.innerHTML = `<img style="display:none;padding-right:5px;" src="./preview-assets/cml-right.png" alt=""><span index=${i} title=${routes[i].path} >${routes[i].url}</span>`
li.innerHTML = '<img style="display:none;padding-right:5px;" src="./preview-assets/cml-right.png" alt=""><span index=' + i + ' title=' + routes[i].path + ' >' + routes[i].url+ '</span>';
routeListDom.appendChild(li);
}
fragment.appendChild(routeListDom)
......@@ -793,9 +792,11 @@
routeListDom.children[0] && routeListDom.children[0].children[1].click();
}
};
function createWS() {
// const ws = new WebSocket(`ws://${location.hostname}:${webport}`);
const ws = new WebSocket(`ws://${location.host}`);
var ws = new WebSocket('ws://' + location.host);
ws.onopen = function () {
console.log('@open');
};
......@@ -823,4 +824,4 @@
</script>
</body>
</html>
\ No newline at end of file
</html>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册