1313ZIM at `_zim_static/__wb_module_decl.js`
1414
1515This code is based on https://github.com/webrecorder/wabac.js/blob/main/src/rewrite/jsrewriter.ts
16- Last backport of upstream changes is from Oct 12, 2025
17- Commit 1849552c3dbcbc065c05afac2dd80061db37b64d
16+ Last backport of upstream changes is from wabac.js commit:
17+ Feb 20, 2026 - 25061cb53ff113d5cff28f2f1354819f6c41034b
1818"""
1919
2020import re
6767this_rw = "_____WB$wombat$check$this$function_____(this)"
6868
6969
70+ def remove_args_if_strict (
71+ target : str , opts : dict [str , Any ] | None , offset : int , full_string : str
72+ ) -> str :
73+ """
74+ Replace 'arguments' with '[]' if the code is in strict mode.
75+ In strict mode, the arguments keyword is not allowed.
76+ """
77+ opts = opts or {}
78+
79+ # Detect strict mode if not already set by checking for class declaration
80+ if "isStrict" not in opts :
81+ opts ["isStrict" ] = full_string [:offset ].find ("class " ) >= 0
82+ if opts .get ("isStrict" ):
83+ return target .replace ("arguments" , "[]" )
84+ return target
85+
86+
7087def add_suffix_non_prop (suffix : str ) -> TransformationAction :
7188 """
7289 Create a rewrite_function which add a `suffix` to the match str.
7390 The suffix is added only if the match is not preceded by `.` or `$`.
91+ Applies strict mode transformation to handle 'arguments' keyword.
7492 """
7593
76- def f (m_object : re .Match [str ], _opts : dict [str , Any ] | None ) -> str :
94+ def f (m_object : re .Match [str ], opts : dict [str , Any ] | None ) -> str :
7795 offset = m_object .start ()
78- if offset > 0 and m_object .string [offset - 1 ] in ".$" :
96+ full_string = m_object .string
97+ if offset > 0 and full_string [offset - 1 ] in ".$" :
7998 return m_object [0 ]
80- return m_object [0 ] + suffix
99+ return m_object [0 ] + remove_args_if_strict ( suffix , opts , offset , full_string )
81100
82101 return f
83102
@@ -145,7 +164,7 @@ def create_js_rules() -> list[TransformationRule]:
145164 # be set.
146165 check_loc = (
147166 "((self.__WB_check_loc && self.__WB_check_loc(location, arguments)) || "
148- "{}).href = "
167+ "{}).maybeHref = "
149168 )
150169
151170 # This will replace `eval(...)`.
@@ -258,6 +277,30 @@ def _get_module_decl(self, local_decls: Iterable[str]) -> str:
258277 f"""import {{ { ", " .join (local_decls )} }} from "{ wb_module_decl_url } ";\n """
259278 )
260279
280+ def _detect_strict_mode (self , text : str ) -> bool :
281+ """
282+ Detect if the JavaScript code is in strict mode.
283+
284+ Returns True if the code contains:
285+ - "use strict"; directive
286+ - import statements
287+ - export statements
288+ - class declarations
289+ """
290+ # Check for "use strict"; directive
291+ if '"use strict";' in text or "'use strict';" in text :
292+ return True
293+
294+ # Check for import or export statements
295+ if re .search (r"(?:^|\s)(?:im|ex)port\s+" , text ):
296+ return True
297+
298+ # Check for class declaration
299+ if re .search (r"\bclass\s+" , text ):
300+ return True
301+
302+ return False
303+
261304 def rewrite (self , text : str | bytes , opts : dict [str , Any ] | None = None ) -> str :
262305 """
263306 Rewrite the js code in `text`.
@@ -269,6 +312,14 @@ def rewrite(self, text: str | bytes, opts: dict[str, Any] | None = None) -> str:
269312
270313 is_module = opts .get ("isModule" , False )
271314
315+ # Detect and set strict mode
316+ # Modules are always strict mode
317+ if is_module :
318+ opts ["isStrict" ] = True
319+ elif "isStrict" not in opts :
320+ # Detect strict mode from the code itself
321+ opts ["isStrict" ] = self ._detect_strict_mode (text )
322+
272323 rules = REWRITE_JS_RULES [:]
273324
274325 if is_module :
0 commit comments