babel-plugin-jsx-dom-expressions 0.40.3 → 0.40.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +7 -0
  2. package/index.js +112 -20
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -198,6 +198,13 @@ Example usage:
198
198
  const template = <div>Hello</div>;
199
199
  ```
200
200
 
201
+ ### inlineStyles
202
+
203
+ - Type: `boolean`
204
+ - Default: `true`
205
+
206
+ Style attributes in templates are inlined when possible: value is a string, `Record<string, string>`, etc. Inlining styles may not be desired when using strong CSP configurations. Disabling `inlineStyles` will cause all of the style definitions to be set at runtime.
207
+
201
208
  ## Special Binding
202
209
 
203
210
  ### ref
package/index.js CHANGED
@@ -436,7 +436,12 @@ function isDynamic(path, { checkMember, checkTags, checkCallExpressions = true,
436
436
  return false;
437
437
  }
438
438
 
439
- if (checkCallExpressions && (t__namespace.isCallExpression(expr) || t__namespace.isOptionalCallExpression(expr) || t__namespace.isTaggedTemplateExpression(expr))) {
439
+ if (
440
+ checkCallExpressions && (
441
+ t__namespace.isCallExpression(expr) ||
442
+ t__namespace.isOptionalCallExpression(expr) ||
443
+ t__namespace.isTaggedTemplateExpression(expr)))
444
+ {
440
445
  return true;
441
446
  }
442
447
 
@@ -770,6 +775,36 @@ const templateEscapes = new Map([
770
775
  ["\u2028", "\\u2028"],
771
776
  ["\u2029", "\\u2029"]]);
772
777
 
778
+
779
+ function evaluateAndInline(value, valueNode) {
780
+ if (t__namespace.isJSXExpressionContainer(value)) {
781
+ evaluateAndInline(value.expression, valueNode.get("expression"));
782
+ } else if (t__namespace.isObjectProperty(value)) {
783
+ evaluateAndInline(value.value, valueNode.get("value"));
784
+ } else if (
785
+ t__namespace.isStringLiteral(value) ||
786
+ t__namespace.isNumericLiteral(value) ||
787
+ t__namespace.isBooleanLiteral(value) ||
788
+ t__namespace.isNullLiteral(value))
789
+ ; else if (t__namespace.isObjectExpression(value)) {const properties = value.properties;
790
+ const propertiesNode = valueNode.get("properties");
791
+ for (let i = 0; i < properties.length; i++) {
792
+ evaluateAndInline(properties[i], propertiesNode[i]);
793
+ }
794
+ } else {
795
+ const r = valueNode.evaluate();
796
+ if (r.confident) {
797
+ if (typeof r.value === "string") {
798
+ valueNode.replaceWith(t__namespace.stringLiteral(r.value));
799
+ } else if (typeof r.value === "number") {
800
+ valueNode.replaceWith(t__namespace.numericLiteral(r.value));
801
+ } else if (typeof r.value === "boolean") {
802
+ valueNode.replaceWith(t__namespace.booleanLiteral(r.value));
803
+ }
804
+ }
805
+ }
806
+ }
807
+
773
808
  const InlineElements = [
774
809
  "a",
775
810
  "abbr",
@@ -887,6 +922,13 @@ const alwaysClose = [
887
922
 
888
923
 
889
924
  function transformElement$3(path, info) {
925
+ path.
926
+ get("openingElement").
927
+ get("attributes").
928
+ forEach((attr) => {
929
+ evaluateAndInline(attr.node.value, attr.get("value"));
930
+ });
931
+
890
932
  let tagName = getTagName(path.node),
891
933
  config = getConfig(path),
892
934
  wrapSVG = info.topLevel && tagName != "svg" && SVGElements.has(tagName),
@@ -918,6 +960,27 @@ function transformElement$3(path, info) {
918
960
  skipTemplate: false
919
961
  };
920
962
 
963
+ if (!config.inlineStyles) {
964
+ path.
965
+ get("openingElement").
966
+ get("attributes").
967
+ forEach((a) => {
968
+ if (a.node.name?.name === "style") {
969
+ let value = a.node.value.expression ? a.node.value.expression : a.node.value;
970
+ if (t__namespace.isStringLiteral(value)) {
971
+ // jsx attribute value is a sting that may takes more than one line
972
+ value = t__namespace.templateLiteral(
973
+ [t__namespace.templateElement({ raw: value.value, cooked: value.value })],
974
+ []);
975
+
976
+ }
977
+ a.get("value").replaceWith(
978
+ t__namespace.jSXExpressionContainer(t__namespace.callExpression(t__namespace.arrowFunctionExpression([], value), [])));
979
+
980
+ }
981
+ });
982
+ }
983
+
921
984
  path.
922
985
  get("openingElement").
923
986
  get("attributes").
@@ -2470,6 +2533,13 @@ function appendToTemplate(template, value) {
2470
2533
  }
2471
2534
 
2472
2535
  function transformElement$2(path, info) {
2536
+ path.
2537
+ get("openingElement").
2538
+ get("attributes").
2539
+ forEach((attr) => {
2540
+ evaluateAndInline(attr.node.value, attr.get("value"));
2541
+ });
2542
+
2473
2543
  const config = getConfig(path);
2474
2544
  const tagName = getTagName(path.node);
2475
2545
  if (tagName === "script" || tagName === "style") path.doNotEscape = true;
@@ -2592,11 +2662,12 @@ function escapeExpression(path, expression, attr, escapeLiterals) {
2592
2662
  expression.alternate = escapeExpression(path, expression.alternate, attr, escapeLiterals);
2593
2663
  return expression;
2594
2664
  } else if (t__namespace.isLogicalExpression(expression)) {
2595
- expression.right = escapeExpression(path, expression.right, attr, escapeLiterals);
2596
- if (expression.operator !== "&&") {
2597
- expression.left = escapeExpression(path, expression.left, attr, escapeLiterals);
2665
+ // Preserve the old short-circuit shape for && while still escaping the
2666
+ // selected result of || and ?? as a whole.
2667
+ if (expression.operator === "&&") {
2668
+ expression.right = escapeExpression(path, expression.right, attr, escapeLiterals);
2669
+ return expression;
2598
2670
  }
2599
- return expression;
2600
2671
  } else if (t__namespace.isCallExpression(expression) && t__namespace.isFunction(expression.callee)) {
2601
2672
  if (t__namespace.isBlockStatement(expression.callee.body)) {
2602
2673
  expression.callee.body.body = expression.callee.body.body.map((e) => {
@@ -2752,8 +2823,10 @@ function transformAttributes$1(path, results, info) {
2752
2823
  children = value;
2753
2824
  } else {
2754
2825
  let doEscape = true;
2826
+
2755
2827
  if (key.startsWith("attr:")) key = key.replace("attr:", "");
2756
- if (BooleanAttributes.has(key)) {
2828
+ if (BooleanAttributes.has(key) || key.startsWith("bool:")) {
2829
+ key = key.replace("bool:", "");
2757
2830
  results.template.push("");
2758
2831
  const fn = t__namespace.callExpression(registerImportMethod(attribute, "ssrAttribute"), [
2759
2832
  t__namespace.stringLiteral(key),
@@ -2769,14 +2842,23 @@ function transformAttributes$1(path, results, info) {
2769
2842
  t__namespace.isObjectExpression(value.expression) &&
2770
2843
  !value.expression.properties.some((p) => t__namespace.isSpreadElement(p)))
2771
2844
  {
2772
- const props = value.expression.properties.map((p, i) =>
2773
- t__namespace.callExpression(registerImportMethod(path, "ssrStyleProperty"), [
2774
- t__namespace.stringLiteral(
2775
- (i ? ";" : "") + (t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value) + ":"),
2845
+ if (value.expression.properties.length === 0) {
2846
+ return;
2847
+ }
2848
+ const props = value.expression.properties.map((p, i) => {
2849
+ if (p.computed) {
2850
+ return t__namespace.callExpression(registerImportMethod(path, "ssrStyleProperty"), [
2851
+ t__namespace.binaryExpression("+", p.key, t__namespace.stringLiteral(":")),
2852
+ escapeExpression(path, p.value, true, true)]);
2776
2853
 
2777
- escapeExpression(path, p.value, true, true)]));
2854
+ }
2855
+ return t__namespace.callExpression(registerImportMethod(path, "ssrStyleProperty"), [
2856
+ t__namespace.stringLiteral(
2857
+ (i ? ";" : "") + (t__namespace.isIdentifier(p.key) ? p.key.name : p.key.value) + ":"),
2778
2858
 
2859
+ escapeExpression(path, p.value, true, true)]);
2779
2860
 
2861
+ });
2780
2862
 
2781
2863
  let res = props[0];
2782
2864
  for (let i = 1; i < props.length; i++) {
@@ -3047,6 +3129,13 @@ function createElement(path, { topLevel, hydratable }) {
3047
3129
  }
3048
3130
 
3049
3131
  function transformElement$1(path, info) {
3132
+ path.
3133
+ get("openingElement").
3134
+ get("attributes").
3135
+ forEach((attr) => {
3136
+ evaluateAndInline(attr.node.value, attr.get("value"));
3137
+ });
3138
+
3050
3139
  let tagName = getTagName(path.node),
3051
3140
  results = {
3052
3141
  id: path.scope.generateUidIdentifier("el$"),
@@ -3133,9 +3222,7 @@ function transformAttributes(path, results) {
3133
3222
  if (!isConstant && t__namespace.isLVal(value.expression)) {
3134
3223
  const refIdentifier = path.scope.generateUidIdentifier("_ref$");
3135
3224
  results.exprs.unshift(
3136
- t__namespace.variableDeclaration("var", [
3137
- t__namespace.variableDeclarator(refIdentifier, value.expression)]),
3138
-
3225
+ t__namespace.variableDeclaration("var", [t__namespace.variableDeclarator(refIdentifier, value.expression)]),
3139
3226
  t__namespace.expressionStatement(
3140
3227
  t__namespace.conditionalExpression(
3141
3228
  t__namespace.binaryExpression(
@@ -3171,9 +3258,7 @@ function transformAttributes(path, results) {
3171
3258
  } else {
3172
3259
  const refIdentifier = path.scope.generateUidIdentifier("_ref$");
3173
3260
  results.exprs.unshift(
3174
- t__namespace.variableDeclaration("var", [
3175
- t__namespace.variableDeclarator(refIdentifier, value.expression)]),
3176
-
3261
+ t__namespace.variableDeclaration("var", [t__namespace.variableDeclarator(refIdentifier, value.expression)]),
3177
3262
  t__namespace.expressionStatement(
3178
3263
  t__namespace.logicalExpression(
3179
3264
  "&&",
@@ -3284,13 +3369,19 @@ function transformChildren(path, results) {
3284
3369
  t__namespace.variableDeclarator(
3285
3370
  child.id,
3286
3371
  t__namespace.callExpression(createTextNode, [
3287
- t__namespace.templateLiteral([t__namespace.templateElement({ raw: escapeStringForTemplate(child.template) })], [])])));
3372
+ t__namespace.templateLiteral(
3373
+ [t__namespace.templateElement({ raw: escapeStringForTemplate(child.template) })],
3374
+ [])])));
3375
+
3288
3376
 
3289
3377
 
3290
3378
 
3291
3379
  } else
3292
3380
  insert = t__namespace.callExpression(createTextNode, [
3293
- t__namespace.templateLiteral([t__namespace.templateElement({ raw: escapeStringForTemplate(child.template) })], [])]);
3381
+ t__namespace.templateLiteral(
3382
+ [t__namespace.templateElement({ raw: escapeStringForTemplate(child.template) })],
3383
+ [])]);
3384
+
3294
3385
 
3295
3386
  }
3296
3387
  appends.push(t__namespace.expressionStatement(t__namespace.callExpression(insertNode, [results.id, insert])));
@@ -4221,7 +4312,8 @@ var config = {
4221
4312
  staticMarker: "@once",
4222
4313
  effectWrapper: "effect",
4223
4314
  memoWrapper: "memo",
4224
- validate: true
4315
+ validate: true,
4316
+ inlineStyles: true
4225
4317
  };
4226
4318
 
4227
4319
  var preprocess = ((path, state) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "babel-plugin-jsx-dom-expressions",
3
3
  "description": "A JSX to DOM plugin that wraps expressions for fine grained change detection",
4
- "version": "0.40.3",
4
+ "version": "0.40.6",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -33,5 +33,5 @@
33
33
  "@rollup/plugin-babel": "6.0.3",
34
34
  "@types/babel__core": "^7.20.5"
35
35
  },
36
- "gitHead": "f241fd111f65fcd81f61191056eda59235929536"
36
+ "gitHead": "4f1ff795b280004134c0c3e16dec1dc0c9148141"
37
37
  }