1
0
mirror of https://github.com/webrecorder/pywb.git synced 2025-03-15 00:03:28 +01:00

WIP: Add JS module handling code

This commit is contained in:
Tessa Walsh 2022-09-29 17:00:39 -04:00
parent c8e78fd7c1
commit dbf52c2579
3 changed files with 53 additions and 1 deletions

View File

@ -280,10 +280,31 @@ class JSWombatProxyRewriter(RegexRewriter):
self.last_buff = self.rules_factory.last_buff
self.local_objs = self.rules_factory.local_objs
@staticmethod
def is_module(string):
"""Return boolean indicating whether import or export statement is found."""
IMPORT_REGEX = r"^\s*?import\s*?[{\"']"
EXPORT_REGEX = r"^\s*?export\s*?({([\s\w,$\n]+?)}[\s;]*|default|class)\s+"
if not string:
return False
if "import" in string and re.search(IMPORT_REGEX, string):
return True
if "export" in string and re.search(EXPORT_REGEX, string):
return True
return False
def rewrite_complete(self, string, **kwargs):
if not kwargs.get('inline_attr'):
if self.is_module(string):
first_buff = "\nimport {} from '/static/__wb_module_decl.js';\n".format(
", ".join(obj for obj in self.local_objs)
)
return super(JSWombatProxyRewriter, self).rewrite_complete(string, first_buff=first_buff)
return super(JSWombatProxyRewriter, self).rewrite_complete(string)
# check if any of the wrapped objects are used in the script
# if not, don't rewrite
if not any(obj in string for obj in self.local_objs):

View File

@ -348,6 +348,7 @@ from pywb.rewrite.url_rewriter import UrlRewriter
from pywb.rewrite.regex_rewriters import RegexRewriter, JSRewriter, CSSRewriter, XMLRewriter, RxRules
from pywb.rewrite.regex_rewriters import JSWombatProxyRewriter
import pytest
urlrewriter = UrlRewriter('20131010/http://example.com/', '/web/', 'https://localhost/web/')
@ -367,6 +368,24 @@ def _test_xml(string):
def _test_css(string):
return CSSRewriter(urlrewriter).rewrite(string)
@pytest.mark.parametrize(
"string, expected_return",
[
# imports
("import './a-module.js'\n", True),
# exports
("export { name1 };\n", True),
("export default function functionName() { /* … */ }", True),
("export class ClassName { /* … */ };", True),
# not a module
("let counter = 0;\nconsole.log(counter);", False),
("", False),
(None, False)
]
)
def test_is_module(string, expected_return):
assert JSWombatProxyRewriter.is_module(string) == expected_return
if __name__ == "__main__":
import doctest
doctest.testmod()

View File

@ -0,0 +1,12 @@
var wrapObj = function(name) {return (self._wb_wombat && self._wb_wombat.local_init && self._wb_wombat.local_init(name)) || self[name]; };
if (!self.__WB_pmw) { self.__WB_pmw = function(obj) { this.__WB_source = obj; return this; } }
const window = wrapObj("window");
const document = wrapObj("document");
const location = wrapObj("location");
const top = wrapObj("top");
const parent = wrapObj("parent");
const frames = wrapObj("frames");
const opener = wrapObj("opener");
const __self = wrapObj("self");
const __globalThis = wrapObj("globalThis");
export { window, document, location, top, parent, frames, opener, __self as self, __globalThis as globalThis };