From c677f6646f6dd914657b76fa30cd34099ffa46be Mon Sep 17 00:00:00 2001 From: Sam Wilson Date: Mon, 11 Feb 2019 09:15:46 +0800 Subject: [PATCH] Disable upload button after clicking This disables and changes the label of the upload button after it's been clicked, to inform the user of progress and to prevent double submissions. Bug: T210564 --- assets/translate.js | 24 +++++++++++++++++++ i18n/en.json | 1 + i18n/qqq.json | 1 + .../{app.ae00a295.js => app.af6924dc.js} | 2 +- public/assets/entrypoints.json | 2 +- public/assets/i18n/app/en.json | 1 + public/assets/i18n/app/qqq.json | 1 + public/assets/manifest.json | 2 +- src/Controller/TranslateController.php | 2 ++ 9 files changed, 33 insertions(+), 3 deletions(-) rename public/assets/{app.ae00a295.js => app.af6924dc.js} (99%) diff --git a/assets/translate.js b/assets/translate.js index 4e93d849..da2285a9 100644 --- a/assets/translate.js +++ b/assets/translate.js @@ -160,3 +160,27 @@ $( window ).on( 'load', function () { appConfig.imageMapLayer = L.imageOverlay( $imageElement.attr( 'src' ), [ [ 0, 0 ], [ $imageElement.height(), $imageElement.width() ] ] ); appConfig.imageMapLayer.addTo( imagemap ); } ); + +/** + * Disable the upload button once it's been clicked. + */ +$( function () { + var uploadButtonWidget, + $uploadButtonElement = $( '#upload-button-widget' ); + if ( $uploadButtonElement.length === 1 ) { + // If there is an upload button, infuse it and modify its submission behaviour. + uploadButtonWidget = OO.ui.infuse( $uploadButtonElement ); + uploadButtonWidget.on( 'click', function () { + // Because we want to disable the upload button after its been clicked but before the + // form has been submitted, we need to make sure the 'upload' parameter is still sent + // (because that's how we distinguish between upload and download; they're both form + // submission buttons on the same form). We do this by creating a new hidden element. + var $form = uploadButtonWidget.$element.parents( 'form' ), + $hiddenUpload = $( '' ).attr( 'type', 'hidden' ).attr( 'name', 'upload' ); + $form.prepend( $hiddenUpload ); + uploadButtonWidget.setLabel( $.i18n( 'upload-button-in-progress' ) ); + uploadButtonWidget.setDisabled( true ); + $form.submit(); + } ); + } +} ); diff --git a/i18n/en.json b/i18n/en.json index 40530600..4454f3fb 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -32,6 +32,7 @@ "confirmation-to-switch-target-lang": "You are trying to change the translation language but you have unsaved translations. Changing the language will result in loss of any added translations. Please upload the translations to Commons or download the translated file before proceeding. Do you wish to continue?", "confirm-change-target-lang": "Change language", "upload-button-label": "Upload to Commons", + "upload-button-in-progress": "Uploading to Commons…", "download-button-label": "Download", "download-or-upload": "or", "translation-image-alt": "The image that's currently being translated. No description available.", diff --git a/i18n/qqq.json b/i18n/qqq.json index b6e35b2a..3cec28b2 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -32,6 +32,7 @@ "confirmation-to-switch-target-lang": "Confirmation message shown when a user tries to switch the target language but has unsaved changes in the form.", "confirm-change-target-lang": "Label for the confirm button for {{msg-wm|confirmation-to-switch-target-lang}}, to appear next to 'Cancel' (i.e. {{wm-msg|ooui-dialog-message-reject}}).", "upload-button-label": "Label for the button that uploads the translated SVG to Wikimedia Commons.", + "upload-button-in-progress": "Label that the upload button swiches to after it's been clicked, while the file is uploading. The button is also disabled at this point.", "download-button-label": "Label for the button that downloads the translated SVG to the user's local computer.", "download-or-upload": "Label positioned between the download and the upload buttons.", "translation-image-alt": "Alt text for the image that's currently being translated. Doesn't explain the image, just explains that we don't explain it.", diff --git a/public/assets/app.ae00a295.js b/public/assets/app.af6924dc.js similarity index 99% rename from public/assets/app.ae00a295.js rename to public/assets/app.af6924dc.js index 78df31cf..a0455fe4 100644 --- a/public/assets/app.ae00a295.js +++ b/public/assets/app.af6924dc.js @@ -62,7 +62,7 @@ function(t){var e,i,n,o,s,a,r,l,u,h,c,d,p,g,m,f,y,v,b,_="sizzle"+1*new Date,w=t. * @licence GNU General Public Licence 2.0 or later * @licence MIT License */ -!function(t){"use strict";var e,i,n,o=Array.prototype.slice;(e=function(i){this.options=t.extend({},e.defaults,i),this.parser=this.options.parser,this.locale=this.options.locale,this.messageStore=this.options.messageStore,this.languages={}}).prototype={localize:function(e){var i,n,o,s,a,r;for(o=this.locale,s=0;o;){n=(i=o.split("-")).length;do{if(a=i.slice(0,n).join("-"),r=this.messageStore.get(a,e))return r;n--}while(n);if("en"===o)break;o=t.i18n.fallbacks[this.locale]&&t.i18n.fallbacks[this.locale][s]||this.options.fallbackLocale,t.i18n.log("Trying fallback locale for "+this.locale+": "+o+" ("+e+")"),s++}return""},destroy:function(){t.removeData(document,"i18n")},load:function(e,i){var n,o,s,a={};if(e||i||(e="i18n/"+t.i18n().locale+".json",i=t.i18n().locale),"string"==typeof e&&"json"!==e.split("?")[0].split(".").pop()){for(a[i]=e+"/"+i+".json",n=(t.i18n.fallbacks[i]||[]).concat(this.options.fallbackLocale),o=0;o-1)return!0;for(n=0;n1},setGroupByRegionOverride:function(t){this.groupByRegionOverride=t},render:function(){var t,i=this.buildQuicklist(),n=[],o={all:"All languages",WW:"Worldwide",SP:"Special",AM:"America",EU:"Europe",ME:"Middle East",AS:"Asia",AF:"Africa",PA:"Pacific"};i.length?n.push(i):this.$element.addClass("uls-lcd--no-quicklist"),this.options.showRegions.forEach(function(i){this.regionLanguages[i]=[],t=e("
").addClass("uls-lcd-region-section hide").attr("data-region",i),e("

").attr("data-i18n","uls-region-"+i).addClass("uls-lcd-region-title").text(o[i]).appendTo(t),n.push(t)}.bind(this)),this.$element.append(n),this.i18n()},renderRegions:function(){var t,i=this;this.$element.removeClass("uls-no-results"),this.$element.children(".uls-lcd-region-section").each(function(){var n=e(this),o=n.data("region");n.is(".uls-lcd-quicklist")||(n.children(".uls-language-block").remove(),(t=i.regionLanguages[o])&&0!==t.length?(i.renderRegion(n,t,i.options.itemsPerColumn,i.options.columns),n.removeClass("hide"),i.regionLanguages[o]=[]):n.addClass("hide"))})},renderRegion:function(t,i,n,o){var s,a,r,l,u,h,c=i.length,d=[],p=[],g=[];if(i=e.uls.data.sortByScriptGroup(i.sort(e.uls.data.sortByAutonym)),s=1===o?"twelve columns":2===o?"six columns":"three columns",1===this.options.columns){for(a=0;a").addClass(s).append(d)),g.push(e("
").addClass("row uls-language-block").append(p))}else for(a=0;a1&&(h=!0):l=e.uls.data.getScriptGroupOfLanguage(i[a]),l=u,d.push(this.renderItem(i[a])),(d.length>=n||r||h)&&(p.push(e("
    ").addClass(s).append(d)),d=[],(p.length>=o||r)&&(g.push(e("
    ").addClass("row uls-language-block").append(p)),p=[]));t.append(g)},renderItem:function(t){var i,n,o,s;return n=this.options.languages[t],o=e.uls.data.getAutonym(t)||n||t,(s=document.createElement("li")).title=n,s.setAttribute("data-code",t),(i=document.createElement("a")).appendChild(document.createTextNode(o)),i.className="autonym",i.lang=t,i.dir=e.uls.data.getDir(t),s.appendChild(i),this.options.languageDecorator&&this.options.languageDecorator(e(i),t),s},i18n:function(){this.$element.find("[data-i18n]").i18n()},quicklist:function(){this.$element.find(".uls-lcd-quicklist").removeClass("hide")},buildQuicklist:function(){var t,i,n;return null!==this.cachedQuicklist?this.cachedQuicklist:(e.isFunction(this.options.quickList)&&(this.options.quickList=this.options.quickList()),this.options.quickList.length?((t=(t=this.options.quickList).slice(0,16)).sort(e.uls.data.sortByAutonym),i=e("
    ").addClass("uls-lcd-region-section uls-lcd-quicklist"),n=e("

    ").attr("data-i18n","uls-common-languages").addClass("uls-lcd-region-title").text("Suggested languages"),i.append(n),this.renderRegion(i,t,this.options.itemsPerColumn,this.options.columns),n.i18n(),this.cachedQuicklist=i,this.cachedQuicklist):(this.cachedQuicklist=e([]),this.cachedQuicklist))},show:function(){this.regionDivs||this.render()},empty:function(){this.$element.addClass("uls-lcd--no-quicklist"),this.$element.find(".uls-lcd-quicklist").addClass("hide")},focus:function(){this.$element.focus()},noResults:function(e,i){var n;if(this.$element.addClass("uls-no-results"),this.$element.find(".uls-no-results-view").remove(),"function"==typeof this.options.noResultsTemplate)n=this.options.noResultsTemplate.call(this,i.query);else{if(!(this.options.noResultsTemplate instanceof t))throw new Error("noResultsTemplate option must be either jQuery or function returning jQuery");n=this.options.noResultsTemplate}this.$element.append(n.addClass("uls-no-results-view").i18n())},listen:function(){var t=this;this.options.clickhandler&&this.$element.on("click",".row li",function(i){t.options.clickhandler.call(this,e(this).data("code"),i)})}},e.fn.lcd=function(t){return this.each(function(){var n=e(this),o=n.data("lcd"),s="object"==typeof t&&t;o||n.data("lcd",o=new i(this,s)),"string"==typeof t&&o[t]()})},e.fn.lcd.defaults={languages:[],showRegions:["WW","AM","EU","ME","AF","AS","PA"],groupByRegion:"auto",itemsPerColumn:8,columns:4,languageDecorator:void 0,quickList:[],clickhandler:void 0,noResultsTemplate:function(){var t,i=e('
    \t\t

    No results found

    \t\t
    \t\t
    \t\t
    You can search by language name, script name, ISO code of language or you can browse by region.
    \t\t
    ');return(t=this.buildQuicklist().clone()).removeClass("hide").find("h3").data("i18n","uls-no-results-suggestion-title").text("You may be interested in:").i18n(),i.find(".uls-no-results-suggestions").append(t),i}}}(t)}).call(this,i("EVdn"))},ML86:function(t,e,i){},Mh5E:function(t,e,i){(function(t){var e;!function(){return function t(i,n,o){function s(r,l){if(!n[r]){if(!i[r]){if(!l&&"function"==typeof e&&e)return e(r,!0);if(a)return a(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var h=n[r]={exports:{}};i[r][0].call(h.exports,function(t){return s(i[r][1][t]||t)},h,h.exports,t,i,n,o)}return n[r].exports}for(var a="function"==typeof e&&e,r=0;r-1)return!0;for(n=0;n1},setGroupByRegionOverride:function(t){this.groupByRegionOverride=t},render:function(){var t,i=this.buildQuicklist(),n=[],o={all:"All languages",WW:"Worldwide",SP:"Special",AM:"America",EU:"Europe",ME:"Middle East",AS:"Asia",AF:"Africa",PA:"Pacific"};i.length?n.push(i):this.$element.addClass("uls-lcd--no-quicklist"),this.options.showRegions.forEach(function(i){this.regionLanguages[i]=[],t=e("
    ").addClass("uls-lcd-region-section hide").attr("data-region",i),e("

    ").attr("data-i18n","uls-region-"+i).addClass("uls-lcd-region-title").text(o[i]).appendTo(t),n.push(t)}.bind(this)),this.$element.append(n),this.i18n()},renderRegions:function(){var t,i=this;this.$element.removeClass("uls-no-results"),this.$element.children(".uls-lcd-region-section").each(function(){var n=e(this),o=n.data("region");n.is(".uls-lcd-quicklist")||(n.children(".uls-language-block").remove(),(t=i.regionLanguages[o])&&0!==t.length?(i.renderRegion(n,t,i.options.itemsPerColumn,i.options.columns),n.removeClass("hide"),i.regionLanguages[o]=[]):n.addClass("hide"))})},renderRegion:function(t,i,n,o){var s,a,r,l,u,h,c=i.length,d=[],p=[],g=[];if(i=e.uls.data.sortByScriptGroup(i.sort(e.uls.data.sortByAutonym)),s=1===o?"twelve columns":2===o?"six columns":"three columns",1===this.options.columns){for(a=0;a").addClass(s).append(d)),g.push(e("
    ").addClass("row uls-language-block").append(p))}else for(a=0;a1&&(h=!0):l=e.uls.data.getScriptGroupOfLanguage(i[a]),l=u,d.push(this.renderItem(i[a])),(d.length>=n||r||h)&&(p.push(e("
      ").addClass(s).append(d)),d=[],(p.length>=o||r)&&(g.push(e("
      ").addClass("row uls-language-block").append(p)),p=[]));t.append(g)},renderItem:function(t){var i,n,o,s;return n=this.options.languages[t],o=e.uls.data.getAutonym(t)||n||t,(s=document.createElement("li")).title=n,s.setAttribute("data-code",t),(i=document.createElement("a")).appendChild(document.createTextNode(o)),i.className="autonym",i.lang=t,i.dir=e.uls.data.getDir(t),s.appendChild(i),this.options.languageDecorator&&this.options.languageDecorator(e(i),t),s},i18n:function(){this.$element.find("[data-i18n]").i18n()},quicklist:function(){this.$element.find(".uls-lcd-quicklist").removeClass("hide")},buildQuicklist:function(){var t,i,n;return null!==this.cachedQuicklist?this.cachedQuicklist:(e.isFunction(this.options.quickList)&&(this.options.quickList=this.options.quickList()),this.options.quickList.length?((t=(t=this.options.quickList).slice(0,16)).sort(e.uls.data.sortByAutonym),i=e("
      ").addClass("uls-lcd-region-section uls-lcd-quicklist"),n=e("

      ").attr("data-i18n","uls-common-languages").addClass("uls-lcd-region-title").text("Suggested languages"),i.append(n),this.renderRegion(i,t,this.options.itemsPerColumn,this.options.columns),n.i18n(),this.cachedQuicklist=i,this.cachedQuicklist):(this.cachedQuicklist=e([]),this.cachedQuicklist))},show:function(){this.regionDivs||this.render()},empty:function(){this.$element.addClass("uls-lcd--no-quicklist"),this.$element.find(".uls-lcd-quicklist").addClass("hide")},focus:function(){this.$element.focus()},noResults:function(e,i){var n;if(this.$element.addClass("uls-no-results"),this.$element.find(".uls-no-results-view").remove(),"function"==typeof this.options.noResultsTemplate)n=this.options.noResultsTemplate.call(this,i.query);else{if(!(this.options.noResultsTemplate instanceof t))throw new Error("noResultsTemplate option must be either jQuery or function returning jQuery");n=this.options.noResultsTemplate}this.$element.append(n.addClass("uls-no-results-view").i18n())},listen:function(){var t=this;this.options.clickhandler&&this.$element.on("click",".row li",function(i){t.options.clickhandler.call(this,e(this).data("code"),i)})}},e.fn.lcd=function(t){return this.each(function(){var n=e(this),o=n.data("lcd"),s="object"==typeof t&&t;o||n.data("lcd",o=new i(this,s)),"string"==typeof t&&o[t]()})},e.fn.lcd.defaults={languages:[],showRegions:["WW","AM","EU","ME","AF","AS","PA"],groupByRegion:"auto",itemsPerColumn:8,columns:4,languageDecorator:void 0,quickList:[],clickhandler:void 0,noResultsTemplate:function(){var t,i=e('
      \t\t

      No results found

      \t\t
      \t\t
      \t\t
      You can search by language name, script name, ISO code of language or you can browse by region.
      \t\t
      ');return(t=this.buildQuicklist().clone()).removeClass("hide").find("h3").data("i18n","uls-no-results-suggestion-title").text("You may be interested in:").i18n(),i.find(".uls-no-results-suggestions").append(t),i}}}(t)}).call(this,i("EVdn"))},ML86:function(t,e,i){},Mh5E:function(t,e,i){(function(t){var e;!function(){return function t(i,n,o){function s(r,l){if(!n[r]){if(!i[r]){if(!l&&"function"==typeof e&&e)return e(r,!0);if(a)return a(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var h=n[r]={exports:{}};i[r][0].call(h.exports,function(t){return s(i[r][1][t]||t)},h,h.exports,t,i,n,o)}return n[r].exports}for(var a="function"==typeof e&&e,r=0;r").attr("type","hidden").attr("name","upload");e.prepend(n),i.setLabel(t.i18n("upload-button-in-progress")),i.setDisabled(!0),e.submit()})})}).call(this,i("EVdn"),i("ovuR"))},anCX:function(t,e,i){(function(t){!function(t){"use strict";t.i18n.languages.fi=t.extend({},t.i18n.languages.default,{convertGrammar:function(t,e){var i=t.match(/[aou][^äöy]*$/i),n=t;switch(t.match(/wiki$/i)&&(i=!1),t.match(/[bcdfghjklmnpqrstvwxz]$/i)&&(t+="i"),e){case"genitive":t+="n";break;case"elative":t+=i?"sta":"stä";break;case"partitive":t+=i?"a":"ä";break;case"illative":t+=t.slice(-1)+"n";break;case"inessive":t+=i?"ssa":"ssä";break;default:t=n}return t}})}(t)}).call(this,i("EVdn"))},bMVF:function(t,e,i){},iGkt:function(t,e,i){(function(t,e){App.InterfaceLangButton=function(e){this.interfaceLang=e.interfaceLang,this.currentLang=this.interfaceLang,e=t.extend({indicator:"down",label:appConfig.languages[this.interfaceLang]},e),App.InterfaceLangButton.super.call(this,e)},e.inheritClass(App.InterfaceLangButton,e.ui.ButtonWidget),App.InterfaceLangButton.prototype.onClick=function(t){this.$element.uls({ulsPurpose:"interfaceLang",languages:appConfig.languages,onSelect:this.onUlsSelect.bind(this),top:App.LanguageDialog.prototype.calculateUlsTop.bind(this.$element)})},App.InterfaceLangButton.prototype.onUlsSelect=function(t){this.setLabel(appConfig.languages[t]),this.currentLang=t}}).call(this,i("EVdn"),i("ovuR"))},lK6O:function(t,e,i){ /* @preserve * Leaflet 1.4.0, a JS library for interactive maps. http://leafletjs.com * (c) 2010-2018 Vladimir Agafonkin, (c) 2010-2011 CloudMade diff --git a/public/assets/entrypoints.json b/public/assets/entrypoints.json index 25733b4e..8f9adc2a 100644 --- a/public/assets/entrypoints.json +++ b/public/assets/entrypoints.json @@ -5,7 +5,7 @@ "assets/app.1709d2c7.css" ], "js": [ - "assets/app.ae00a295.js" + "assets/app.af6924dc.js" ] } } diff --git a/public/assets/i18n/app/en.json b/public/assets/i18n/app/en.json index 40530600..4454f3fb 100644 --- a/public/assets/i18n/app/en.json +++ b/public/assets/i18n/app/en.json @@ -32,6 +32,7 @@ "confirmation-to-switch-target-lang": "You are trying to change the translation language but you have unsaved translations. Changing the language will result in loss of any added translations. Please upload the translations to Commons or download the translated file before proceeding. Do you wish to continue?", "confirm-change-target-lang": "Change language", "upload-button-label": "Upload to Commons", + "upload-button-in-progress": "Uploading to Commons…", "download-button-label": "Download", "download-or-upload": "or", "translation-image-alt": "The image that's currently being translated. No description available.", diff --git a/public/assets/i18n/app/qqq.json b/public/assets/i18n/app/qqq.json index b6e35b2a..3cec28b2 100644 --- a/public/assets/i18n/app/qqq.json +++ b/public/assets/i18n/app/qqq.json @@ -32,6 +32,7 @@ "confirmation-to-switch-target-lang": "Confirmation message shown when a user tries to switch the target language but has unsaved changes in the form.", "confirm-change-target-lang": "Label for the confirm button for {{msg-wm|confirmation-to-switch-target-lang}}, to appear next to 'Cancel' (i.e. {{wm-msg|ooui-dialog-message-reject}}).", "upload-button-label": "Label for the button that uploads the translated SVG to Wikimedia Commons.", + "upload-button-in-progress": "Label that the upload button swiches to after it's been clicked, while the file is uploading. The button is also disabled at this point.", "download-button-label": "Label for the button that downloads the translated SVG to the user's local computer.", "download-or-upload": "Label positioned between the download and the upload buttons.", "translation-image-alt": "Alt text for the image that's currently being translated. Doesn't explain the image, just explains that we don't explain it.", diff --git a/public/assets/manifest.json b/public/assets/manifest.json index d097b49e..178c34b2 100644 --- a/public/assets/manifest.json +++ b/public/assets/manifest.json @@ -1,6 +1,6 @@ { "assets/app.css": "assets/app.1709d2c7.css", - "assets/app.js": "assets/app.ae00a295.js", + "assets/app.js": "assets/app.af6924dc.js", "assets/grabbing.cur": "assets/a8c874b93b3d848f39a71260c57e3863.cur", "assets/grab.cur": "assets/b06c243f534d9c5461d16528156cd5a8.cur", "assets/i18n/app/af.json": "assets/i18n/app/af.json", diff --git a/src/Controller/TranslateController.php b/src/Controller/TranslateController.php index 2236b0c9..1bbcf70e 100644 --- a/src/Controller/TranslateController.php +++ b/src/Controller/TranslateController.php @@ -68,6 +68,8 @@ public function translate( 'type' => 'submit', 'icon' => 'logoWikimediaCommons', 'name' => 'upload', + 'id' => 'upload-button-widget', + 'infusable' => true, ]); if (!$session->get('logged_in_user')) { // Only logged in users can upload.