[wp-trac] [WordPress Trac] #42794: Can't upload new media files when multiple media dialogues are present on a single page

WordPress Trac noreply at wordpress.org
Mon Dec 4 16:01:07 UTC 2017


#42794: Can't upload new media files when multiple media dialogues are present on a
single page
---------------------------+-----------------------------
 Reporter:  carlobeltrame  |      Owner:
     Type:  defect (bug)   |     Status:  new
 Priority:  normal         |  Milestone:  Awaiting Review
Component:  Media          |    Version:  4.8.2
 Severity:  normal         |   Keywords:
  Focuses:  javascript     |
---------------------------+-----------------------------
 '''Layman error description''': When there are more than one Inline Media
 Uploader on a page in the Admin, and one tries to upload a new image or
 file to the Media Library, the upload gets stuck and the image is never
 inserted into the media library (see attached screenshot). This happens to
 me when using the post-types-definitely plugin to create multiple media
 fields in a CPT. The exact same error (including error messages) has been
 described before ([https://wordpress.org/support/topic/js-bug-prevents-
 uploading-media-in-pagepost-editor/?replies=11#post-6860868] and
 https://wordpress.org/support/topic/error-uploading-media-in-post-if-
 yoast-is-active/#post-6922117), and even though there it was related to a
 plugin combination, it is not in my case. The workaround proposed there is
 not applicable to my case and the error source I found has nothing to do
 with plugins.[[BR]][[BR]]

 '''Technical error description''': When examined in the Firefox Developer
 Tools, the console shows the error `TypeError: this.$index is undefined`.
 In Chrome, the error is `Cannot read property 'text' of undefined`. Both
 of them point to `wp-includes/js/media-views.js:UploaderStatus.info()`
 [https://core.trac.wordpress.org/browser/trunk/src/wp-includes/js/media-
 views.js?rev=40359#L8361][[BR]][[BR]]

 '''Technical analysis''': Upon closer inspection of the code, the problem
 seems to be as follows: When we upload a file (by clicking Ok on the OS
 file dialogue), a callback handler calls info() on each UploadStatus
 object belonging to a loaded media dialogue. The method info() relies on
 the fact that normally, the method ready() on the same UploadStatus object
 is called before the call to info(). ready() uses JQuery to set (amongst
 others) the member variable $index inside the UploadStatus object. info()
 then tries to access this.$index on all UploadStatus objects and set their
 contents using the JQuery text() function. However, since ready() is not
 called before a media dialogue is opened for the first time, and our
 opened dialogue calls info() on all media dialogues, the access to
 this.$index fails in the unopened UploadStatus objects, throwing the above
 Javascript Error and making the script abort, therefore freezing the
 upload progress bar.[[BR]][[BR]]

 '''Workarounds''': This analysis is confirmed by the fact that when I open
 all media dialogues on the page at least once before uploading an image in
 any of them, uploading works as expected (because all of the
 UploadStatuses are ready() and have their $index member variable defined).
 A workaround for the problem is to just use the inline media dialogues for
 selecting existing media from the media library, and using the Media->New
 menu to actually upload any files. The error happened in all Wordpress
 versions I tested (since 4.8.3).[[BR]][[BR]]

 '''Proposed solution''': I can see a number of different solutions for
 this problem. The best one would be to only call info() on the
 UploadStatus belonging to the opened media dialogue. However, the info()
 calls are performed via a single event trigger
 ([https://core.trac.wordpress.org/browser/trunk/src/wp-includes/js/media-
 views.js?rev=40359#L8289]) that all info() methods subscribe to in the
 UploadStatus.initialize() function (relevant for this bug is the `"add"`
 trigger), and this trigger cannot distinguish its subscribers. Therefore I
 propose to instead call ready() at the end of the initialize() function.
 This way, ready() is only called once more than before per media dialogue
 and page load, and we can be certain that info() is only called on
 UploadStatuses that are ready().

--
Ticket URL: <https://core.trac.wordpress.org/ticket/42794>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list