Skip to content

Commit bd5fc4c

Browse files
authored
implement mangle.properties.domprops (#5686)
- support destructuring syntax - fix corner case with comma operator
1 parent a570c00 commit bd5fc4c

File tree

15 files changed

+94
-38
lines changed

15 files changed

+94
-38
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,12 +891,15 @@ UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
891891

892892
### Mangle properties options
893893

894-
- `builtins` (default: `false`) — Use `true` to allow the mangling of builtin
895-
DOM properties. Not recommended to override this setting.
894+
- `builtins` (default: `false`) — Use `true` to allow the mangling of built-in
895+
properties of JavaScript API. Not recommended to override this setting.
896896

897897
- `debug` (default: `false`) — Mangle names with the original name still present.
898898
Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
899899

900+
- `domprops` (default: `false`) — Use `true` to allow the mangling of properties
901+
commonly found in Document Object Model. Not recommended to override this setting.
902+
900903
- `keep_fargs` (default: `false`) — Use `true` to prevent mangling of function
901904
arguments.
902905

bin/uglifyjs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -238,17 +238,6 @@ if (specified["beautify"] && specified["output-opts"]) fatal("--beautify cannot
238238
[ "compress", "mangle" ].forEach(function(name) {
239239
if (!(name in options)) options[name] = false;
240240
});
241-
if (options.mangle && options.mangle.properties) {
242-
if (options.mangle.properties.domprops) {
243-
delete options.mangle.properties.domprops;
244-
} else {
245-
if (typeof options.mangle.properties != "object") options.mangle.properties = {};
246-
if (!Array.isArray(options.mangle.properties.reserved)) options.mangle.properties.reserved = [];
247-
require("../tools/domprops").forEach(function(name) {
248-
UglifyJS.push_uniq(options.mangle.properties.reserved, name);
249-
});
250-
}
251-
}
252241
if (/^ast|spidermonkey$/.test(output)) {
253242
if (typeof options.output != "object") options.output = {};
254243
options.output.ast = true;

lib/propmangle.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ function get_builtins() {
124124

125125
function reserve_quoted_keys(ast, reserved) {
126126
ast.walk(new TreeWalker(function(node) {
127-
if (node instanceof AST_ClassProperty || node instanceof AST_ObjectProperty) {
127+
if (node instanceof AST_ClassProperty
128+
|| node instanceof AST_DestructuredKeyVal
129+
|| node instanceof AST_ObjectProperty) {
128130
if (node.key instanceof AST_Node) {
129131
addStrings(node.key, add);
130132
} else if (node.start && node.start.quote) {
@@ -158,12 +160,16 @@ function mangle_properties(ast, options) {
158160
builtins: false,
159161
cache: null,
160162
debug: false,
163+
domprops: false,
161164
keep_quoted: false,
162165
regex: null,
163166
reserved: null,
164167
}, true);
165168

166169
var reserved = options.builtins ? new Dictionary() : get_builtins();
170+
if (!options.domprops && typeof domprops !== "undefined") domprops.forEach(function(name) {
171+
reserved.set(name, true);
172+
});
167173
if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) {
168174
reserved.set(name, true);
169175
});
@@ -210,7 +216,9 @@ function mangle_properties(ast, options) {
210216
addStrings(node.args[0], add);
211217
break;
212218
}
213-
} else if (node instanceof AST_ClassProperty || node instanceof AST_ObjectProperty) {
219+
} else if (node instanceof AST_ClassProperty
220+
|| node instanceof AST_DestructuredKeyVal
221+
|| node instanceof AST_ObjectProperty) {
214222
if (node.key instanceof AST_Node) {
215223
addStrings(node.key, add);
216224
} else {
@@ -244,7 +252,9 @@ function mangle_properties(ast, options) {
244252
mangleStrings(node.args[0]);
245253
break;
246254
}
247-
} else if (node instanceof AST_ClassProperty || node instanceof AST_ObjectProperty) {
255+
} else if (node instanceof AST_ClassProperty
256+
|| node instanceof AST_DestructuredKeyVal
257+
|| node instanceof AST_ObjectProperty) {
248258
if (node.key instanceof AST_Node) {
249259
mangleStrings(node.key);
250260
} else {
@@ -307,7 +317,7 @@ function mangle_properties(ast, options) {
307317

308318
function mangleStrings(node) {
309319
if (node instanceof AST_Sequence) {
310-
mangleStrings(node.expressions.tail_node());
320+
mangleStrings(node.tail_node());
311321
} else if (node instanceof AST_String) {
312322
node.value = mangle(node.value);
313323
} else if (node instanceof AST_Conditional) {

test/compress.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,9 @@ function test_case(test) {
271271
expect = test.expect_exact;
272272
}
273273
var input = to_toplevel(test.input, test.mangle, test.expression);
274-
var input_code = make_code(input, {}, test.expression);
274+
var input_code = make_code(input, {
275+
keep_quoted_props: true,
276+
}, test.expression);
275277
var input_formatted = make_code(test.input, {
276278
annotations: true,
277279
beautify: true,

test/compress/classes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2164,6 +2164,7 @@ issue_4829_2: {
21642164
mangle_properties: {
21652165
mangle = {
21662166
properties: {
2167+
domprops: true,
21672168
keep_quoted: true,
21682169
},
21692170
}

test/compress/destructured.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,23 @@ singleton_side_effects: {
17371737
node_version: ">=6"
17381738
}
17391739

1740+
mangle_properties: {
1741+
mangle = {
1742+
properties: {
1743+
domprops: true,
1744+
},
1745+
}
1746+
input: {
1747+
function f({ p: a }) {
1748+
return a;
1749+
}
1750+
console.log(f({ p: "PASS" }));
1751+
}
1752+
expect_exact: 'function f({n}){return n}console.log(f({n:"PASS"}));'
1753+
expect_stdout: "PASS"
1754+
node_version: ">=6"
1755+
}
1756+
17401757
issue_4280: {
17411758
options = {
17421759
evaluate: true,

test/compress/issue-1321.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
issue_1321_no_debug: {
22
mangle = {
33
properties: {
4+
domprops: true,
45
keep_quoted: true,
56
},
67
}
@@ -23,6 +24,7 @@ issue_1321_debug: {
2324
mangle = {
2425
properties: {
2526
debug: "",
27+
domprops: true,
2628
keep_quoted: true,
2729
},
2830
}
@@ -44,6 +46,7 @@ issue_1321_debug: {
4446
issue_1321_with_quoted: {
4547
mangle = {
4648
properties: {
49+
domprops: true,
4750
keep_quoted: false,
4851
},
4952
}

test/compress/issue-1770.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ mangle_props: {
6565

6666
numeric_literal: {
6767
mangle = {
68-
properties: true,
68+
properties: {
69+
domprops: true,
70+
},
6971
}
7072
beautify = {
7173
beautify: true,
@@ -125,6 +127,7 @@ identifier: {
125127
mangle = {
126128
properties: {
127129
builtins: true,
130+
domprops: true,
128131
},
129132
}
130133
input: {

test/compress/issue-747.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
dont_reuse_prop: {
22
mangle = {
33
properties: {
4+
domprops: true,
45
regex: /asd/,
56
},
67
}
@@ -29,6 +30,7 @@ dont_reuse_prop: {
2930
unmangleable_props_should_always_be_reserved: {
3031
mangle = {
3132
properties: {
33+
domprops: true,
3234
regex: /asd/,
3335
},
3436
}

test/compress/objects.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ numeric_literal: {
173173
side_effects: true,
174174
}
175175
mangle = {
176-
properties: true,
176+
properties: {
177+
domprops: true,
178+
},
177179
}
178180
beautify = {
179181
beautify: true,

test/compress/properties.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ evaluate_string_length: {
133133
mangle_properties_1: {
134134
mangle = {
135135
properties: {
136+
domprops: true,
136137
keep_quoted: false,
137138
},
138139
}
@@ -155,9 +156,10 @@ mangle_properties_1: {
155156
mangle_properties_2: {
156157
mangle = {
157158
properties: {
159+
domprops: true,
158160
reserved: [
159161
"value",
160-
]
162+
],
161163
},
162164
}
163165
input: {
@@ -199,6 +201,24 @@ mangle_properties_2: {
199201
]
200202
}
201203

204+
mangle_properties_3: {
205+
mangle = {
206+
properties: true,
207+
}
208+
input: {
209+
console.log({
210+
[(console, "foo")]: "PASS",
211+
}.foo);
212+
}
213+
expect: {
214+
console.log({
215+
[(console, "o")]: "PASS",
216+
}.o);
217+
}
218+
expect_stdout: "PASS"
219+
node_version: ">=4"
220+
}
221+
202222
mangle_unquoted_properties: {
203223
options = {
204224
evaluate: true,
@@ -207,6 +227,7 @@ mangle_unquoted_properties: {
207227
mangle = {
208228
properties: {
209229
builtins: true,
230+
domprops: true,
210231
keep_quoted: true,
211232
},
212233
}
@@ -308,6 +329,7 @@ mangle_debug_suffix_keep_quoted: {
308329
properties: {
309330
builtins: true,
310331
debug: "XYZ",
332+
domprops: true,
311333
keep_quoted: true,
312334
reserved: [],
313335
},

test/mocha/let.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ describe("let", function() {
4242
compress: false,
4343
ie: true,
4444
mangle: {
45-
properties: true,
45+
properties: {
46+
domprops: true,
47+
},
4648
},
4749
});
4850
if (result.error) throw result.error;

test/mocha/minify.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,12 @@ describe("minify", function() {
110110
var result = UglifyJS.minify(code, {
111111
compress: false,
112112
mangle: {
113-
properties: true,
114-
toplevel: true
113+
properties: {
114+
domprops: true,
115+
},
116+
toplevel: true,
115117
},
116-
nameCache: cache
118+
nameCache: cache,
117119
});
118120
if (result.error) throw result.error;
119121
original += code;
@@ -188,21 +190,19 @@ describe("minify", function() {
188190
it("Shouldn't mangle quoted properties", function() {
189191
var js = 'a["foo"] = "bar"; a.color = "red"; x = {"bar": 10};';
190192
var result = UglifyJS.minify(js, {
191-
compress: {
192-
properties: false
193-
},
193+
compress: true,
194194
mangle: {
195195
properties: {
196-
keep_quoted: true
197-
}
196+
domprops: true,
197+
keep_quoted: true,
198+
},
198199
},
199200
output: {
200201
keep_quoted_props: true,
201-
quote_style: 3
202-
}
202+
quote_style: 3,
203+
},
203204
});
204-
assert.strictEqual(result.code,
205-
'a["foo"]="bar",a.a="red",x={"bar":10};');
205+
assert.strictEqual(result.code, 'a["foo"]="bar",a.a="red",x={"bar":10};');
206206
});
207207
it("Should not mangle quoted property within dead code", function() {
208208
var result = UglifyJS.minify('({ "keep": 1 }); g.keep = g.change = 42;', {

test/node.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
var fs = require("fs");
22

3-
new Function("exports", require("../tools/node").FILES.map(function(file) {
3+
new Function("domprops", "exports", require("../tools/node").FILES.map(function(file) {
44
if (/exports\.js$/.test(file)) file = require.resolve("./exports");
55
return fs.readFileSync(file, "utf8");
6-
}).join("\n\n"))(exports);
6+
}).join("\n\n"))(require("../tools/domprops.json"), exports);

tools/node.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ exports.FILES = [
1515
require.resolve("./exports.js"),
1616
];
1717

18-
new Function("exports", function() {
18+
new Function("domprops", "exports", function() {
1919
var code = exports.FILES.map(function(file) {
2020
return fs.readFileSync(file, "utf8");
2121
});
2222
code.push("exports.describe_ast = " + describe_ast.toString());
2323
return code.join("\n\n");
24-
}())(exports);
24+
}())(require("./domprops.json"), exports);
2525

2626
function to_comment(value) {
2727
if (typeof value != "string") value = JSON.stringify(value, function(key, value) {

0 commit comments

Comments
 (0)