Make WordPress Core

Opened 8 years ago

Closed 8 years ago

#40658 closed defect (bug) (fixed)

Customize: Do fallback full page refresh when selective refresh partial content contains script

Reported by: westonruter's profile westonruter Owned by: westonruter's profile westonruter
Milestone: 4.8 Priority: normal
Severity: normal Version: 4.5
Component: Customize Keywords: has-patch commit
Focuses: Cc:

Description

A common use case for the Text widget is to paste in some JavaScript code to display some 3rd party widget on a site. Such JavaScript usually to be executed while the page is loading (especially when document.write() is used) and as such previewing the addition of a script tag in a Text widget cannot be previewed with selective refresh.

Attachments (3)

40658.0.diff (1.2 KB) - added by westonruter 8 years ago.
40658.1.diff (615 bytes) - added by westonruter 8 years ago.
40658.2.diff (572 bytes) - added by westonruter 8 years ago.

Download all attachments as: .zip

Change History (12)

@westonruter
8 years ago

#1 @westonruter
8 years ago

  • Keywords has-patch needs-testing added

#2 @westonruter
8 years ago

  • Owner set to westonruter
  • Status changed from new to accepted

#3 @Kopepasah
8 years ago

Tested adding various inline scripts inside the Text Widget and I can confirm that this patch fixes this issue.

#4 @westonruter
8 years ago

  • Keywords commit added; needs-testing removed

#5 @westonruter
8 years ago

  • Keywords commit removed

Humm. Should we specifically only do a fallback refresh if the script[type] is absent or it is anything other than something which would get executed as JavaScript? I'm thinking here of script[type="text/template"] and the like which would not be relevant to do full-refreshes.

@westonruter
8 years ago

#6 @westonruter
8 years ago

Actually, jQuery does evaluate inline script tags that get inserted into the DOM. For example, pasting the following into the HTML for a Text widget:

<iframe width='560' height='314' src='https://videopress.com/embed/OAVHZIvv?hd=0' frameborder='0' allowfullscreen></iframe><script src='https://v0.wordpress.com/js/next/videopress-iframe.js?m=1435166243'></script>
<div id="currentTime">Loading...</div>
<script>document.getElementById('currentTime').innerHTML='Current Time: ' + String( new Date() );</script>

So really the main problem is document.write(). Currently an attempted document.write() is throwing an error. But this was the wrong move. What we should instead be doing is issuing a fallback refresh (of course): 40658.1.diff

@westonruter
8 years ago

#7 @westonruter
8 years ago

And instead of just doing fallback-refresh if document.write() was called, we should be doing it whenever there is a script error. See 40658.2.diff.

Last edited 8 years ago by westonruter (previous) (diff)

#8 @westonruter
8 years ago

  • Keywords commit added

The above also accounts for the situation when you have an external script tag followed by an inline script that attempts to reference a variable in the external script. Since external scripts are loaded asynchronously when dynamically added to the DOM, the second inline script tag gets evaluated before the external script can load, resulting in a JS error. With 40658.2.diff this is also accounted for because when there is such an error thrown during selective refresh, it will do a fallback full refresh.

#9 @westonruter
8 years ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 40771:

Customize: Run a partial's fallback behavior (full refresh) when selective refresh fails due to a script error.

This ensures that 3rd-party scripts that users paste into Text widgets will gracefully recover and result in the expected preview.

See #27355.
Fixes #40658.

Note: See TracTickets for help on using tickets.