transformStyle.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.createVirtualHostStyle = exports.rewriteStyle = exports.findStaticStyleIndex = exports.isStyleBinding = void 0;
  4. const types_1 = require("@babel/types");
  5. const compiler_core_1 = require("@vue/compiler-core");
  6. const shared_1 = require("@vue/shared");
  7. const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
  8. const runtimeHelpers_1 = require("../runtimeHelpers");
  9. const ast_1 = require("../ast");
  10. const codegen_1 = require("../codegen");
  11. const utils_1 = require("./utils");
  12. function isStyleBinding({ arg, exp }) {
  13. return (arg && arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && arg.content === 'style');
  14. }
  15. exports.isStyleBinding = isStyleBinding;
  16. function findStaticStyleIndex(props) {
  17. return props.findIndex((prop) => prop.name === 'style');
  18. }
  19. exports.findStaticStyleIndex = findStaticStyleIndex;
  20. function rewriteStyle(index, styleBindingProp, props, virtualHost, context) {
  21. const expr = styleBindingProp.exp
  22. ? (0, ast_1.parseExpr)(styleBindingProp.exp, context)
  23. : undefined;
  24. let styleBidingExpr = expr;
  25. if (expr) {
  26. if ((0, types_1.isObjectExpression)(expr)) {
  27. styleBidingExpr = createStyleBindingByObjectExpression(rewriteStyleObjectExpression(expr, styleBindingProp.loc, context));
  28. }
  29. else if ((0, types_1.isArrayExpression)(expr)) {
  30. styleBidingExpr = createStyleBindingByArrayExpression(rewriteStyleArrayExpression(expr, context));
  31. }
  32. else {
  33. styleBidingExpr = (0, ast_1.parseExpr)(rewriteStyleExpression(styleBindingProp.exp, context).content, context);
  34. }
  35. if (!styleBidingExpr) {
  36. return;
  37. }
  38. }
  39. else if (!virtualHost) {
  40. return;
  41. }
  42. const staticStylePropIndex = findStaticStyleIndex(props);
  43. if (staticStylePropIndex > -1) {
  44. const staticStyle = props[staticStylePropIndex].value
  45. .content;
  46. if (staticStyle.trim()) {
  47. if (styleBidingExpr) {
  48. if (index > staticStylePropIndex) {
  49. styleBidingExpr = (0, types_1.binaryExpression)('+', addSemicolon((0, types_1.stringLiteral)(staticStyle)), styleBidingExpr);
  50. }
  51. else {
  52. styleBidingExpr = (0, types_1.binaryExpression)('+', addSemicolon(styleBidingExpr), (0, types_1.stringLiteral)(staticStyle));
  53. }
  54. }
  55. else {
  56. styleBidingExpr = (0, types_1.stringLiteral)(staticStyle);
  57. }
  58. }
  59. }
  60. if (virtualHost) {
  61. styleBidingExpr = styleBidingExpr
  62. ? (0, types_1.binaryExpression)('+', addSemicolon(styleBidingExpr), (0, types_1.identifier)(utils_1.VIRTUAL_HOST_STYLE))
  63. : (0, types_1.identifier)(utils_1.VIRTUAL_HOST_STYLE);
  64. }
  65. styleBindingProp.exp = (0, compiler_core_1.createSimpleExpression)((0, codegen_1.genBabelExpr)(styleBidingExpr));
  66. }
  67. exports.rewriteStyle = rewriteStyle;
  68. function createVirtualHostStyle(props, context) {
  69. const styleBindingProp = (0, uni_cli_shared_1.createBindDirectiveNode)('style', '');
  70. delete styleBindingProp.exp;
  71. rewriteStyle(0, styleBindingProp, props, true, context);
  72. return styleBindingProp;
  73. }
  74. exports.createVirtualHostStyle = createVirtualHostStyle;
  75. function rewriteStyleExpression(expr, context) {
  76. return (0, utils_1.rewriteExpression)((0, compiler_core_1.createCompoundExpression)([
  77. context.helperString(runtimeHelpers_1.STRINGIFY_STYLE) + '(',
  78. expr,
  79. ')',
  80. ]), context);
  81. }
  82. function rewriteStyleArrayExpression(expr, context) {
  83. expr.elements.forEach((prop, index) => {
  84. if (!(0, types_1.isStringLiteral)(prop)) {
  85. const code = (0, codegen_1.genBabelExpr)((0, types_1.arrayExpression)([(0, types_1.isSpreadElement)(prop) ? prop.argument : prop]));
  86. expr.elements[index] = (0, types_1.identifier)(rewriteStyleExpression((0, compiler_core_1.createSimpleExpression)(code.slice(1, -1), false), context).content);
  87. }
  88. });
  89. return expr;
  90. }
  91. function rewriteStyleObjectExpression(expr, loc, context) {
  92. expr.properties.forEach((prop, index) => {
  93. if ((0, types_1.isSpreadElement)(prop)) {
  94. // <view :style="{...obj}"/>
  95. // <view style="{{a}}"/>
  96. const newExpr = (0, utils_1.rewriteSpreadElement)(runtimeHelpers_1.STRINGIFY_STYLE, prop, loc, context);
  97. if (newExpr) {
  98. prop.argument = newExpr;
  99. }
  100. }
  101. else if ((0, types_1.isObjectProperty)(prop)) {
  102. const { key, value, computed } = prop;
  103. if (!(0, types_1.isPrivateName)(key)) {
  104. if (computed) {
  105. // {[handle(computedKey)]:1} => {[a]:1}
  106. const newExpr = (0, utils_1.rewirteWithHelper)(runtimeHelpers_1.HYPHENATE, key, loc, context);
  107. if (newExpr) {
  108. prop.key = newExpr;
  109. }
  110. }
  111. else {
  112. // {fontSize:'15px'} => {'font-size':'15px'}
  113. prop.key = (0, ast_1.parseStringLiteral)(key);
  114. prop.key.value = (0, shared_1.hyphenate)(prop.key.value) + ':';
  115. }
  116. // {fontSize:`${fontSize}px`} => {'font-size':a}
  117. if ((0, utils_1.isStaticLiteral)(value)) {
  118. return;
  119. }
  120. else {
  121. const newExpr = (0, utils_1.parseExprWithRewrite)((0, codegen_1.genBabelExpr)(value), loc, context, value);
  122. if (newExpr) {
  123. prop.value = newExpr;
  124. }
  125. }
  126. }
  127. }
  128. });
  129. return expr;
  130. }
  131. function addSemicolon(expr) {
  132. return createBinaryExpression(expr, (0, types_1.stringLiteral)(';'));
  133. }
  134. function createBinaryExpression(left, right) {
  135. return (0, types_1.binaryExpression)('+', left, right);
  136. }
  137. function createStyleBindingByArrayExpression(expr) {
  138. let result;
  139. function concat(expr) {
  140. if (!result) {
  141. result = expr;
  142. }
  143. else {
  144. result = createBinaryExpression(addSemicolon(result), expr);
  145. }
  146. }
  147. expr.elements.forEach((prop) => {
  148. if ((0, types_1.isStringLiteral)(prop) || (0, types_1.isIdentifier)(prop)) {
  149. concat(prop);
  150. }
  151. });
  152. return result;
  153. }
  154. function createStyleBindingByObjectExpression(expr) {
  155. let result;
  156. function concat(expr) {
  157. if (!result) {
  158. result = expr;
  159. }
  160. else {
  161. result = createBinaryExpression(addSemicolon(result), expr);
  162. }
  163. }
  164. expr.properties.forEach((prop) => {
  165. if ((0, types_1.isSpreadElement)(prop)) {
  166. concat(prop.argument);
  167. }
  168. else if ((0, types_1.isObjectProperty)(prop)) {
  169. const { key, value } = prop;
  170. if (!(0, types_1.isPrivateName)(key)) {
  171. const expr = createBinaryExpression((0, types_1.isStringLiteral)(key)
  172. ? key // 之前已经补充了:
  173. : createBinaryExpression(key, (0, types_1.stringLiteral)(':')), value);
  174. concat(expr);
  175. }
  176. }
  177. });
  178. return result;
  179. }