Skip to content

Commit

Permalink
feat: added :style support
Browse files Browse the repository at this point in the history
  • Loading branch information
Gcaufy committed May 24, 2018
1 parent 845a3b3 commit e8a4911
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 84 deletions.
2 changes: 1 addition & 1 deletion packages/wepy-cli/core/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class Compile extends Hook {
'./plugins/build/vendor',

'./plugins/template/parse',
'./plugins/template/parseBindClass',
'./plugins/template/parseClassAndStyle',
].map(v => require(v));

initHooks(this, plugins);
Expand Down
9 changes: 7 additions & 2 deletions packages/wepy-cli/core/plugins/template/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ exports = module.exports = function () {
logger.silly('html2wxml', `Change "${item.name}" to "${html2wxmlMap[item.name]}"`);
item.name = html2wxmlMap[item.name];
} else if (wxmlTags.indexOf(item.name) > -1) { // Tag is a wxml tag

} else if (htmlTags.indexOf(item.name) > -1) { // Tag is a html tag
logger.silly('html2wxml', `Change "${item.name}" is a html tag, changed to "view"`);
item.name = 'view';
Expand Down Expand Up @@ -252,10 +252,15 @@ exports = module.exports = function () {
str += '<' + item.name;
if (item.parsedAttr) {
Object.keys(item.parsedAttr).forEach(attr => {
if (attr !== 'class')
if (attr !== 'class' && attr !== 'style')
str += ` ${attr}="${item.parsedAttr[attr]}"`;
});
}
if (item.parsedAttr.style || (item.bindStyle && item.bindStyle.length)) {
let staticStyle = item.parsedAttr.style || '';
let bindStyle = (item.bindStyle && item.bindStyle.length) ? ` {{ ${item.bindStyle.join(' + ')} }}` : '';
str += ` style="${staticStyle + bindStyle}"`;
}
if (item.parsedAttr.class || (item.bindClass && item.bindClass.length)) {
let staticClass = item.parsedAttr.class || '';
let bindClass = (item.bindClass && item.bindClass.length) ? ` {{ [ ${item.bindClass.join(',')} ] }}` : '';
Expand Down
81 changes: 0 additions & 81 deletions packages/wepy-cli/core/plugins/template/parseBindClass.js

This file was deleted.

32 changes: 32 additions & 0 deletions packages/wepy-cli/core/plugins/template/parseClassAndStyle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const exprParser = require('../../util/exprParser');


exports = module.exports = function () {

this.register('template-parse-ast-attr-:class', function parseBindClass ({item, name, expr}) {
let exprObj = exprParser.str2obj(expr);
item.bindClass = Object.keys(exprObj).map(name => {
let exp = exprObj[name].replace(/\'/ig, '\\\'').replace(/\"/ig, '\\"');
name = name.replace(/\'/ig, '\\\'').replace(/\"/ig, '\\"');
return `${exp} ? '${name}' : ''`;
});
// return {} means remove :class
return {};
});


this.register('template-parse-ast-attr-:style', function parseBindClass ({item, name, expr}) {
let exprObj = exprParser.str2obj(expr);
item.bindStyle = Object.keys(exprObj).map(name => {
let exp = exprObj[name].replace(/\'/ig, '\\\'').replace(/\"/ig, '\\"');
name = name.replace(/\'/ig, '\\\'').replace(/\"/ig, '\\"');
name = exprParser.hyphenate(name);
return `'${name}:' + ${exp} + ';'`;
});
// return {} means remove :class
return {};
});


};

92 changes: 92 additions & 0 deletions packages/wepy-cli/core/util/exprParser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
const camelizeRE = /-(\w)/g;
const hyphenateRE = /([^-])([A-Z])/g;


const cached = (fn) => {
let cache = {};
return ((str) => (cache[str] || (cache[str] = fn(str))));
};

exports = module.exports = {
hyphenate: cached((str) => {
return str
.replace(hyphenateRE, '$1-$2')
.replace(hyphenateRE, '$1-$2')
.toLowerCase();
}),
camelize: cached((str) => {
return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; });
}),
/**
* str2obj parse a object string to a real object
* @param {String} str "{someKey: someCondition}"
* @return {Object} {someKey: someCondition}
*/
str2obj: cached((exp) => {
exp = exp.replace(/^\s/ig, '').replace(/\s$/ig, '');
if (exp[0] === '{' && exp[exp.length - 1] === '}') {
exp = exp.substring(1, exp.length - 1);
let i = 0, len = exp.length;
let flagStack = [], flag = 'start';
let classNames = [], result = {}, str = '';
for (i = 0; i < len; i++) {
if ((exp[i] === '\'' || exp[i] === '"')) {
if (flagStack.length && flagStack[0] === exp[i]) {
flagStack.pop();
if (flag === 'class') {
flag = ':';
continue;
} else if (flag === 'expression') {
str += exp[i];
continue;
}
} else {
if (flagStack.length === 0) {
flagStack.push(exp[i]);
if (flag === 'start') {
flag = 'class';
continue;
} else if (flag === 'expression') {
str += exp[i];
continue;
}
}
}
}
// {abc: num < 1} or {'abc': num <1}
if (exp[i] === ':' && (flag === ':' || flag === 'class') && flagStack.length === 0) {
flag = 'expression';
classNames.push(str);
str = '';
continue;
}
if (exp[i] === ',' && flag === 'expression' && flagStack.length === 0) {
result[classNames[classNames.length - 1]] = str.replace(/^\s/ig, '').replace(/\s$/ig, '');;
str = '';
flag = 'start';
continue;
}
// get rid of the begining space
if (!str.length && exp[i] === ' ')
continue;

// not started with '', like {abc: num < 1}
if (flag === 'start') {
flag = 'class';
}

if (flag === 'class' || flag === 'expression') {
str += exp[i];
}
}
if (str.length) {
result[classNames[classNames.length - 1]] = str.replace(/^\s/ig, '').replace(/\s$/ig, '');
}
return result;
} else {
throw ':class expression is not correct, it has to be {\'className\': mycondition}';
}
})
}


0 comments on commit e8a4911

Please sign in to comment.