From 57204e39cd24ecdb190a671bd3e163ff0c2ab983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Thu, 20 Jan 2022 16:06:23 +0900 Subject: [PATCH] fix(es/minifier): Don't inline functions used as arguments (#3320) swc_ecma_minifier: - Preserve a variable initialized with a function expression if it's used as an argument. --- .../classWithEmptyBody_es5.2.minified.js | 9 +- ...signableReturnExpression_es5.2.minified.js | 20 +++ ...WithConstructSignatures2_es5.2.minified.js | 8 + ...uresDifferingParamCounts_es5.2.minified.js | 8 + ...sDifferingByConstraints2_es5.2.minified.js | 10 ++ ...sDifferingByConstraints3_es5.2.minified.js | 6 + ...esDifferingByConstraints_es5.2.minified.js | 8 + ...esDifferingByReturnType2_es5.2.minified.js | 8 + ...resDifferingByReturnType_es5.2.minified.js | 8 + ...eringTypeParameterCounts_es5.2.minified.js | 8 + ...feringTypeParameterNames_es5.2.minified.js | 8 + ...ignaturesOptionalParams2_es5.2.minified.js | 8 + ...ignaturesOptionalParams3_es5.2.minified.js | 8 + ...SignaturesOptionalParams_es5.2.minified.js | 8 + .../scripts/next/evaluate.js | 2 +- crates/swc_ecma_minifier/src/analyzer/ctx.rs | 2 +- crates/swc_ecma_minifier/src/analyzer/mod.rs | 20 ++- .../src/analyzer/storage/mod.rs | 2 + .../src/analyzer/storage/normal.rs | 9 +- .../src/compress/optimize/collapse_vars.rs | 2 +- .../src/compress/optimize/hoist_props.rs | 2 +- .../src/compress/optimize/inline.rs | 17 ++- .../fixture/issues/2257/full/output.js | 18 +-- .../d6e1aeb5-38a8d7ae57119c23/output.js | 6 +- .../pages/no-spread-2db60295b526e113/input.js | 119 +++++++++++++++ .../no-spread-2db60295b526e113/output.js | 71 +++++++++ .../pages/spread-be872e60d968a0f7/input.js | 143 ++++++++++++++++++ .../pages/spread-be872e60d968a0f7/output.js | 86 +++++++++++ .../tests/projects/output/jquery-1.9.1.js | 8 +- .../projects/output/jquery.mobile-1.4.2.js | 10 +- 30 files changed, 601 insertions(+), 41 deletions(-) create mode 100644 crates/swc/tests/tsc-references/constructorWithAssignableReturnExpression_es5.2.minified.js create mode 100644 crates/swc/tests/tsc-references/objectTypesIdentityWithConstructSignatures2_es5.2.minified.js create mode 100644 crates/swc/tests/tsc-references/objectTypesIdentityWithConstructSignaturesDifferingParamCounts_es5.2.minified.js create mode 100644 crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints2_es5.2.minified.js create mode 100644 crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints_es5.2.minified.js create mode 100644 crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType2_es5.2.minified.js create mode 100644 crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType_es5.2.minified.js create mode 100644 crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterCounts_es5.2.minified.js create mode 100644 crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterNames_es5.2.minified.js create mode 100644 crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams2_es5.2.minified.js create mode 100644 crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams3_es5.2.minified.js create mode 100644 crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams_es5.2.minified.js create mode 100644 crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/no-spread-2db60295b526e113/input.js create mode 100644 crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/no-spread-2db60295b526e113/output.js create mode 100644 crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/spread-be872e60d968a0f7/input.js create mode 100644 crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/spread-be872e60d968a0f7/output.js diff --git a/crates/swc/tests/tsc-references/classWithEmptyBody_es5.2.minified.js b/crates/swc/tests/tsc-references/classWithEmptyBody_es5.2.minified.js index e6c7819e998..c94b51bbeb4 100644 --- a/crates/swc/tests/tsc-references/classWithEmptyBody_es5.2.minified.js +++ b/crates/swc/tests/tsc-references/classWithEmptyBody_es5.2.minified.js @@ -1,6 +1,9 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} var C = function() { "use strict"; - !function(instance, Constructor) { - if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); - }(this, C); + _classCallCheck(this, C); +}, D = function() { + return _classCallCheck(this, D), 1; }; diff --git a/crates/swc/tests/tsc-references/constructorWithAssignableReturnExpression_es5.2.minified.js b/crates/swc/tests/tsc-references/constructorWithAssignableReturnExpression_es5.2.minified.js new file mode 100644 index 00000000000..98df782b0de --- /dev/null +++ b/crates/swc/tests/tsc-references/constructorWithAssignableReturnExpression_es5.2.minified.js @@ -0,0 +1,20 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var C = function() { + return _classCallCheck(this, C), 1; +}, D = function() { + return _classCallCheck(this, D), 1; +}, E = function() { + return _classCallCheck(this, E), { + x: 1 + }; +}, F = function() { + return _classCallCheck(this, F), { + x: 1 + }; +}, G = function() { + return _classCallCheck(this, G), { + x: null + }; +}; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithConstructSignatures2_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithConstructSignatures2_es5.2.minified.js new file mode 100644 index 00000000000..a2f21d4595a --- /dev/null +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithConstructSignatures2_es5.2.minified.js @@ -0,0 +1,8 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var B = function(x) { + return _classCallCheck(this, B), null; +}, C = function(x) { + return _classCallCheck(this, C), null; +}; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithConstructSignaturesDifferingParamCounts_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithConstructSignaturesDifferingParamCounts_es5.2.minified.js new file mode 100644 index 00000000000..8f7131e0d0e --- /dev/null +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithConstructSignaturesDifferingParamCounts_es5.2.minified.js @@ -0,0 +1,8 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var B = function(x, y) { + return _classCallCheck(this, B), null; +}, C = function(x, y) { + return _classCallCheck(this, C), null; +}; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints2_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints2_es5.2.minified.js new file mode 100644 index 00000000000..39568eeb445 --- /dev/null +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints2_es5.2.minified.js @@ -0,0 +1,10 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var B = function(x, y) { + return _classCallCheck(this, B), null; +}, C = function(x, y) { + return _classCallCheck(this, C), null; +}, D = function(x, y) { + return _classCallCheck(this, D), null; +}; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints3_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints3_es5.2.minified.js index c6abdeb122d..91d3d2c957a 100644 --- a/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints3_es5.2.minified.js +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints3_es5.2.minified.js @@ -7,4 +7,10 @@ var One = function() { }, Two = function() { "use strict"; _classCallCheck(this, Two); +}, B = function(x, y) { + return _classCallCheck(this, B), null; +}, C = function(x, y) { + return _classCallCheck(this, C), null; +}, D = function(x, y) { + return _classCallCheck(this, D), null; }; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints_es5.2.minified.js new file mode 100644 index 00000000000..a2f21d4595a --- /dev/null +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByConstraints_es5.2.minified.js @@ -0,0 +1,8 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var B = function(x) { + return _classCallCheck(this, B), null; +}, C = function(x) { + return _classCallCheck(this, C), null; +}; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType2_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType2_es5.2.minified.js new file mode 100644 index 00000000000..a2f21d4595a --- /dev/null +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType2_es5.2.minified.js @@ -0,0 +1,8 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var B = function(x) { + return _classCallCheck(this, B), null; +}, C = function(x) { + return _classCallCheck(this, C), null; +}; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType_es5.2.minified.js new file mode 100644 index 00000000000..a2f21d4595a --- /dev/null +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingByReturnType_es5.2.minified.js @@ -0,0 +1,8 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var B = function(x) { + return _classCallCheck(this, B), null; +}, C = function(x) { + return _classCallCheck(this, C), null; +}; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterCounts_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterCounts_es5.2.minified.js new file mode 100644 index 00000000000..a2f21d4595a --- /dev/null +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterCounts_es5.2.minified.js @@ -0,0 +1,8 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var B = function(x) { + return _classCallCheck(this, B), null; +}, C = function(x) { + return _classCallCheck(this, C), null; +}; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterNames_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterNames_es5.2.minified.js new file mode 100644 index 00000000000..a2f21d4595a --- /dev/null +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterNames_es5.2.minified.js @@ -0,0 +1,8 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var B = function(x) { + return _classCallCheck(this, B), null; +}, C = function(x) { + return _classCallCheck(this, C), null; +}; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams2_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams2_es5.2.minified.js new file mode 100644 index 00000000000..8f7131e0d0e --- /dev/null +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams2_es5.2.minified.js @@ -0,0 +1,8 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var B = function(x, y) { + return _classCallCheck(this, B), null; +}, C = function(x, y) { + return _classCallCheck(this, C), null; +}; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams3_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams3_es5.2.minified.js new file mode 100644 index 00000000000..8f7131e0d0e --- /dev/null +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams3_es5.2.minified.js @@ -0,0 +1,8 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var B = function(x, y) { + return _classCallCheck(this, B), null; +}, C = function(x, y) { + return _classCallCheck(this, C), null; +}; diff --git a/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams_es5.2.minified.js b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams_es5.2.minified.js new file mode 100644 index 00000000000..8f7131e0d0e --- /dev/null +++ b/crates/swc/tests/tsc-references/objectTypesIdentityWithGenericConstructSignaturesOptionalParams_es5.2.minified.js @@ -0,0 +1,8 @@ +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); +} +var B = function(x, y) { + return _classCallCheck(this, B), null; +}, C = function(x, y) { + return _classCallCheck(this, C), null; +}; diff --git a/crates/swc_ecma_minifier/scripts/next/evaluate.js b/crates/swc_ecma_minifier/scripts/next/evaluate.js index 5876b71d8fa..90998f3fc76 100644 --- a/crates/swc_ecma_minifier/scripts/next/evaluate.js +++ b/crates/swc_ecma_minifier/scripts/next/evaluate.js @@ -11,7 +11,7 @@ const rl = readline.createInterface({ rl.on('line', async (data) => { try { const { name, source } = eval(`(${data})`) - const targetPath = path.join(__dirname, '..', '..', 'tests', 'compress', 'fixture', 'issues', 'next', name.replace('.js', ''), 'input.js'); + const targetPath = path.join(__dirname, '..', '..', 'tests', 'compress', 'fixture', 'next', 'raw', name.replace('.js', ''), 'input.js'); await fs.mkdir(path.dirname(targetPath), { recursive: true }); diff --git a/crates/swc_ecma_minifier/src/analyzer/ctx.rs b/crates/swc_ecma_minifier/src/analyzer/ctx.rs index 7834562feac..3009886b3cd 100644 --- a/crates/swc_ecma_minifier/src/analyzer/ctx.rs +++ b/crates/swc_ecma_minifier/src/analyzer/ctx.rs @@ -45,7 +45,7 @@ pub(crate) struct Ctx { pub(super) in_left_of_for_loop: bool, - pub(super) in_loop: bool, + pub(super) executed_multiple_time: bool, /// Are we handling argument of an update expression. pub(super) in_update_arg: bool, pub(super) in_assign_lhs: bool, diff --git a/crates/swc_ecma_minifier/src/analyzer/mod.rs b/crates/swc_ecma_minifier/src/analyzer/mod.rs index 6ba7b53efc0..7b6972697d9 100644 --- a/crates/swc_ecma_minifier/src/analyzer/mod.rs +++ b/crates/swc_ecma_minifier/src/analyzer/mod.rs @@ -92,7 +92,7 @@ pub(crate) struct VarUsageInfo { used_by_nested_fn: bool, - pub used_in_loop: bool, + pub executed_multiple_time: bool, pub used_in_cond: bool, pub var_kind: Option, @@ -104,6 +104,8 @@ pub(crate) struct VarUsageInfo { pub used_as_callee: bool, + pub used_as_arg: bool, + /// In `c = b`, `b` infects `c`. infects: Vec, } @@ -318,6 +320,12 @@ where n.args.visit_with(&mut *self.with_ctx(ctx)); } + for arg in &n.args { + if let Expr::Ident(arg) = &*arg.expr { + self.data.var_or_default(arg.to_id()).mark_used_as_arg(); + } + } + if let Callee::Expr(callee) = &n.callee { match &**callee { Expr::Ident(Ident { sym, .. }) if *sym == *"eval" => { @@ -400,7 +408,7 @@ where fn visit_do_while_stmt(&mut self, n: &DoWhileStmt) { let ctx = Ctx { - in_loop: true, + executed_multiple_time: true, in_cond: true, ..self.ctx }; @@ -481,7 +489,7 @@ where n.right.visit_with(child); let ctx = Ctx { - in_loop: true, + executed_multiple_time: true, in_cond: true, ..child.ctx }; @@ -501,7 +509,7 @@ where n.left.visit_with(&mut *child.with_ctx(ctx)); let ctx = Ctx { - in_loop: true, + executed_multiple_time: true, in_cond: true, ..child.ctx }; @@ -513,7 +521,7 @@ where n.init.visit_with(self); let ctx = Ctx { - in_loop: true, + executed_multiple_time: true, in_cond: true, ..self.ctx }; @@ -836,7 +844,7 @@ where fn visit_while_stmt(&mut self, n: &WhileStmt) { let ctx = Ctx { - in_loop: true, + executed_multiple_time: true, in_cond: true, ..self.ctx }; diff --git a/crates/swc_ecma_minifier/src/analyzer/storage/mod.rs b/crates/swc_ecma_minifier/src/analyzer/storage/mod.rs index aa92b1af708..7a9a8a8a42a 100644 --- a/crates/swc_ecma_minifier/src/analyzer/storage/mod.rs +++ b/crates/swc_ecma_minifier/src/analyzer/storage/mod.rs @@ -51,6 +51,8 @@ pub(crate) trait VarDataLike: Sized { fn mark_used_as_callee(&mut self); + fn mark_used_as_arg(&mut self); + fn add_accessed_property(&mut self, name: JsWord); fn mark_mutated(&mut self); diff --git a/crates/swc_ecma_minifier/src/analyzer/storage/normal.rs b/crates/swc_ecma_minifier/src/analyzer/storage/normal.rs index 2916efbe8b2..e3695b1ba5c 100644 --- a/crates/swc_ecma_minifier/src/analyzer/storage/normal.rs +++ b/crates/swc_ecma_minifier/src/analyzer/storage/normal.rs @@ -53,7 +53,7 @@ impl Storage for ProgramData { // usages. // // e.get_mut().used_above_decl |= var_info.used_above_decl; - e.get_mut().used_in_loop |= var_info.used_in_loop; + e.get_mut().executed_multiple_time |= var_info.executed_multiple_time; e.get_mut().used_in_cond |= var_info.used_in_cond; e.get_mut().assign_count += var_info.assign_count; e.get_mut().mutation_by_call_count += var_info.mutation_by_call_count; @@ -68,6 +68,7 @@ impl Storage for ProgramData { && var_info.no_side_effect_for_member_access; e.get_mut().used_as_callee |= var_info.used_as_callee; + e.get_mut().used_as_arg |= var_info.used_as_arg; match kind { ScopeKind::Fn => { @@ -188,7 +189,7 @@ impl ProgramData { e.reassigned |= is_first && is_modify && ctx.is_exact_reassignment; // Passing object as a argument is possibly modification. e.mutated |= is_modify || (ctx.in_call_arg && ctx.is_exact_arg); - e.used_in_loop |= ctx.in_loop; + e.executed_multiple_time |= ctx.executed_multiple_time; e.used_in_cond |= ctx.in_cond; if is_modify && ctx.is_exact_reassignment { @@ -232,6 +233,10 @@ impl VarDataLike for VarUsageInfo { self.used_as_callee = true; } + fn mark_used_as_arg(&mut self) { + self.used_as_arg = true + } + fn add_accessed_property(&mut self, name: swc_atoms::JsWord) { self.accessed_props.insert(name); } diff --git a/crates/swc_ecma_minifier/src/compress/optimize/collapse_vars.rs b/crates/swc_ecma_minifier/src/compress/optimize/collapse_vars.rs index edecc02aabe..e80cec75493 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/collapse_vars.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/collapse_vars.rs @@ -41,7 +41,7 @@ where return; } - if usage.used_in_loop || usage.used_in_cond { + if usage.executed_multiple_time || usage.used_in_cond { match &*assign.right { Expr::Lit(..) | Expr::Ident(..) => {} _ => return, diff --git a/crates/swc_ecma_minifier/src/compress/optimize/hoist_props.rs b/crates/swc_ecma_minifier/src/compress/optimize/hoist_props.rs index fc2d6a47b67..1c10ff84414 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/hoist_props.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/hoist_props.rs @@ -117,7 +117,7 @@ where v.ref_count == 1 && v.has_property_access && v.is_fn_local - && !v.used_in_loop + && !v.executed_multiple_time && !v.used_in_cond }) }) diff --git a/crates/swc_ecma_minifier/src/compress/optimize/inline.rs b/crates/swc_ecma_minifier/src/compress/optimize/inline.rs index 2eb125dc783..767505a4380 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/inline.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/inline.rs @@ -232,7 +232,7 @@ where } match &**init { Expr::Lit(Lit::Regex(..)) => { - if !usage.is_fn_local || usage.used_in_loop { + if !usage.is_fn_local || usage.executed_multiple_time { return; } } @@ -247,7 +247,13 @@ where _ => {} } - if usage.used_in_loop { + if usage.used_as_arg && !usage.is_fn_local { + if let Expr::Fn(..) = &**init { + return; + } + } + + if usage.executed_multiple_time { match &**init { Expr::Lit(..) | Expr::Fn(..) => {} _ => { @@ -261,8 +267,9 @@ where } tracing::debug!( - "inline: Decided to inline var '{}' because it's used only once", - i.id + "inline: Decided to inline var '{}' because it's used only once {:?}", + i.id, + usage ); self.changed = true; self.vars_for_inlining.insert(i.to_id(), init.take()); @@ -466,7 +473,7 @@ where if (self.options.reduce_vars || self.options.collapse_vars || self.options.inline != 0) && usage.ref_count == 1 && (usage.is_fn_local || (usage.used_as_callee && !usage.used_above_decl)) - && !usage.used_in_loop + && !usage.executed_multiple_time && !usage.inline_prevented && (match decl { Decl::Class(..) => !usage.used_above_decl, diff --git a/crates/swc_ecma_minifier/tests/compress/fixture/issues/2257/full/output.js b/crates/swc_ecma_minifier/tests/compress/fixture/issues/2257/full/output.js index 03810d89431..4e4042a408b 100644 --- a/crates/swc_ecma_minifier/tests/compress/fixture/issues/2257/full/output.js +++ b/crates/swc_ecma_minifier/tests/compress/fixture/issues/2257/full/output.js @@ -2774,6 +2774,10 @@ ]; }, unpackInt32 = function(buffer) { return buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0]; + }, packFloat32 = function(number) { + return packIEEE754(number, 23, 4); + }, packFloat64 = function(number) { + return packIEEE754(number, 52, 8); }, addGetter = function(Constructor, key) { defineProperty(Constructor[PROTOTYPE], key, { get: function() { @@ -2879,14 +2883,10 @@ set(this, 4, byteOffset, packInt32, value, arguments.length > 2 ? arguments[2] : void 0); }, setFloat32: function(byteOffset, value) { - set(this, 4, byteOffset, function(number) { - return packIEEE754(number, 23, 4); - }, value, arguments.length > 2 ? arguments[2] : void 0); + set(this, 4, byteOffset, packFloat32, value, arguments.length > 2 ? arguments[2] : void 0); }, setFloat64: function(byteOffset, value) { - set(this, 8, byteOffset, function(number) { - return packIEEE754(number, 52, 8); - }, value, arguments.length > 2 ? arguments[2] : void 0); + set(this, 8, byteOffset, packFloat64, value, arguments.length > 2 ? arguments[2] : void 0); } }); setToStringTag($ArrayBuffer, ARRAY_BUFFER), setToStringTag($DataView, DATA_VIEW), module.exports = { @@ -8406,10 +8406,10 @@ ")": "%29", "~": "%7E", "%20": "+" + }, replacer = function(match) { + return replace[match]; }, serialize = function(it) { - return encodeURIComponent(it).replace(find, function(match) { - return replace[match]; - }); + return encodeURIComponent(it).replace(find, replacer); }, parseSearchParams = function(result, query) { if (query) for(var attribute, entry, attributes = query.split("&"), index = 0; index < attributes.length;)(attribute = attributes[index++]).length && (entry = attribute.split("="), result.push({ key: deserialize(entry.shift()), diff --git a/crates/swc_ecma_minifier/tests/compress/fixture/next/33265/static/chunks/d6e1aeb5-38a8d7ae57119c23/output.js b/crates/swc_ecma_minifier/tests/compress/fixture/next/33265/static/chunks/d6e1aeb5-38a8d7ae57119c23/output.js index 1e1ed825f58..9fb4b821fa9 100644 --- a/crates/swc_ecma_minifier/tests/compress/fixture/next/33265/static/chunks/d6e1aeb5-38a8d7ae57119c23/output.js +++ b/crates/swc_ecma_minifier/tests/compress/fixture/next/33265/static/chunks/d6e1aeb5-38a8d7ae57119c23/output.js @@ -7135,6 +7135,8 @@ }, formatHexString = function(e, i) { var value = e.toString(16); return "00".substring(0, 2 - value.length) + value + (i % 2 ? " " : ""); + }, formatAsciiString = function(e) { + return e >= 32 && e < 126 ? String.fromCharCode(e) : "."; }, createTransferableMessage1 = function(message) { var transferable = {}; return Object.keys(message).forEach(function(key) { @@ -7158,9 +7160,7 @@ }, segmentKeyId = function(key) { return key.resolvedUri; }, hexDump = function(data) { - for(var hex, ascii, bytes = Array.prototype.slice.call(data), result = "", j = 0; j < bytes.length / 16; j++)hex = bytes.slice(16 * j, 16 * j + 16).map(formatHexString).join(""), ascii = bytes.slice(16 * j, 16 * j + 16).map(function(e) { - return e >= 32 && e < 126 ? String.fromCharCode(e) : "."; - }).join(""), result += hex + " " + ascii + "\n"; + for(var hex, ascii, bytes = Array.prototype.slice.call(data), result = "", j = 0; j < bytes.length / 16; j++)hex = bytes.slice(16 * j, 16 * j + 16).map(formatHexString).join(""), ascii = bytes.slice(16 * j, 16 * j + 16).map(formatAsciiString).join(""), result += hex + " " + ascii + "\n"; return result; }, utils1 = Object.freeze({ __proto__: null, diff --git a/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/no-spread-2db60295b526e113/input.js b/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/no-spread-2db60295b526e113/input.js new file mode 100644 index 00000000000..baa278d5ae7 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/no-spread-2db60295b526e113/input.js @@ -0,0 +1,119 @@ +(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([[492],{ + +/***/ 5467: +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + + + (window.__NEXT_P = window.__NEXT_P || []).push([ + "/no-spread", + function () { + return __webpack_require__(1918); + } + ]); + if(false) {} + + +/***/ }), + +/***/ 2726: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": function() { return /* binding */ components_Form; } +}); + +// EXTERNAL MODULE: ./node_modules/react/jsx-runtime.js +var jsx_runtime = __webpack_require__(5893); +// EXTERNAL MODULE: ./node_modules/react/index.js +var react = __webpack_require__(7294); +;// CONCATENATED MODULE: ./components/Input.js + +function Input(param) { + var value = param.value, onChange = param.onChange; + return(/*#__PURE__*/ (0,jsx_runtime.jsx)("input", { + value: value, + onChange: onChange + })); +} +/* harmony default export */ var components_Input = (Input); + +;// CONCATENATED MODULE: ./components/Form.js + + + +function Form(param) { + var value = param.value, onChange = param.onChange; + (0,react.useEffect)(function() { + // If parent component spreads the props, + // will cause remount on every re-render + console.log('EFFECT'); + }, []); + return(/*#__PURE__*/ (0,jsx_runtime.jsx)(components_Input, { + value: value, + onChange: onChange + })); +} +/* harmony default export */ var components_Form = (Form); + + +/***/ }), + +/***/ 1918: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +// ESM COMPAT FLAG +__webpack_require__.r(__webpack_exports__); + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "default": function() { return /* binding */ PageWithNoSpread; } +}); + +// EXTERNAL MODULE: ./node_modules/react/jsx-runtime.js +var jsx_runtime = __webpack_require__(5893); +// EXTERNAL MODULE: ./node_modules/react/index.js +var react = __webpack_require__(7294); +// EXTERNAL MODULE: ./components/Form.js + 1 modules +var Form = __webpack_require__(2726); +;// CONCATENATED MODULE: ./components/NoSpread.js + + +function ContainerNoSpread(param) { + var value = param.value, onChange = param.onChange; + return(/*#__PURE__*/ (0,jsx_runtime.jsx)(Form/* default */.Z, { + value: value, + onChange: onChange + })); +} +/* harmony default export */ var NoSpread = (ContainerNoSpread); + +;// CONCATENATED MODULE: ./pages/no-spread.js + + + +function PageWithNoSpread() { + var ref = (0,react.useState)(''), text = ref[0], setText = ref[1]; + var handleChange = (0,react.useCallback)(function(e) { + setText(e.target.value); + }, []); + return(/*#__PURE__*/ (0,jsx_runtime.jsx)(NoSpread, { + onChange: handleChange, + value: text + })); +}; + + +/***/ }) + +}, +/******/ function(__webpack_require__) { // webpackRuntimeModules +/******/ var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId); } +/******/ __webpack_require__.O(0, [774,888,179], function() { return __webpack_exec__(5467); }); +/******/ var __webpack_exports__ = __webpack_require__.O(); +/******/ _N_E = __webpack_exports__; +/******/ } +]); \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/no-spread-2db60295b526e113/output.js b/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/no-spread-2db60295b526e113/output.js new file mode 100644 index 00000000000..89dd8917ba8 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/no-spread-2db60295b526e113/output.js @@ -0,0 +1,71 @@ +(self.webpackChunk_N_E = self.webpackChunk_N_E || []).push([ + [ + 492 + ], + { + 5467: function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + (window.__NEXT_P = window.__NEXT_P || []).push([ + "/no-spread", + function() { + return __webpack_require__(1918); + } + ]); + }, + 2726: function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.d(__webpack_exports__, { + Z: function() { + return components_Form; + } + }); + var jsx_runtime = __webpack_require__(5893), react = __webpack_require__(7294), components_Input = function(param) { + var value = param.value, onChange = param.onChange; + return (0, jsx_runtime.jsx)("input", { + value: value, + onChange: onChange + }); + }, components_Form = function(param) { + var value = param.value, onChange = param.onChange; + return (0, react.useEffect)(function() { + console.log("EFFECT"); + }, []), (0, jsx_runtime.jsx)(components_Input, { + value: value, + onChange: onChange + }); + }; + }, + 1918: function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__), __webpack_require__.d(__webpack_exports__, { + "default": function() { + return PageWithNoSpread; + } + }); + var jsx_runtime = __webpack_require__(5893), react = __webpack_require__(7294), Form = __webpack_require__(2726), NoSpread = function(param) { + var value = param.value, onChange = param.onChange; + return (0, jsx_runtime.jsx)(Form.Z, { + value: value, + onChange: onChange + }); + }; + function PageWithNoSpread() { + var ref = (0, react.useState)(""), text = ref[0], setText = ref[1], handleChange = (0, react.useCallback)(function(e) { + setText(e.target.value); + }, []); + return (0, jsx_runtime.jsx)(NoSpread, { + onChange: handleChange, + value: text + }); + } + } + }, + function(__webpack_require__) { + __webpack_require__.O(0, [ + 774, + 888, + 179 + ], function() { + return __webpack_require__(__webpack_require__.s = 5467); + }), _N_E = __webpack_require__.O(); + } +]); diff --git a/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/spread-be872e60d968a0f7/input.js b/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/spread-be872e60d968a0f7/input.js new file mode 100644 index 00000000000..288db772e1a --- /dev/null +++ b/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/spread-be872e60d968a0f7/input.js @@ -0,0 +1,143 @@ +(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([[217],{ + +/***/ 2809: +/***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + + + (window.__NEXT_P = window.__NEXT_P || []).push([ + "/spread", + function () { + return __webpack_require__(1767); + } + ]); + if(false) {} + + +/***/ }), + +/***/ 2726: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": function() { return /* binding */ components_Form; } +}); + +// EXTERNAL MODULE: ./node_modules/react/jsx-runtime.js +var jsx_runtime = __webpack_require__(5893); +// EXTERNAL MODULE: ./node_modules/react/index.js +var react = __webpack_require__(7294); +;// CONCATENATED MODULE: ./components/Input.js + +function Input(param) { + var value = param.value, onChange = param.onChange; + return(/*#__PURE__*/ (0,jsx_runtime.jsx)("input", { + value: value, + onChange: onChange + })); +} +/* harmony default export */ var components_Input = (Input); + +;// CONCATENATED MODULE: ./components/Form.js + + + +function Form(param) { + var value = param.value, onChange = param.onChange; + (0,react.useEffect)(function() { + // If parent component spreads the props, + // will cause remount on every re-render + console.log('EFFECT'); + }, []); + return(/*#__PURE__*/ (0,jsx_runtime.jsx)(components_Input, { + value: value, + onChange: onChange + })); +} +/* harmony default export */ var components_Form = (Form); + + +/***/ }), + +/***/ 1767: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +// ESM COMPAT FLAG +__webpack_require__.r(__webpack_exports__); + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "default": function() { return /* binding */ PageWithSpread; } +}); + +// EXTERNAL MODULE: ./node_modules/react/jsx-runtime.js +var jsx_runtime = __webpack_require__(5893); +// EXTERNAL MODULE: ./node_modules/react/index.js +var react = __webpack_require__(7294); +// EXTERNAL MODULE: ./components/Form.js + 1 modules +var Form = __webpack_require__(2726); +;// CONCATENATED MODULE: ./components/Container.js + + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; +} +function _objectSpread(target) { + for(var i = 1; i < arguments.length; i++){ + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); + if (typeof Object.getOwnPropertySymbols === "function") { + ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + } + ownKeys.forEach(function(key) { + _defineProperty(target, key, source[key]); + }); + } + return target; +} +function Container(props) { + return(/*#__PURE__*/ (0,jsx_runtime.jsx)(Form/* default */.Z, _objectSpread({}, props))); +} +/* harmony default export */ var components_Container = (Container); + +;// CONCATENATED MODULE: ./pages/spread.js + + + +function PageWithSpread() { + var ref = (0,react.useState)(''), text = ref[0], setText = ref[1]; + var handleChange = (0,react.useCallback)(function(e) { + setText(e.target.value); + }, []); + return(/*#__PURE__*/ (0,jsx_runtime.jsx)(components_Container, { + onChange: handleChange, + value: text + })); +}; + + +/***/ }) + +}, +/******/ function(__webpack_require__) { // webpackRuntimeModules +/******/ var __webpack_exec__ = function(moduleId) { return __webpack_require__(__webpack_require__.s = moduleId); } +/******/ __webpack_require__.O(0, [774,888,179], function() { return __webpack_exec__(2809); }); +/******/ var __webpack_exports__ = __webpack_require__.O(); +/******/ _N_E = __webpack_exports__; +/******/ } +]); \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/spread-be872e60d968a0f7/output.js b/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/spread-be872e60d968a0f7/output.js new file mode 100644 index 00000000000..e65c1d25afd --- /dev/null +++ b/crates/swc_ecma_minifier/tests/compress/fixture/next/33458/static/chunks/pages/spread-be872e60d968a0f7/output.js @@ -0,0 +1,86 @@ +(self.webpackChunk_N_E = self.webpackChunk_N_E || []).push([ + [ + 217 + ], + { + 2809: function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { + (window.__NEXT_P = window.__NEXT_P || []).push([ + "/spread", + function() { + return __webpack_require__(1767); + } + ]); + }, + 2726: function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.d(__webpack_exports__, { + Z: function() { + return components_Form; + } + }); + var jsx_runtime = __webpack_require__(5893), react = __webpack_require__(7294), components_Input = function(param) { + var value = param.value, onChange = param.onChange; + return (0, jsx_runtime.jsx)("input", { + value: value, + onChange: onChange + }); + }, components_Form = function(param) { + var value = param.value, onChange = param.onChange; + return (0, react.useEffect)(function() { + console.log("EFFECT"); + }, []), (0, jsx_runtime.jsx)(components_Input, { + value: value, + onChange: onChange + }); + }; + }, + 1767: function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + "use strict"; + __webpack_require__.r(__webpack_exports__), __webpack_require__.d(__webpack_exports__, { + "default": function() { + return PageWithSpread; + } + }); + var jsx_runtime = __webpack_require__(5893), react = __webpack_require__(7294), Form = __webpack_require__(2726); + function _defineProperty(obj, key, value) { + return key in obj ? Object.defineProperty(obj, key, { + value: value, + enumerable: !0, + configurable: !0, + writable: !0 + }) : obj[key] = value, obj; + } + var components_Container = function(props) { + return (0, jsx_runtime.jsx)(Form.Z, function(target) { + for(var i = 1; i < arguments.length; i++){ + var source = null != arguments[i] ? arguments[i] : {}, ownKeys = Object.keys(source); + "function" == typeof Object.getOwnPropertySymbols && (ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + }))), ownKeys.forEach(function(key) { + _defineProperty(target, key, source[key]); + }); + } + return target; + }({}, props)); + }; + function PageWithSpread() { + var ref = (0, react.useState)(""), text = ref[0], setText = ref[1], handleChange = (0, react.useCallback)(function(e) { + setText(e.target.value); + }, []); + return (0, jsx_runtime.jsx)(components_Container, { + onChange: handleChange, + value: text + }); + } + } + }, + function(__webpack_require__) { + __webpack_require__.O(0, [ + 774, + 888, + 179 + ], function() { + return __webpack_require__(__webpack_require__.s = 2809); + }), _N_E = __webpack_require__.O(); + } +]); diff --git a/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js b/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js index 0d523c82479..f7d17426c96 100644 --- a/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js +++ b/crates/swc_ecma_minifier/tests/projects/output/jquery-1.9.1.js @@ -1,7 +1,9 @@ !function(window1, undefined1) { var readyList, rootjQuery1, core_strundefined = "undefined", document1 = window1.document, location = window1.location, _jQuery = window1.jQuery, _$ = window1.$, class2type = {}, core_deletedIds = [], core_version = "1.9.1", core_concat = core_deletedIds.concat, core_push = core_deletedIds.push, core_slice = core_deletedIds.slice, core_indexOf = core_deletedIds.indexOf, core_toString = class2type.toString, core_hasOwn = class2type.hasOwnProperty, core_trim = core_version.trim, jQuery = function(selector, context) { return new jQuery.fn.init(selector, context, rootjQuery1); - }, core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, core_rnotwhite = /\S+/g, rtrim1 = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, rquickExpr1 = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/, rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, rvalidchars = /^[\],:{}\s]*$/, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, rmsPrefix = /^-ms-/, rdashAlpha = /-([\da-z])/gi, completed = function(event) { + }, core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, core_rnotwhite = /\S+/g, rtrim1 = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, rquickExpr1 = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/, rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, rvalidchars = /^[\],:{}\s]*$/, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, rmsPrefix = /^-ms-/, rdashAlpha = /-([\da-z])/gi, fcamelCase = function(all, letter) { + return letter.toUpperCase(); + }, completed = function(event) { (document1.addEventListener || "load" === event.type || "complete" === document1.readyState) && (detach(), jQuery.ready()); }, detach = function() { document1.addEventListener ? (document1.removeEventListener("DOMContentLoaded", completed, !1), window1.removeEventListener("load", completed, !1)) : (document1.detachEvent("onreadystatechange", completed), window1.detachEvent("onload", completed)); @@ -168,9 +170,7 @@ })(data1); }, camelCase: function(string) { - return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, function(all, letter) { - return letter.toUpperCase(); - }); + return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase); }, nodeName: function(elem, name) { return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); diff --git a/crates/swc_ecma_minifier/tests/projects/output/jquery.mobile-1.4.2.js b/crates/swc_ecma_minifier/tests/projects/output/jquery.mobile-1.4.2.js index 20ae4543256..8ae4adfbf03 100644 --- a/crates/swc_ecma_minifier/tests/projects/output/jquery.mobile-1.4.2.js +++ b/crates/swc_ecma_minifier/tests/projects/output/jquery.mobile-1.4.2.js @@ -5,7 +5,7 @@ return factory($, root, doc), $.mobile; }) : factory(root.jQuery, root, doc); }(this, document, function(jQuery, window3, document1, undefined9) { - var $27, nsNormalizeDict, oldFind, rbrace, jqmDataRE, $1, window1, compensateToolbars, $2, undefined1, uuid1, slice, _cleanData, $3, rcapitals, $4, doc1, bool, docElem, refNode, fakeBody1, div1, $5, support1, $6, self1, $win1, dummyFnToInitNavigate, $7, undefined2, path2, $base, dialogHashKey, $8, undefined3, $9, path1, initialHref, $10, undefined4, props1, testElement, vendorPrefixes, $11, heldCall, curr, diff1, handler1, lastCall, $12, baseElement, base1, $13, undefined5, originalWidget, keepNativeFactoryDefault, orig1, $14, undefined6, pageTransitionQueue, isPageTransitioning, $15, window2, $16, $17, $18, $19, $20, $21, undefined7, rInitialLetter, iconposClass1, $22, $23, $24, meta, initialContent1, disabledZoom, enabledZoom, disabledInitially, $25, $26, undefined8, rDividerListItem, origDefaultFilterCallback; + var $27, nsNormalizeDict, oldFind, rbrace, jqmDataRE, $1, window1, compensateToolbars, $2, undefined1, uuid1, slice, _cleanData, $3, rcapitals, replaceFunction, $4, doc1, bool, docElem, refNode, fakeBody1, div1, $5, support1, $6, self1, $win1, dummyFnToInitNavigate, $7, undefined2, path2, $base, dialogHashKey, $8, undefined3, $9, path1, initialHref, $10, undefined4, props1, testElement, vendorPrefixes, $11, heldCall, curr, diff1, handler1, lastCall, $12, baseElement, base1, $13, undefined5, originalWidget, keepNativeFactoryDefault, orig1, $14, undefined6, pageTransitionQueue, isPageTransitioning, $15, window2, $16, $17, $18, $19, $20, $21, undefined7, rInitialLetter, iconposClass1, $22, $23, $24, meta, initialContent1, disabledZoom, enabledZoom, disabledInitially, $25, $26, undefined8, rDividerListItem, origDefaultFilterCallback; jQuery.mobile = {}, (function($, window, undefined) { $.extend($.mobile, { version: "1.4.2", @@ -485,12 +485,12 @@ $2(this)[method](), callback && callback.call(element[0]), next(); }); }; - }), rcapitals = /[A-Z]/g, ($3 = jQuery).extend($3.Widget.prototype, { + }), $3 = jQuery, rcapitals = /[A-Z]/g, replaceFunction = function(c) { + return "-" + c.toLowerCase(); + }, $3.extend($3.Widget.prototype, { _getCreateOptions: function() { var option, value, elem = this.element[0], options = {}; - if (!$3.mobile.getAttribute(elem, "defaults")) for(option in this.options)null != (value = $3.mobile.getAttribute(elem, option.replace(rcapitals, function(c) { - return "-" + c.toLowerCase(); - }))) && (options[option] = value); + if (!$3.mobile.getAttribute(elem, "defaults")) for(option in this.options)null != (value = $3.mobile.getAttribute(elem, option.replace(rcapitals, replaceFunction))) && (options[option] = value); return options; } }), $3.mobile.widget = $3.Widget, (function($) {