webrecorder / pywb

Core Python Web Archiving Toolkit for replay and recording of web archives
https://pypi.python.org/pypi/pywb
GNU General Public License v3.0
1.34k stars 207 forks source link

jquery rewriting causes error #850

Closed mona-ul closed 3 months ago

mona-ul commented 1 year ago

Description

Since an update of pywb I have an object with a jquery problem. It seems to be a rewritting issue. The issue occurs since pywb 2.6.9. Everything workes fine in pywb 2.6.8., ReplayWeb.Page and Conifer.

live web: https://dejame-c0mer.tumblr.com/ Pywb Replay (2.7.3): https://webarchives.rhizome.org/Q15390/20230111102538/https://dejame-c0mer.tumblr.com/ Conifer: https://conifer.rhizome.org/mona/dejame-c0mer/list/pages-detected/b1/20230111102655/https://dejame-c0mer.tumblr.com/

Expected behavior

As you can see in the live web or conifer replay, draggable divs appear on the web page.

What actually happened

  1. Go to https://webarchives.rhizome.org/Q15390/20230111102538/https://dejame-c0mer.tumblr.com/

Draggable divs are missing in pywb replay.

Error Messages

Error message in dev console (pywb replay): (1) Uncaught SyntaxError: expected expression, got ';’ (2) Uncaught TypeError: $(...).draggable is not a function

The first error message refers to the resource jquery-ui.js and this particular part:

if ( element ) {
    element = element.jquery || element.nodeType ?
        $( element ) :
        ;_____WB$wombat$check$this$function_____(this).document.find( element ).eq( 0 );
}

Browser

Desktop:

ato commented 3 months ago

We hit this on https://www.wilsontucker.com.au/ too.

The problem is the semicolon is being inserted by this rule in regex_rewriters.py:

# rewriting 'this.' special properties access on new line, with ; prepended
(r'\n\s*this\b(?=(?:\.(?:{0})\b))'.format(prop_str), self.replace_str(';' + this_rw), 0),

I suspect the semicolon insertion is not necessary anymore. This rewrite rule dates back to when this was rewritten to (this && this._WB_wombat_obj_proxy || this). At that time if you had some code like:

x = 2 + 3
this.location = "foo"

if it were rewritten without the added semicolon it would rewrite to:

x = 2 + 3
(this && this._WB_wombat_obj_proxy || this).location = "foo"

which the JS engine would interpret as a function call, i.e.:

x = 2 + 3(this && this._WB_wombat_obj_proxy || this).location = "foo"

and you'd get a "TypeError: 3 is not a function" exception.

However, nowadays this is rewritten to _____WB$wombat$check$this$function_____(this) and thus:

x = 2 + 3
_____WB$wombat$check$this$function_____(this).location = "foo"

which will trigger JavaScript's automatic semicolon insertion just like the original code does.