jenkins-bot has submitted this change and it was merged. (
https://gerrit.wikimedia.org/r/327233 )
Change subject: Load details divs on scroll
......................................................................
Load details divs on scroll
Speeds up the loading of details step significantly when there are many
uploads.
Bug: T153210
Change-Id: Ie178d8b7ec3c622d05b5648747d20deaf568f1e1
---
M resources/controller/uw.controller.Details.js
M resources/mw.UploadWizardDetails.js
2 files changed, 260 insertions(+), 203 deletions(-)
Approvals:
Matthias Mullie: Looks good to me, approved
jenkins-bot: Verified
diff --git a/resources/controller/uw.controller.Details.js
b/resources/controller/uw.controller.Details.js
index c64bede..9e99669 100644
--- a/resources/controller/uw.controller.Details.js
+++ b/resources/controller/uw.controller.Details.js
@@ -139,7 +139,6 @@
*/
uw.controller.Details.prototype.createDetails = function ( upload ) {
upload.details = new mw.UploadWizardDetails( upload, $(
'#mwe-upwiz-macro-files' ) );
- upload.details.populate();
upload.details.attach();
};
diff --git a/resources/mw.UploadWizardDetails.js
b/resources/mw.UploadWizardDetails.js
index 262808a..b4cc851 100644
--- a/resources/mw.UploadWizardDetails.js
+++ b/resources/mw.UploadWizardDetails.js
@@ -10,11 +10,6 @@
* @param {jQuery} containerDiv The `div` to put the interface into
*/
mw.UploadWizardDetails = function ( upload, containerDiv ) {
- var
- descriptionRequired, uri,
- $moreDetailsWrapperDiv, $moreDetailsDiv,
- details = this;
-
this.upload = upload;
this.containerDiv = containerDiv;
this.api = upload.api;
@@ -22,208 +17,226 @@
this.mainFields = [];
this.div = $( '<div class="mwe-upwiz-info-file
ui-helper-clearfix filled"></div>' );
-
- this.thumbnailDiv = $( '<div class="mwe-upwiz-thumbnail
mwe-upwiz-thumbnail-side"></div>' );
-
- this.dataDiv = $( '<div class="mwe-upwiz-data"></div>' );
-
- // descriptions
- // Description is not required if a campaign provides
alternative wikitext fields,
- // which are assumed to function like a description
- descriptionRequired = !(
- mw.UploadWizard.config.fields &&
- mw.UploadWizard.config.fields.length &&
- mw.UploadWizard.config.fields[ 0 ].wikitext
- );
- this.descriptionsDetails = new uw.DescriptionsDetailsWidget( {
- required: descriptionRequired
- } );
- this.descriptionsDetailsField = new uw.FieldLayout(
this.descriptionsDetails, {
- label: mw.message( 'mwe-upwiz-desc' ).text(),
- help: mw.message( 'mwe-upwiz-tooltip-description'
).text(),
- required: descriptionRequired
- } );
- this.mainFields.push( this.descriptionsDetailsField );
-
- this.titleDetails = new uw.TitleDetailsWidget( {
- // Normalize file extension, e.g. 'JPEG' to 'jpg'
- extension: mw.Title.normalizeExtension(
this.upload.title.getExtension() )
- } );
- this.titleDetailsField = new uw.FieldLayout( this.titleDetails,
{
- label: mw.message( 'mwe-upwiz-title' ).text(),
- help: mw.message( 'mwe-upwiz-tooltip-title' ).text(),
- required: true
- } );
- this.mainFields.push( this.titleDetailsField );
-
- this.deedChooserDetails = new uw.DeedChooserDetailsWidget();
- this.deedChooserDetailsField = new uw.FieldLayout(
this.deedChooserDetails, {
- label: mw.message( 'mwe-upwiz-copyright-info' ).text(),
- required: true
- } );
- this.deedChooserDetailsField.toggle( false ); // See
useCustomDeedChooser()
- this.mainFields.push( this.deedChooserDetailsField );
-
- this.categoriesDetails = new uw.CategoriesDetailsWidget();
- this.categoriesDetailsField = new uw.FieldLayout(
this.categoriesDetails, {
- label: mw.message( 'mwe-upwiz-categories' ).text(),
- help: new OO.ui.HtmlSnippet(
- mw.message( 'mwe-upwiz-tooltip-categories', $(
'<a>' ).attr( {
- target: '_blank',
- href:
'https://commons.wikimedia.org/wiki/Commons:Categories'
- } ) ).parse()
- )
- } );
- this.mainFields.push( this.categoriesDetailsField );
-
- this.dateDetails = new uw.DateDetailsWidget( { upload:
this.upload } );
- this.dateDetailsField = new uw.FieldLayout( this.dateDetails, {
- label: mw.message( 'mwe-upwiz-date-created' ).text(),
- help: mw.message( 'mwe-upwiz-tooltip-date' ).text(),
- required: true
- } );
- this.mainFields.push( this.dateDetailsField );
-
- this.otherDetails = new uw.OtherDetailsWidget();
- this.otherDetailsField = new uw.FieldLayout( this.otherDetails,
{
- label: mw.message( 'mwe-upwiz-other' ).text(),
- help: mw.message( 'mwe-upwiz-tooltip-other' ).text()
- } );
- this.mainFields.push( this.otherDetailsField );
-
- this.locationInput = new uw.LocationDetailsWidget( {
showHeading: true } );
- this.locationInputField = new uw.FieldLayout(
this.locationInput, {
- // No 'label', labels are included in this widget
- help: new OO.ui.HtmlSnippet(
- mw.message( 'mwe-upwiz-tooltip-location', $(
'<a>' ).attr( {
- target: '_blank',
- href:
'//commons.wikimedia.org/wiki/Commons:Geocoding'
- } ) ).parse()
- )
- } );
- this.mainFields.push( this.locationInputField );
-
- /* Build the form for the file upload */
- this.$form = $( '<form id="mwe-upwiz-detailsform' +
this.upload.index + '"></form>' ).addClass( 'detailsForm' );
- this.$form.append(
- this.titleDetailsField.$element,
- this.descriptionsDetailsField.$element,
- this.deedChooserDetailsField.$element,
- this.dateDetailsField.$element,
- this.categoriesDetailsField.$element
- );
-
- this.$form.on( 'submit', function ( e ) {
- // Prevent actual form submission
- e.preventDefault();
- } );
-
- this.campaignDetailsFields = [];
- $.each( mw.UploadWizard.config.fields, function ( i, field ) {
- var customDetails, customDetailsField;
-
- if ( field.wikitext ) {
- customDetails = new uw.CampaignDetailsWidget(
field );
- customDetailsField = new uw.FieldLayout(
customDetails, {
- label: $( $.parseHTML( field.label ) ),
- required: !!field.required
- } );
-
- if ( field.initialValue ) {
- customDetails.setSerialized( { value:
field.initialValue } );
- }
-
- details.$form.append(
customDetailsField.$element );
- details.campaignDetailsFields.push(
customDetailsField );
- }
- } );
-
- $moreDetailsWrapperDiv = $( '<div class="mwe-more-details">' );
- $moreDetailsDiv = $( '<div>' );
-
- $moreDetailsDiv.append(
- this.locationInputField.$element,
- this.otherDetailsField.$element
- );
-
- $moreDetailsWrapperDiv
- .append(
- $( '<a>' ).text( mw.msg(
'mwe-upwiz-more-options' ) )
- .addClass(
'mwe-upwiz-details-more-options mw-collapsible-toggle mw-collapsible-arrow' ),
- $moreDetailsDiv.addClass(
'mw-collapsible-content' )
- )
- .makeCollapsible( { collapsed: true } );
-
- // Expand collapsed sections if the fields within were changed
(e.g. by metadata copier)
- this.locationInput.on( 'change', function () {
- $moreDetailsWrapperDiv.data( 'mw-collapsible'
).expand();
- } );
- this.otherDetails.on( 'change', function () {
- $moreDetailsWrapperDiv.data( 'mw-collapsible'
).expand();
- } );
-
- this.$form.append(
- $moreDetailsWrapperDiv
- );
-
- // Add in remove control to form
- this.removeCtrl = new OO.ui.ButtonWidget( {
- label: mw.message( 'mwe-upwiz-remove' ).text(),
- title: mw.message( 'mwe-upwiz-remove-upload' ).text(),
- classes: [ 'mwe-upwiz-remove-upload' ],
- flags: 'destructive',
- icon: 'remove',
- framed: false
- } ).on( 'click', function () {
- OO.ui.confirm( mw.message(
'mwe-upwiz-license-confirm-remove' ).text(), {
- title: mw.message(
'mwe-upwiz-license-confirm-remove-title' ).text()
- } ).done( function ( confirmed ) {
- if ( confirmed ) {
- details.upload.emit( 'remove-upload' );
- }
- } );
- } );
-
- this.$form.append( this.removeCtrl.$element );
-
- this.submittingDiv = $( '<div>' ).addClass(
'mwe-upwiz-submitting' )
- .append(
- $( '<div>' ).addClass(
'mwe-upwiz-file-indicator' ),
- $( '<div>' ).addClass(
'mwe-upwiz-details-texts' ).append(
- $( '<div>' ).addClass(
'mwe-upwiz-visible-file-filename-text' ),
- $( '<div>' ).addClass(
'mwe-upwiz-file-status-line' )
- )
- );
-
- $( this.dataDiv ).append(
- this.$form,
- this.submittingDiv
- ).morphCrossfader();
-
- $( this.div ).append(
- this.thumbnailDiv,
- this.dataDiv
- );
-
- uri = new mw.Uri( location.href, { overrideKeys: true } );
- if ( mw.UploadWizard.config.defaults.description ||
uri.query.descriptionlang ) {
- this.descriptionsDetails.setSerialized( {
- descriptions: [
- {
- language:
uri.query.descriptionlang ?
-
uw.DescriptionDetailsWidget.static.getClosestAllowedLanguage(
uri.query.descriptionlang ) :
-
uw.DescriptionDetailsWidget.static.getDefaultLanguage(),
- description:
mw.UploadWizard.config.defaults.description || ''
- }
- ]
- } );
- }
};
mw.UploadWizardDetails.prototype = {
// Has this details object been attached to the DOM already?
isAttached: false,
+
+ /**
+ * Build the interface and attach all elements - do this on
demand.
+ */
+ buildInterface: function () {
+ var descriptionRequired, uri,
+ $moreDetailsWrapperDiv, $moreDetailsDiv,
+ details = this;
+
+ this.thumbnailDiv = $( '<div class="mwe-upwiz-thumbnail
mwe-upwiz-thumbnail-side"></div>' );
+
+ this.dataDiv = $( '<div class="mwe-upwiz-data"></div>'
);
+
+ // descriptions
+ // Description is not required if a campaign provides
alternative wikitext fields,
+ // which are assumed to function like a description
+ descriptionRequired = !(
+ mw.UploadWizard.config.fields &&
+ mw.UploadWizard.config.fields.length &&
+ mw.UploadWizard.config.fields[ 0 ].wikitext
+ );
+ this.descriptionsDetails = new
uw.DescriptionsDetailsWidget( {
+ required: descriptionRequired
+ } );
+ this.descriptionsDetailsField = new uw.FieldLayout(
this.descriptionsDetails, {
+ label: mw.message( 'mwe-upwiz-desc' ).text(),
+ help: mw.message(
'mwe-upwiz-tooltip-description' ).text(),
+ required: descriptionRequired
+ } );
+ this.mainFields.push( this.descriptionsDetailsField );
+
+ this.titleDetails = new uw.TitleDetailsWidget( {
+ // Normalize file extension, e.g. 'JPEG' to
'jpg'
+ extension: mw.Title.normalizeExtension(
this.upload.title.getExtension() )
+ } );
+ this.titleDetailsField = new uw.FieldLayout(
this.titleDetails, {
+ label: mw.message( 'mwe-upwiz-title' ).text(),
+ help: mw.message( 'mwe-upwiz-tooltip-title'
).text(),
+ required: true
+ } );
+ this.mainFields.push( this.titleDetailsField );
+
+ this.deedChooserDetails = new
uw.DeedChooserDetailsWidget();
+ this.deedChooserDetailsField = new uw.FieldLayout(
this.deedChooserDetails, {
+ label: mw.message( 'mwe-upwiz-copyright-info'
).text(),
+ required: true
+ } );
+ this.deedChooserDetailsField.toggle( false ); // See
useCustomDeedChooser()
+ this.mainFields.push( this.deedChooserDetailsField );
+
+ this.categoriesDetails = new
uw.CategoriesDetailsWidget();
+ this.categoriesDetailsField = new uw.FieldLayout(
this.categoriesDetails, {
+ label: mw.message( 'mwe-upwiz-categories'
).text(),
+ help: new OO.ui.HtmlSnippet(
+ mw.message(
'mwe-upwiz-tooltip-categories', $( '<a>' ).attr( {
+ target: '_blank',
+ href:
'https://commons.wikimedia.org/wiki/Commons:Categories'
+ } ) ).parse()
+ )
+ } );
+ this.mainFields.push( this.categoriesDetailsField );
+
+ this.dateDetails = new uw.DateDetailsWidget( { upload:
this.upload } );
+ this.dateDetailsField = new uw.FieldLayout(
this.dateDetails, {
+ label: mw.message( 'mwe-upwiz-date-created'
).text(),
+ help: mw.message( 'mwe-upwiz-tooltip-date'
).text(),
+ required: true
+ } );
+ this.mainFields.push( this.dateDetailsField );
+
+ this.otherDetails = new uw.OtherDetailsWidget();
+ this.otherDetailsField = new uw.FieldLayout(
this.otherDetails, {
+ label: mw.message( 'mwe-upwiz-other' ).text(),
+ help: mw.message( 'mwe-upwiz-tooltip-other'
).text()
+ } );
+ this.mainFields.push( this.otherDetailsField );
+
+ this.locationInput = new uw.LocationDetailsWidget( {
showHeading: true } );
+ this.locationInputField = new uw.FieldLayout(
this.locationInput, {
+ // No 'label', labels are included in this
widget
+ help: new OO.ui.HtmlSnippet(
+ mw.message(
'mwe-upwiz-tooltip-location', $( '<a>' ).attr( {
+ target: '_blank',
+ href:
'//commons.wikimedia.org/wiki/Commons:Geocoding'
+ } ) ).parse()
+ )
+ } );
+ this.mainFields.push( this.locationInputField );
+
+ /* Build the form for the file upload */
+ this.$form = $( '<form id="mwe-upwiz-detailsform' +
this.upload.index + '"></form>' ).addClass( 'detailsForm' );
+ this.$form.append(
+ this.titleDetailsField.$element,
+ this.descriptionsDetailsField.$element,
+ this.deedChooserDetailsField.$element,
+ this.dateDetailsField.$element,
+ this.categoriesDetailsField.$element
+ );
+
+ this.$form.on( 'submit', function ( e ) {
+ // Prevent actual form submission
+ e.preventDefault();
+ } );
+
+ this.campaignDetailsFields = [];
+ $.each( mw.UploadWizard.config.fields, function ( i,
field ) {
+ var customDetails, customDetailsField;
+
+ if ( field.wikitext ) {
+ customDetails = new
uw.CampaignDetailsWidget( field );
+ customDetailsField = new
uw.FieldLayout( customDetails, {
+ label: $( $.parseHTML(
field.label ) ),
+ required: !!field.required
+ } );
+
+ if ( field.initialValue ) {
+ customDetails.setSerialized( {
value: field.initialValue } );
+ }
+
+ details.$form.append(
customDetailsField.$element );
+ details.campaignDetailsFields.push(
customDetailsField );
+ }
+ } );
+
+ $moreDetailsWrapperDiv = $( '<div
class="mwe-more-details">' );
+ $moreDetailsDiv = $( '<div>' );
+
+ $moreDetailsDiv.append(
+ this.locationInputField.$element,
+ this.otherDetailsField.$element
+ );
+
+ $moreDetailsWrapperDiv
+ .append(
+ $( '<a>' ).text( mw.msg(
'mwe-upwiz-more-options' ) )
+ .addClass(
'mwe-upwiz-details-more-options mw-collapsible-toggle mw-collapsible-arrow' ),
+ $moreDetailsDiv.addClass(
'mw-collapsible-content' )
+ )
+ .makeCollapsible( { collapsed: true } );
+
+ // Expand collapsed sections if the fields within were
changed (e.g. by metadata copier)
+ this.locationInput.on( 'change', function () {
+ $moreDetailsWrapperDiv.data( 'mw-collapsible'
).expand();
+ } );
+ this.otherDetails.on( 'change', function () {
+ $moreDetailsWrapperDiv.data( 'mw-collapsible'
).expand();
+ } );
+
+ this.$form.append(
+ $moreDetailsWrapperDiv
+ );
+
+ // Add in remove control to form
+ this.removeCtrl = new OO.ui.ButtonWidget( {
+ label: mw.message( 'mwe-upwiz-remove' ).text(),
+ title: mw.message( 'mwe-upwiz-remove-upload'
).text(),
+ classes: [ 'mwe-upwiz-remove-upload' ],
+ flags: 'destructive',
+ icon: 'remove',
+ framed: false
+ } ).on( 'click', function () {
+ OO.ui.confirm( mw.message(
'mwe-upwiz-license-confirm-remove' ).text(), {
+ title: mw.message(
'mwe-upwiz-license-confirm-remove-title' ).text()
+ } ).done( function ( confirmed ) {
+ if ( confirmed ) {
+ details.upload.emit(
'remove-upload' );
+ }
+ } );
+ } );
+
+ this.$form.append( this.removeCtrl.$element );
+
+ this.submittingDiv = $( '<div>' ).addClass(
'mwe-upwiz-submitting' )
+ .append(
+ $( '<div>' ).addClass(
'mwe-upwiz-file-indicator' ),
+ $( '<div>' ).addClass(
'mwe-upwiz-details-texts' ).append(
+ $( '<div>' ).addClass(
'mwe-upwiz-visible-file-filename-text' ),
+ $( '<div>' ).addClass(
'mwe-upwiz-file-status-line' )
+ )
+ );
+
+ $( this.dataDiv ).append(
+ this.$form,
+ this.submittingDiv
+ ).morphCrossfader();
+
+ $( this.div ).append(
+ this.thumbnailDiv,
+ this.dataDiv
+ );
+
+ uri = new mw.Uri( location.href, { overrideKeys: true }
);
+ if ( mw.UploadWizard.config.defaults.description ||
uri.query.descriptionlang ) {
+ this.descriptionsDetails.setSerialized( {
+ descriptions: [
+ {
+ language:
uri.query.descriptionlang ?
+
uw.DescriptionDetailsWidget.static.getClosestAllowedLanguage(
uri.query.descriptionlang ) :
+
uw.DescriptionDetailsWidget.static.getDefaultLanguage(),
+ description:
mw.UploadWizard.config.defaults.description || ''
+ }
+ ]
+ } );
+ }
+
+ this.populate();
+
+ this.interfaceBuilt = true;
+
+ if ( this.savedSerialData ) {
+ this.setSerialized( this.savedSerialData );
+ this.savedSerialData = undefined;
+ }
+ },
/*
* Append the div for this details object to the DOM.
@@ -233,8 +246,25 @@
* Will only append once.
*/
attach: function () {
+ var $window = $( window ),
+ details = this;
+
+ function maybeBuild() {
+ if ( !this.interfaceBuilt &&
$window.scrollTop() + $window.height() + 1000 >= details.div.offset().top ) {
+ details.buildInterface();
+ $window.off( 'scroll', maybeBuild );
+ }
+ }
+
if ( !this.isAttached ) {
$( this.containerDiv ).append( this.div );
+
+ if ( $window.scrollTop() + $window.height() +
1000 >= this.div.offset().top ) {
+ this.buildInterface();
+ } else {
+ $window.on( 'scroll', maybeBuild );
+ }
+
this.isAttached = true;
}
},
@@ -573,6 +603,12 @@
* @return {Object.<string,Object>}
*/
getSerialized: function () {
+ if ( !this.interfaceBuilt ) {
+ // We don't have the interface yet, but it'll
get filled out as
+ // needed.
+ return;
+ }
+
return {
title: this.titleDetails.getSerialized(),
description:
this.descriptionsDetails.getSerialized(),
@@ -593,10 +629,32 @@
*
* Fields from the representation can be omitted to keep the
current value.
*
- * @param {Object.<string,Object>} serialized
+ * @param {Object.<string,Object>} [serialized]
*/
setSerialized: function ( serialized ) {
var i;
+
+ if ( !this.interfaceBuilt ) {
+ // There's no interface yet! Don't load the
data, just keep it
+ // around.
+ if ( serialized === undefined ) {
+ // Note: This will happen if we "undo"
a copy operation while
+ // some of the details interfaces
aren't loaded.
+ this.savedSerialData = undefined;
+ } else {
+ this.savedSerialData = $.extend( true,
+ this.savedSerialData || {},
+ serialized
+ );
+ }
+ return;
+ }
+
+ if ( serialized === undefined ) {
+ // This is meaningless if the interface is
already built.
+ return;
+ }
+
if ( serialized.title ) {
this.titleDetails.setSerialized(
serialized.title );
}
--
To view, visit https://gerrit.wikimedia.org/r/327233
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ie178d8b7ec3c622d05b5648747d20deaf568f1e1
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/extensions/UploadWizard
Gerrit-Branch: master
Gerrit-Owner: MarkTraceur <[email protected]>
Gerrit-Reviewer: Matthias Mullie <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits