Add AST_Interpolate to produce ${expression} in minified output (allows to drop serve...
authorNick Downing <nick@ndcode.org>
Wed, 12 Jan 2022 12:09:45 +0000 (23:09 +1100)
committerNick Downing <nick@ndcode.org>
Wed, 12 Jan 2022 12:09:45 +0000 (23:09 +1100)
lib/ast.js
lib/mozilla-ast.js
lib/output.js
package.json

index 7632348..9c8c133 100644 (file)
@@ -2017,6 +2017,23 @@ var AST_True = DEFNODE("True", null, {
     value: true,
 }, AST_Boolean);
 
+// Nick
+var AST_Interpolate = DEFNODE("Interpolate", "expression", {
+    $documentation: "An interpolated expression. Used to for dropping computed values from server-side javascript into client-side javascript.",
+    $propdoc: {
+        expression: "[AST_Node] server-side expression to substitute",
+    },
+    walk: function(visitor) {
+        var node = this;
+        visitor.visit(node, function() {
+            node.expression.walk(visitor);
+        });
+    },
+    _validate: function() {
+        must_be_expression(this, "expression");
+    },
+});
+
 /* -----[ TreeWalker ]----- */
 
 function TreeWalker(callback) {
index 8cb3231..28e6138 100644 (file)
     map("AwaitExpression", AST_Await, "argument>expression");
     map("YieldExpression", AST_Yield, "argument>expression, delegate=nested");
 
+    // Nick
+    map("InterpolateExpression", AST_Interpolate, "argument>expression");
+
     def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
         return to_moz_scope("Program", M);
     });
index 6890632..6bb2200 100644 (file)
@@ -73,6 +73,8 @@ function OutputStream(options) {
         webkit           : false,
         width            : 80,
         wrap_iife        : false,
+        // Nick
+        interpolate      : false,
     }, true);
 
     // Convert comment option to RegExp if neccessary and set up comments filter
@@ -202,6 +204,8 @@ function OutputStream(options) {
             }
             return s;
         });
+        if (options.interpolate) // Nick
+            str = str.replace("\\", "\\\\").replace("${", "\\${")
         return quote_string(to_utf8(str), quote, dq, sq);
     }
 
@@ -611,6 +615,10 @@ function OutputStream(options) {
         parent          : function(n) {
             return stack[stack.length - 2 - (n || 0)];
         },
+        // Nick
+        interpolate     : function() {
+            return options.interpolate
+        }
     };
 }
 
@@ -1761,12 +1769,21 @@ function OutputStream(options) {
         if (self.tag) self.tag.print(output);
         output.print("`");
         for (var i = 0; i < self.expressions.length; i++) {
-            output.print(self.strings[i]);
-            output.print("${");
+            if (output.interpolate) { // Nick
+                output.print(self.strings[i].replace("\\", "\\\\").replace("${", "\\${"));
+                output.print("\\${");
+            }
+            else {
+                output.print(self.strings[i]);
+                output.print("${");
+            }
             self.expressions[i].print(output);
             output.print("}");
         }
-        output.print(self.strings[i]);
+        if (output.interpolate) // Nick
+            output.print(self.strings[i].replace("\\", "\\\\").replace("${", "\\${"));
+        else
+            output.print(self.strings[i]);
         output.print("`");
     });
     DEFPRINT(AST_Constant, function(output) {
@@ -1797,7 +1814,7 @@ function OutputStream(options) {
                 return match[0] == "\\" ? match : match.slice(0, -1) + "\\/";
             }) + str.slice(end);
         }
-        output.print(output.to_utf8(str).replace(/\\(?:\0(?![0-9])|[^\0])/g, function(match) {
+        str = output.to_utf8(str).replace(/\\(?:\0(?![0-9])|[^\0])/g, function(match) {
             switch (match[1]) {
               case "\n": return "\\n";
               case "\r": return "\\r";
@@ -1817,12 +1834,24 @@ function OutputStream(options) {
               case "\u2028": return "\\u2028";
               case "\u2029": return "\\u2029";
             }
-        }));
+        });
+        if (output.interpolate()) // Nick
+            str = str.replace("\\", "\\\\").replace("${", "\\${")
+        output.print(str);
         var p = output.parent();
         if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === this)
             output.print(" ");
     });
 
+    // Nick
+    DEFPRINT(AST_Interpolate, function(output) {
+        if (!output.interpolate()) // Nick
+            throw new Error("AST_Interpolate with interpolation turned off")
+        output.print("(${");
+        this.expression.print(output);
+        output.print("})");
+    });
+
     function force_statement(stat, output) {
         if (output.option("braces") && !(stat instanceof AST_Const || stat instanceof AST_Let)) {
             make_block(stat, output);
index 0636384..d78fa3f 100644 (file)
@@ -1,6 +1,6 @@
 {
-  "name": "uglify-js",
-  "description": "JavaScript parser, mangler/compressor and beautifier toolkit",
+  "name": "@ndcode/uglify-js",
+  "description": "JavaScript parser, mangler/compressor and beautifier toolkit, NDCODE",
   "author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
   "license": "BSD-2-Clause",
   "version": "3.14.5",