r59278 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r59277‎ | r59278 | r59279 >
Date:07:23, 20 November 2009
Author:tstarling
Status:deferred (Comments)
Tags:
Comment:
Rework of libAddMedia. The changes are entirely untested and there may be bugs, but at least the code is nicer to look at now. This commit message is probably incomplete.

In libAddMedia:
* Made many style changes, renamed many variables.
* Wrote a doc comment for most functions
* Renamed messages:
* fogg-check_for_fogg -> fogg-check_for_firefogg
* fogg-for_improved_uplods -> fogg-for_improved_uploads
* fogg-use_latest_fox -> fogg-use_latest_firefox
* mwe-upload-stats-fileprogres -> mwe-upload-stats-fileprogress

* Renamed functions:
* doRemapFormToApi -> remapFormToApi
* doUploadSwitch -> doUpload
* proccessIframeResult -> processIframeResult
* getEditForm -> getForm
* dispProgressOverlay -> displayProgressOverlay
* cancel_button -> getCancelButton
* cancel_action -> onCancel
* doControlHTML -> createControls
* getTargetHtml -> getControlHtml
* doControlBindings -> bindControls
* getOSlink -> getFirefoggInstallUrl
* doPreviewControl -> createPreviewControls
* doRenderPreview -> renderPreview
* selectFogg -> selectSourceFile
* selectFoggActions -> updateSourceFileUI
* saveLocalFogg -> doLocalEncodeAndSave
* doChunkWithFormData -> doChunkUploadWithFormData
* proccessPresetControl -> getPresetControlHtml
* proccessCkControlHTML -> getConfigControlHtml
* selectByUrl -> selectSourceUrl

* Promoted anonymous functions to methods:
* onSubmit
* onAjaxUploadStatusTimer
* onAjaxUploadStatusResponse
* onPreviewClick

In mvBaseUploadInterface:
* Made http_copy_upload lazy-initialised
* Made detectUploadMode() do only what it says, moved the actual upload stage to a callback.
* Refactored doUpload(), splitting out doApiCopyUpload() and doPostUpload()
* Refactored apiUpdateErrorCheck() into isApiSuccess() and showApiError()

In mvFirefogg:
* Made have_firefogg, sourceFileInfo lazy initialised
* Rearranged autoEncoderSettings() to make it the accessor getEncoderSettings()
* Rearranged firefoggCheck() to make it the accessor getFirefogg()
* Split encodeDone into the anonymous doEncode() done callbacks, and also the new function onLocalEncodeDone()

In mvAdvFirefogg:
* Refactored autoEncoderSettings() into getEncoderSetings() and updateSourceFileUI()

Elsewhere:
* Fixed spelling error UploadBase::MIN_LENGHT_PARTNAME
Modified paths:
  • /trunk/phase3/includes/api/ApiUpload.php (modified) (history)
  • /trunk/phase3/includes/upload/UploadBase.php (modified) (history)
  • /trunk/phase3/js2/mwEmbed/libAddMedia/mvAdvFirefogg.js (modified) (history)
  • /trunk/phase3/js2/mwEmbed/libAddMedia/mvBaseUploadInterface.js (modified) (history)
  • /trunk/phase3/js2/mwEmbed/libAddMedia/mvFirefogg.js (modified) (history)
  • /trunk/phase3/js2/mwEmbed/php/languages/mwEmbed.i18n.php (modified) (history)
  • /trunk/phase3/js2/uploadPage.js (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/api/ApiUpload.php
@@ -231,7 +231,7 @@
232232 'allowed' => $wgFileExtensions
233233 ) );
234234 break;
235 - case UploadBase::MIN_LENGHT_PARTNAME:
 235+ case UploadBase::MIN_LENGTH_PARTNAME:
236236 $this->dieUsage( 'The filename is too short', 'filename-tooshort' );
237237 break;
238238 case UploadBase::ILLEGAL_FILENAME:
Index: trunk/phase3/includes/upload/UploadBase.php
@@ -31,7 +31,6 @@
3232 const VERIFICATION_ERROR = 10;
3333 const UPLOAD_VERIFICATION_ERROR = 11;
3434 const HOOK_ABORTED = 11;
35 - const MIN_LENGHT_PARTNAME = 14;
3635
3736 const SESSION_VERSION = 2;
3837
Index: trunk/phase3/js2/uploadPage.js
@@ -3,7 +3,7 @@
44 * It controls the invocation of the mvUploader class based on local config.
55 */
66
7 -var mwUploadFormTarget = '#mw-upload-form';
 7+var mwUploadFormSelector = '#mw-upload-form';
88 // Set up the upload form bindings once all DOM manipulation is done
99 var mwUploadHelper = {
1010 init: function() {
@@ -18,7 +18,7 @@
1919 // An API URL (we won't submit directly to action of the form)
2020 'api_url': wgServer + wgScriptPath + '/api.php',
2121 'form_rewrite': true,
22 - 'target_edit_from': mwUploadFormTarget,
 22+ 'edit_form_selector': mwUploadFormSelector,
2323 'new_source_cb': function( orgFilename, oggName ) {
2424 $j( '#wpDestFile' ).val( oggName );
2525 $j( '#wpDestFile' ).doDestCheck( {
@@ -32,7 +32,7 @@
3333 if ( $j( '#wpUploadFileURL' ).length != 0 ) {
3434 $j( '#wpUploadFileURL' ).baseUploadInterface( {
3535 'api_url': wgServer + wgScriptPath + '/api.php',
36 - 'target_edit_from': mwUploadFormTarget
 36+ 'edit_form_selector': mwUploadFormSelector
3737 } );
3838 }
3939 }
Index: trunk/phase3/js2/mwEmbed/php/languages/mwEmbed.i18n.php
@@ -141,11 +141,11 @@
142142 'fogg-select_new_file' => 'Select new file',
143143 'fogg-select_url' => 'Select URL',
144144 'fogg-save_local_file' => 'Save Ogg',
145 - 'fogg-check_for_fogg' => 'Checking for Firefogg...',
 145+ 'fogg-check_for_firefogg' => 'Checking for Firefogg...',
146146 'fogg-installed' => 'Firefogg is installed',
147 - 'fogg-for_improved_uplods' => 'For improved uploads:',
 147+ 'fogg-for_improved_uploads' => 'For improved uploads:',
148148 'fogg-please_install' => '<a href="$1">Install Firefogg</a>. More <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">about Firefogg</a>.',
149 - 'fogg-use_latest_fox' => 'Please first install <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (or later). <i>Then revisit this page to install the <b>Firefogg</b> extension.</i>',
 149+ 'fogg-use_latest_firefox' => 'Please first install <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (or later). <i>Then revisit this page to install the <b>Firefogg</b> extension.</i>',
150150 'fogg-passthrough_mode' => 'Your selected file is already Ogg or not a video file',
151151 'fogg-transcoding' => 'Encoding video to Ogg...',
152152 'fogg-encoding-done' => 'Encoding complete',
@@ -594,7 +594,7 @@
595595 'fogg-select_new_file' => 'اختر ملفًا جديدًا',
596596 'fogg-select_url' => 'اختر مسارًا',
597597 'fogg-save_local_file' => 'احفظ Ogg',
598 - 'fogg-check_for_fogg' => 'يلتمس Firefogg...',
 598+ 'fogg-check_for_firefogg' => 'يلتمس Firefogg...',
599599 'fogg-installed' => 'Firefogg مُثبّت',
600600 'fogg-transcoding' => 'ترميز الفيديو إلى Ogg',
601601 'fogg-encoding-done' => 'انتهى الترميز',
@@ -775,11 +775,11 @@
776776 'fogg-select_new_file' => 'Выберыце новы файл',
777777 'fogg-select_url' => 'Выберыце URL-адрас',
778778 'fogg-save_local_file' => 'Захаваць Ogg',
779 - 'fogg-check_for_fogg' => 'Праверка наяўнасьці Firefogg …',
 779+ 'fogg-check_for_firefogg' => 'Праверка наяўнасьці Firefogg …',
780780 'fogg-installed' => 'Firefogg усталяваны',
781 - 'fogg-for_improved_uplods' => 'Для палепшаных загрузак:',
 781+ 'fogg-for_improved_uploads' => 'Для палепшаных загрузак:',
782782 'fogg-please_install' => '<a href="$1">Усталяваць Firefogg</a>. Болей <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">пра Firefogg</a>',
783 - 'fogg-use_latest_fox' => 'Калі ласка, спачатку ўсталюйце <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (ці больш позьнюю вэрсію). <i>Потым зноў наведайце гэтую старонку і ўсталюйце пашырэньне <b>Firefogg</b>.</i>',
 783+ 'fogg-use_latest_firefox' => 'Калі ласка, спачатку ўсталюйце <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (ці больш позьнюю вэрсію). <i>Потым зноў наведайце гэтую старонку і ўсталюйце пашырэньне <b>Firefogg</b>.</i>',
784784 'fogg-passthrough_mode' => 'Выбраны Вамі файл ужо ў фармаце Ogg альбо не зьяўляецца відэа-файлам',
785785 'fogg-transcoding' => 'Перакадыроўка відэа ў фармат Ogg',
786786 'fogg-encoding-done' => 'Перакадыроўка скончаная',
@@ -1165,7 +1165,7 @@
11661166 'fogg-select_new_file' => 'Odaberi novu datoteku',
11671167 'fogg-select_url' => 'Odaberi URL',
11681168 'fogg-save_local_file' => 'Sačuvaj Ogg',
1169 - 'fogg-check_for_fogg' => 'Provjera za Firefogg ...',
 1169+ 'fogg-check_for_firefogg' => 'Provjera za Firefogg ...',
11701170 'fogg-installed' => 'Firefogg je instaliran',
11711171 'fogg-passthrough_mode' => 'Vaša odabrana datoteka je već Ogg ili nije video datoteka',
11721172 'fogg-badtoken' => 'Token nije valjan',
@@ -1264,11 +1264,11 @@
12651265 'mwe-loading_txt' => 'Načítá se …',
12661266 'mwe-loading-add-media-wiz' => 'Načítá se průvodce pro přidání souboru',
12671267 'mwe-cancel' => 'Storno',
1268 - 'fogg-check_for_fogg' => 'Ověřuje se Firefogg…',
 1268+ 'fogg-check_for_firefogg' => 'Ověřuje se Firefogg…',
12691269 'fogg-installed' => 'Firefogg je nainstalován',
1270 - 'fogg-for_improved_uplods' => 'Pro vylepšené načítání:',
 1270+ 'fogg-for_improved_uploads' => 'Pro vylepšené načítání:',
12711271 'fogg-please_install' => '<a href="$1">Nainstalujte si Firefogg.</a> <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg/cs">Další informace o&nbsp;Firefoggu</a>',
1272 - 'fogg-use_latest_fox' => 'Nejprve si nainstalujte <a href="http://www.mozilla-europe.org/cs/firefox/?from=firefogg">Firefox 3.5</a> (nebo novější). <i>Poté se vraťte na tuto stránku, abyste si mohli nainstalovat rozšíření <b>Firefogg</b>.</i>',
 1272+ 'fogg-use_latest_firefox' => 'Nejprve si nainstalujte <a href="http://www.mozilla-europe.org/cs/firefox/?from=firefogg">Firefox 3.5</a> (nebo novější). <i>Poté se vraťte na tuto stránku, abyste si mohli nainstalovat rozšíření <b>Firefogg</b>.</i>',
12731273 'mwe-add_media_wizard' => 'Průvodce pro přidání souboru',
12741274 'mwe-media_search' => 'Hledání multimédií',
12751275 'rsd_box_layout' => 'Ikony',
@@ -1437,11 +1437,11 @@
14381438 'fogg-select_new_file' => 'Wähle eine neue Datei',
14391439 'fogg-select_url' => 'Wähle eine URL',
14401440 'fogg-save_local_file' => 'Ogg speichern',
1441 - 'fogg-check_for_fogg' => 'Suche nach Firefogg …',
 1441+ 'fogg-check_for_firefogg' => 'Suche nach Firefogg …',
14421442 'fogg-installed' => 'Firefogg ist installiert',
1443 - 'fogg-for_improved_uplods' => 'Für verbessertes Hochladen:',
 1443+ 'fogg-for_improved_uploads' => 'Für verbessertes Hochladen:',
14441444 'fogg-please_install' => '<a href="$1">Installiere Firefogg</a>. Mehr <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">über Firefogg</a>',
1445 - 'fogg-use_latest_fox' => 'Installiere bitte zuerst [http://de.www.mozilla.com/de/ Firefox 3.5] (oder eine spätere Version).
 1445+ 'fogg-use_latest_firefox' => 'Installiere bitte zuerst [http://de.www.mozilla.com/de/ Firefox 3.5] (oder eine spätere Version).
14461446 <i>Besuche danach die Seite neu, um die <b>Firefogg</b>-Erweiterung zu installieren.</i>',
14471447 'fogg-passthrough_mode' => 'Deine ausgewählte Datei ist bereits Ogg oder keine Videodatei',
14481448 'fogg-transcoding' => 'Codiere Video nach Ogg',
@@ -1735,11 +1735,11 @@
17361736 'fogg-select_new_file' => 'dosyaya neweyi bıweçin',
17371737 'fogg-select_url' => 'URL bıweçin',
17381738 'fogg-save_local_file' => 'Ogg qeyd bıker',
1739 - 'fogg-check_for_fogg' => 'Firefogg kontrol beno...',
 1739+ 'fogg-check_for_firefogg' => 'Firefogg kontrol beno...',
17401740 'fogg-installed' => 'Firefogg bar bı',
1741 - 'fogg-for_improved_uplods' => 'qey barkerdışê dewlemend biyayeyani:',
 1741+ 'fogg-for_improved_uploads' => 'qey barkerdışê dewlemend biyayeyani:',
17421742 'fogg-please_install' => '<a href="$1">Firefogg bar ker</a>. <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">derheqê firefoggi de</a>',
1743 - 'fogg-use_latest_fox' => 'kerem kerê ewwil <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a>\'i barkerê. <i>u hema parçeyê <b>Firefogg</b> i bar kerê, qey barkerdışi no pel ziyaret bıkerê</i>',
 1743+ 'fogg-use_latest_firefox' => 'kerem kerê ewwil <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a>\'i barkerê. <i>u hema parçeyê <b>Firefogg</b> i bar kerê, qey barkerdışi no pel ziyaret bıkerê</i>',
17441744 'fogg-passthrough_mode' => 'dosyaya ke şıma weçina ca ra yew dosyaya Oggi ya zi videoyi niyo',
17451745 'fogg-transcoding' => 'Video Ogg ra kod beno',
17461746 'fogg-encoding-done' => 'kodkerdış temam bı',
@@ -2045,11 +2045,11 @@
20462046 'fogg-select_new_file' => 'Nowu dataju wubraś',
20472047 'fogg-select_url' => 'URL wubraś',
20482048 'fogg-save_local_file' => 'Ogg składowaś',
2049 - 'fogg-check_for_fogg' => 'Za Firefogg pśeglědaś ...',
 2049+ 'fogg-check_for_firefogg' => 'Za Firefogg pśeglědaś ...',
20502050 'fogg-installed' => 'Firefogg jo instalěrowany.',
2051 - 'fogg-for_improved_uplods' => 'Za pólěpšone nagraśa:',
 2051+ 'fogg-for_improved_uploads' => 'Za pólěpšone nagraśa:',
20522052 'fogg-please_install' => '<a href="$1">Firefogg instalěrowaś</a>. Wjace <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">wó Firefogg</a>',
2053 - 'fogg-use_latest_fox' => 'Pšosym instalěruj njepjerwjej <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (abo wuši). <i>Woglědaj pótom k toś tomu bokoju zasego, aby rozšyrjenje <b>Firefogg</b> instalěrował.</i>',
 2053+ 'fogg-use_latest_firefox' => 'Pšosym instalěruj njepjerwjej <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (abo wuši). <i>Woglědaj pótom k toś tomu bokoju zasego, aby rozšyrjenje <b>Firefogg</b> instalěrował.</i>',
20542054 'fogg-passthrough_mode' => 'Twója wubrana dataja jo južo dataja Ogg abo njejo wideojowa dataja',
20552055 'fogg-transcoding' => 'Wideo do Ogg koděrowaś',
20562056 'fogg-encoding-done' => 'Koděrowanje skóńcone',
@@ -2317,7 +2317,7 @@
23182318 'fogg-select_url' => 'Επιλογή URL',
23192319 'fogg-save_local_file' => 'Αποθήκευση Οgg',
23202320 'fogg-installed' => 'Ο Firefogg είναι εγκατεστημένος',
2321 - 'fogg-for_improved_uplods' => 'Για βελτιωμένες φορτώσεις:',
 2321+ 'fogg-for_improved_uploads' => 'Για βελτιωμένες φορτώσεις:',
23222322 'fogg-transcoding' => 'Κωδικοποίηση βίντεο σε Ogg',
23232323 'fogg-encoding-done' => 'Κωδικοποίηση πλήρης',
23242324 'fogg-badtoken' => 'Το δείγμα δεν είναι έγκυρο',
@@ -2420,7 +2420,7 @@
24212421 'fogg-select_new_file' => 'Elekti novan dosieron',
24222422 'fogg-select_url' => 'Elekti URL-on',
24232423 'fogg-installed' => 'Instalis Firefogg',
2424 - 'fogg-use_latest_fox' => 'Bonvolu antaŭe instali <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox (Fajrvulpo) 3.5</a> (or later). <i>Poste revenu al ĉi tiu paĝo por instali la kromprogramon <b>Firefogg</b>.</i>',
 2424+ 'fogg-use_latest_firefox' => 'Bonvolu antaŭe instali <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox (Fajrvulpo) 3.5</a> (or later). <i>Poste revenu al ĉi tiu paĝo por instali la kromprogramon <b>Firefogg</b>.</i>',
24252425 'fogg-hidepreview' => 'Kaŝi antaŭvidon',
24262426 'fogg-videoQuality-title' => 'Videa kvalito',
24272427 'fogg-starttime-title' => 'Komenca sekundo',
@@ -2545,11 +2545,11 @@
25462546 'fogg-select_new_file' => 'Seleccionar nuevo archivo',
25472547 'fogg-select_url' => 'Seleccionar URL',
25482548 'fogg-save_local_file' => 'Grabar Ogg',
2549 - 'fogg-check_for_fogg' => 'Verificando Firefogg ...',
 2549+ 'fogg-check_for_firefogg' => 'Verificando Firefogg ...',
25502550 'fogg-installed' => 'Firefogg está instalado',
2551 - 'fogg-for_improved_uplods' => 'Para cargas mejoradas:',
 2551+ 'fogg-for_improved_uploads' => 'Para cargas mejoradas:',
25522552 'fogg-please_install' => '<a href="$1">Instalar Firefogg</a>. Más <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">acerca de Firefogg</a>',
2553 - 'fogg-use_latest_fox' => 'Por favor primero instala <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (o posterior). <i>Luego vuelve a visitar esta página para instalar la extensión <b>Firefogg</b>.</i>',
 2553+ 'fogg-use_latest_firefox' => 'Por favor primero instala <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (o posterior). <i>Luego vuelve a visitar esta página para instalar la extensión <b>Firefogg</b>.</i>',
25542554 'fogg-passthrough_mode' => 'Tu archivo seleccionado ya es Ogg o no es un archivo de video',
25552555 'fogg-transcoding' => 'Codificando video a Ogg',
25562556 'fogg-encoding-done' => 'Codificación completa',
@@ -2812,9 +2812,9 @@
28132813 'fogg-select_url' => 'Valitse URL',
28142814 'fogg-save_local_file' => 'Tallenna Ogg',
28152815 'fogg-installed' => 'Firefogg on asennettu',
2816 - 'fogg-for_improved_uplods' => 'Parannettua tallentamista varten:',
 2816+ 'fogg-for_improved_uploads' => 'Parannettua tallentamista varten:',
28172817 'fogg-please_install' => '<a href="$1">Asenna Firefogg</a> – <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">Tietoja Firefoggista</a>.',
2818 - 'fogg-use_latest_fox' => 'Asenna ensin <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (tai uudempi). <i>Tule sen jälkeen uudelleen tälle sivulle ja asenna <b>Firefogg</b>-laajennus.</i>',
 2818+ 'fogg-use_latest_firefox' => 'Asenna ensin <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (tai uudempi). <i>Tule sen jälkeen uudelleen tälle sivulle ja asenna <b>Firefogg</b>-laajennus.</i>',
28192819 'fogg-preview' => 'Videon esikatselu',
28202820 'fogg-hidepreview' => 'Piilota esikatselu',
28212821 'fogg-audioQuality-title' => 'Äänenlaatu',
@@ -2971,11 +2971,11 @@
29722972 'fogg-select_new_file' => 'Sélectionnez un nouveau fichier',
29732973 'fogg-select_url' => 'Sélectionnez une URL',
29742974 'fogg-save_local_file' => 'Sauvegarder au format Ogg',
2975 - 'fogg-check_for_fogg' => 'Vérification de Firefogg ...',
 2975+ 'fogg-check_for_firefogg' => 'Vérification de Firefogg ...',
29762976 'fogg-installed' => 'Firefogg est installé',
2977 - 'fogg-for_improved_uplods' => 'Pour des téléversements améliorés :',
 2977+ 'fogg-for_improved_uploads' => 'Pour des téléversements améliorés :',
29782978 'fogg-please_install' => '<a href="$1">Installer Firefogg</a>. Plus d\'infos <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">sur Firefogg</a>',
2979 - 'fogg-use_latest_fox' => 'Veuillez d\'abord installer <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (ou plus récent). <i>Puis revenez sur cette page pour installer l\'extension <b>Firefogg</b>.</i>',
 2979+ 'fogg-use_latest_firefox' => 'Veuillez d\'abord installer <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (ou plus récent). <i>Puis revenez sur cette page pour installer l\'extension <b>Firefogg</b>.</i>',
29802980 'fogg-passthrough_mode' => "Le fichier que vous avez sélectionné est déjà au format Ogg ou n'est pas un fichier vidéo",
29812981 'fogg-transcoding' => "Encodage d'une vidéo au format Ogg",
29822982 'fogg-encoding-done' => 'Encodage terminé',
@@ -3282,11 +3282,11 @@
32833283 'fogg-select_new_file' => 'Seleccione un ficheiro novo',
32843284 'fogg-select_url' => 'Seleccione un enderezo URL',
32853285 'fogg-save_local_file' => 'Gardar en formato Ogg',
3286 - 'fogg-check_for_fogg' => 'Examinando en busca do Firefogg...',
 3286+ 'fogg-check_for_firefogg' => 'Examinando en busca do Firefogg...',
32873287 'fogg-installed' => 'O Firefogg está instalado',
3288 - 'fogg-for_improved_uplods' => 'Para cargas melloradas:',
 3288+ 'fogg-for_improved_uploads' => 'Para cargas melloradas:',
32893289 'fogg-please_install' => '<a href="$1">Instalar o Firefogg</a>. Máis información <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">acerca do Firefogg</a>',
3290 - 'fogg-use_latest_fox' => 'Por favor, instale primeiro o <a href="http://gl.www.mozilla.com/gl/">Firefox 3.5</a> (ou superior). <i>Logo diso, volte a esta páxina para instalar a extensión <b>Firefogg</b>.</i>',
 3290+ 'fogg-use_latest_firefox' => 'Por favor, instale primeiro o <a href="http://gl.www.mozilla.com/gl/">Firefox 3.5</a> (ou superior). <i>Logo diso, volte a esta páxina para instalar a extensión <b>Firefogg</b>.</i>',
32913291 'fogg-passthrough_mode' => 'O ficheiro que seleccionou xa está en formato Ogg ou non é un ficheiro de vídeo',
32923292 'fogg-transcoding' => 'Codificando o vídeo en formato Ogg',
32933293 'fogg-encoding-done' => 'Codificación completa',
@@ -3605,11 +3605,11 @@
36063606 'fogg-select_new_file' => 'Neji Datei uuswehle',
36073607 'fogg-select_url' => 'URL uuswehle',
36083608 'fogg-save_local_file' => 'Ogg spychere',
3609 - 'fogg-check_for_fogg' => 'Am Priefe vu Firefogg ...',
 3609+ 'fogg-check_for_firefogg' => 'Am Priefe vu Firefogg ...',
36103610 'fogg-installed' => 'Firefogg isch inschtalliert',
3611 - 'fogg-for_improved_uplods' => 'Fir e verbesseret Uffelade:',
 3611+ 'fogg-for_improved_uploads' => 'Fir e verbesseret Uffelade:',
36123612 'fogg-please_install' => '<a href="$1">Firefogg inschtalliere</a>. Meh <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">Informatione iber Firefogg</a>',
3613 - 'fogg-use_latest_fox' => 'Bitte ischtallier zerscht <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (oder e nejeri Version). <i>DErno gang wider uf die Syte go d <b>Firefogg</b>-Erwyterig inschtalliere.</i>',
 3613+ 'fogg-use_latest_firefox' => 'Bitte ischtallier zerscht <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (oder e nejeri Version). <i>DErno gang wider uf die Syte go d <b>Firefogg</b>-Erwyterig inschtalliere.</i>',
36143614 'fogg-passthrough_mode' => 'D Datei, wu Du uusgwehlt hesch, isch schon im Ogg-Format oder s het kei Video din',
36153615 'fogg-transcoding' => 'Am Umwandle vum Video in s Ogg-Format',
36163616 'fogg-encoding-done' => 'Umwandlig fertig',
@@ -3891,11 +3891,11 @@
38923892 'fogg-select_new_file' => 'בחירת קובץ חדש',
38933893 'fogg-select_url' => 'בחירת כתובת',
38943894 'fogg-save_local_file' => 'שמירת ה־Ogg',
3895 - 'fogg-check_for_fogg' => 'מתבצעת בדיקה האם מותקן Firefogg ...',
 3895+ 'fogg-check_for_firefogg' => 'מתבצעת בדיקה האם מותקן Firefogg ...',
38963896 'fogg-installed' => 'Firefogg מותקן',
3897 - 'fogg-for_improved_uplods' => 'להעלאות משופרות:',
 3897+ 'fogg-for_improved_uploads' => 'להעלאות משופרות:',
38983898 'fogg-please_install' => '<a href="$1">להתקנת Firefogg</a>. עוד <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">אודות Firefogg</a>',
3899 - 'fogg-use_latest_fox' => 'ראשית יש להתקין את <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (ומעלה). <b>לאחר מכן יש לבקר בדף זה שוב כדי להתקין את ההרחבה <i>Firefogg</i>.</b>',
 3899+ 'fogg-use_latest_firefox' => 'ראשית יש להתקין את <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (ומעלה). <b>לאחר מכן יש לבקר בדף זה שוב כדי להתקין את ההרחבה <i>Firefogg</i>.</b>',
39003900 'fogg-passthrough_mode' => 'הקובץ שנבחר הוא כבר קובץ Ogg או שאינו קובץ וידאו',
39013901 'fogg-transcoding' => 'קידוד הווידאו ל־Ogg',
39023902 'fogg-encoding-done' => 'הקידוד הושלם',
@@ -4080,11 +4080,11 @@
40814081 'fogg-select_new_file' => 'Nowu dataju wubrać',
40824082 'fogg-select_url' => 'URL wubrać',
40834083 'fogg-save_local_file' => 'Ogg składować',
4084 - 'fogg-check_for_fogg' => 'Pruwowanje za Firefogg ...',
 4084+ 'fogg-check_for_firefogg' => 'Pruwowanje za Firefogg ...',
40854085 'fogg-installed' => 'Firefogg so instaluje',
4086 - 'fogg-for_improved_uplods' => 'Za polěpšene nahraća:',
 4086+ 'fogg-for_improved_uploads' => 'Za polěpšene nahraća:',
40874087 'fogg-please_install' => '<a href="$1">Firefogg instalować</a>. Wjace <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">wo Firefoggu</a>',
4088 - 'fogg-use_latest_fox' => 'Prošu instalu najprjedy <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (abo wyše). <i>Potom wopytaj tutu strona znowa, zo by rozšěrjenje <b>Firefogg</b> instalował.</i>',
 4088+ 'fogg-use_latest_firefox' => 'Prošu instalu najprjedy <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (abo wyše). <i>Potom wopytaj tutu strona znowa, zo by rozšěrjenje <b>Firefogg</b> instalował.</i>',
40894089 'fogg-passthrough_mode' => 'Twoja wubrana dataja je hižo Ogg abo njeje widejowa dataja',
40904090 'fogg-transcoding' => 'Kodowanje wideja do Ogg',
40914091 'fogg-encoding-done' => 'Kodowanje hotowe',
@@ -4393,11 +4393,11 @@
43944394 'fogg-select_new_file' => 'Új fájl kiválasztása',
43954395 'fogg-select_url' => 'URL kiválasztása',
43964396 'fogg-save_local_file' => 'Ogg mentése',
4397 - 'fogg-check_for_fogg' => 'Firefogg keresése…',
 4397+ 'fogg-check_for_firefogg' => 'Firefogg keresése…',
43984398 'fogg-installed' => 'Firefogg telepítve',
4399 - 'fogg-for_improved_uplods' => 'Fejlettebb feltöltésekhez:',
 4399+ 'fogg-for_improved_uploads' => 'Fejlettebb feltöltésekhez:',
44004400 'fogg-please_install' => '<a href="$1">Firefogg telepítése</a>. További információkat <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">itt</a> találsz róla.',
4401 - 'fogg-use_latest_fox' => 'Először telepítsd a <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a>-ös, vagy újabb verzióját, <i>majd látogass el ide újra a <b>Firefogg</b>-kiterjesztés telepítéséhez.</i>',
 4401+ 'fogg-use_latest_firefox' => 'Először telepítsd a <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a>-ös, vagy újabb verzióját, <i>majd látogass el ide újra a <b>Firefogg</b>-kiterjesztés telepítéséhez.</i>',
44024402 'fogg-passthrough_mode' => 'Az általad kiválasztott fájl már Ogg formátumban van, vagy nem videófájl',
44034403 'fogg-transcoding' => 'Videó kódolása Ogg formátumba',
44044404 'fogg-encoding-done' => 'A kódolás kész',
@@ -4704,11 +4704,11 @@
47054705 'fogg-select_new_file' => 'Seliger nove file',
47064706 'fogg-select_url' => 'Seliger URL',
47074707 'fogg-save_local_file' => 'Immagazinar in Ogg',
4708 - 'fogg-check_for_fogg' => 'Verifica presentia de Firefogg ...',
 4708+ 'fogg-check_for_firefogg' => 'Verifica presentia de Firefogg ...',
47094709 'fogg-installed' => 'Firefogg es installate',
4710 - 'fogg-for_improved_uplods' => 'Pro cargamentos meliorate:',
 4710+ 'fogg-for_improved_uploads' => 'Pro cargamentos meliorate:',
47114711 'fogg-please_install' => '<a href="$1">Installar Firefogg</a>. Plus information <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">a proposito de Firefogg</a>',
4712 - 'fogg-use_latest_fox' => 'Per favor primo installa <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (o plus recente). <i>Alora revisita iste pagina pro installar le extension <b>Firefogg</b>.</i>',
 4712+ 'fogg-use_latest_firefox' => 'Per favor primo installa <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (o plus recente). <i>Alora revisita iste pagina pro installar le extension <b>Firefogg</b>.</i>',
47134713 'fogg-passthrough_mode' => 'Le file que tu seligeva ja es in Ogg, o non es un file video',
47144714 'fogg-transcoding' => 'Codification del video in Ogg',
47154715 'fogg-encoding-done' => 'Codification complete',
@@ -5016,11 +5016,11 @@
50175017 'fogg-select_new_file' => 'Pilih berkas baru',
50185018 'fogg-select_url' => 'Pilih URL',
50195019 'fogg-save_local_file' => 'Simpan Ogg',
5020 - 'fogg-check_for_fogg' => 'Mengecek Firefogg...',
 5020+ 'fogg-check_for_firefogg' => 'Mengecek Firefogg...',
50215021 'fogg-installed' => 'Firefogg telah terinstal',
5022 - 'fogg-for_improved_uplods' => 'Untuk pengunggahan canggih:',
 5022+ 'fogg-for_improved_uploads' => 'Untuk pengunggahan canggih:',
50235023 'fogg-please_install' => '<a href="$1">Instal Firefogg.</a> Lebih lanjut <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">tentang Firefogg.</a>',
5024 - 'fogg-use_latest_fox' => 'Silakan instal dulu <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (atau lebih baru). <i>Kemudian kunjungi kembali halaman ini untuk menginstal ekstensi <b>Firefogg</b>.</i>',
 5024+ 'fogg-use_latest_firefox' => 'Silakan instal dulu <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (atau lebih baru). <i>Kemudian kunjungi kembali halaman ini untuk menginstal ekstensi <b>Firefogg</b>.</i>',
50255025 'fogg-passthrough_mode' => 'Berkas yang dipilih sudah berformat Ogg atau bukan suatu berkas video',
50265026 'fogg-transcoding' => 'Mengkodekan video ke Ogg...',
50275027 'fogg-encoding-done' => 'Pengkodean selesai',
@@ -5376,11 +5376,11 @@
53775377 'fogg-select_new_file' => '別のファイルを選択',
53785378 'fogg-select_url' => 'URLを選択',
53795379 'fogg-save_local_file' => 'Ogg を保存',
5380 - 'fogg-check_for_fogg' => 'Firefogg を確認しています ...',
 5380+ 'fogg-check_for_firefogg' => 'Firefogg を確認しています ...',
53815381 'fogg-installed' => 'Firefogg はインストールされています',
5382 - 'fogg-for_improved_uplods' => 'アップロードをより便利にするには:',
 5382+ 'fogg-for_improved_uploads' => 'アップロードをより便利にするには:',
53835383 'fogg-please_install' => '<a href="$1">Firefogg をインストール</a>。<a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">Firefogg について</a>。',
5384 - 'fogg-use_latest_fox' => 'はじめに <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5 (以降)</a>をインストールしてください。<i>次にこのページを再読み込みし、 <b>Firefogg</b> 拡張機能をインストールしてください。</i>',
 5384+ 'fogg-use_latest_firefox' => 'はじめに <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5 (以降)</a>をインストールしてください。<i>次にこのページを再読み込みし、 <b>Firefogg</b> 拡張機能をインストールしてください。</i>',
53855385 'fogg-passthrough_mode' => '選択したファイルはすでに Ogg 形式であるか、動画ファイルではありません',
53865386 'fogg-transcoding' => '動画を Ogg に形式変換',
53875387 'fogg-encoding-done' => '形式変換終了',
@@ -5733,11 +5733,11 @@
57345734 'fogg-select_new_file' => 'Neu Dattei ußwähle',
57355735 'fogg-select_url' => '<i lang="en">URL</i> ußwähle',
57365736 'fogg-save_local_file' => 'Ogg afshpeijshere',
5737 - 'fogg-check_for_fogg' => 'Op <i lang="en">Firefogg</i> aam Prööve&nbsp;…',
 5737+ 'fogg-check_for_firefogg' => 'Op <i lang="en">Firefogg</i> aam Prööve&nbsp;…',
57385738 'fogg-installed' => '<i lang="en">Firefogg</i> es ennjeresht',
5739 - 'fogg-for_improved_uplods' => 'För e verbäßert Huhlaade:&nbsp;',
 5739+ 'fogg-for_improved_uploads' => 'För e verbäßert Huhlaade:&nbsp;',
57405740 'fogg-please_install' => 'Donn <a href="$1"><i lang="en">Firefogg</i> ennreshte</a>. Kanns mieh <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">övver <i lang="en">Firefogg</i> lässe</a>.',
5741 - 'fogg-use_latest_fox' => 'Donn eets dä <i lang="en"><a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a></i> (odder neuer) enshtalleere. Donoh jangk widder op hee di Sigg, öm et Zohsazprojramm <i lang="en"><b>Firefogg</b></i> ze enshtalleere.',
 5741+ 'fogg-use_latest_firefox' => 'Donn eets dä <i lang="en"><a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a></i> (odder neuer) enshtalleere. Donoh jangk widder op hee di Sigg, öm et Zohsazprojramm <i lang="en"><b>Firefogg</b></i> ze enshtalleere.',
57425742 'fogg-passthrough_mode' => 'Ding ußjesöhk Dattei eß ald em <i lang="en">Ogg</i>-Fommaat, udder et eß jaa keine Viddejo drän.',
57435743 'fogg-transcoding' => 'Dä Viddejo weedt jraadt noh em <i lang="en">Ogg</i>-Fommaat ömjewandelt',
57445744 'fogg-encoding-done' => 'Ömwandlung es fäädesch',
@@ -5981,11 +5981,11 @@
59825982 'fogg-select_new_file' => 'Neie Fichier eraussichen',
59835983 'fogg-select_url' => 'URL eraussichen',
59845984 'fogg-save_local_file' => 'Ogg späicheren',
5985 - 'fogg-check_for_fogg' => 'Sichen no Firefogg ...',
 5985+ 'fogg-check_for_firefogg' => 'Sichen no Firefogg ...',
59865986 'fogg-installed' => 'Firefogg ass installéiert',
5987 - 'fogg-for_improved_uplods' => 'Fir verbessert Eroplueden:',
 5987+ 'fogg-for_improved_uploads' => 'Fir verbessert Eroplueden:',
59885988 'fogg-please_install' => '<a href="$1">Installéiert Firefogg</a>. Méi <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">iwwer Firefogg</a>',
5989 - 'fogg-use_latest_fox' => "Installéiert w.e.g. fir d'éischt <a href=\"http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg\">Firefox 3.5</a> (oder méi eng nei Versioun). <i>Kommt duerno zréck op dës Säit fir d'<b>Firefogg</b>-Erweiderung z'installéieren.</i>",
 5989+ 'fogg-use_latest_firefox' => "Installéiert w.e.g. fir d'éischt <a href=\"http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg\">Firefox 3.5</a> (oder méi eng nei Versioun). <i>Kommt duerno zréck op dës Säit fir d'<b>Firefogg</b>-Erweiderung z'installéieren.</i>",
59905990 'fogg-preview' => 'Video kucken ouni ze späicheren',
59915991 'mwe-imported_from' => "$1 huet vun [$2 $3] importéiert. Kuckt d'[$4 Originalquellsäit] fir méi Informatiounen.",
59925992 'mwe-stream_title' => '$1 $2 bis $3',
@@ -6190,11 +6190,11 @@
61916191 'fogg-select_new_file' => 'പുതിയ പ്രമാണം തിരഞ്ഞെടുക്കുക',
61926192 'fogg-select_url' => 'യു.ആർ.എൽ. തിരഞ്ഞെടുക്കുക',
61936193 'fogg-save_local_file' => 'ഓഗ് ആയി സേവ് ചെയ്യുക',
6194 - 'fogg-check_for_fogg' => 'ഫയർഫോഗ് തിരയുന്നു...',
 6194+ 'fogg-check_for_firefogg' => 'ഫയർഫോഗ് തിരയുന്നു...',
61956195 'fogg-installed' => 'ഫയർഫോഗ് ഇൻസ്റ്റോൾ ചെയ്തിട്ടുണ്ട്',
6196 - 'fogg-for_improved_uplods' => 'മെച്ചപ്പെടുത്തിയ അപ്‌‌ലോഡുകൾക്കു വേണ്ടി:',
 6196+ 'fogg-for_improved_uploads' => 'മെച്ചപ്പെടുത്തിയ അപ്‌‌ലോഡുകൾക്കു വേണ്ടി:',
61976197 'fogg-please_install' => '<a href="$1">ഫയർഫോഗ് ഇൻസ്റ്റോൾ ചെയ്യുക</a>. <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">ഫയർഫോഗിനെ കുറിച്ചു കൂടുതൽ</a>',
6198 - 'fogg-use_latest_fox' => 'ദയവായി <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">ഫയർഫോക്സ് 3.5</a> (അല്ലങ്കിൽ ശേഷമുള്ളത്) ആദ്യം ഇൻസ്റ്റോൾ ചെയ്യുക. <i>പിന്നീട് <b>Firefogg</b> അനുബന്ധത്തിനായി ഈ താൾ ഒന്നുകൂടി സന്ദർശിക്കുക.</i>',
 6198+ 'fogg-use_latest_firefox' => 'ദയവായി <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">ഫയർഫോക്സ് 3.5</a> (അല്ലങ്കിൽ ശേഷമുള്ളത്) ആദ്യം ഇൻസ്റ്റോൾ ചെയ്യുക. <i>പിന്നീട് <b>Firefogg</b> അനുബന്ധത്തിനായി ഈ താൾ ഒന്നുകൂടി സന്ദർശിക്കുക.</i>',
61996199 'fogg-passthrough_mode' => 'താങ്കൾ തിരഞ്ഞെടുത്ത പ്രമാണം ഓഗ് (Ogg) തന്നെയാണ് അല്ലങ്കിൽ വീഡിയോ പ്രമാണം അല്ല',
62006200 'fogg-transcoding' => 'ചലച്ചിത്രം ഓഗ് ആയി എൻകോഡ് ചെയ്യുന്നു...',
62016201 'fogg-encoding-done' => 'എൻകോഡിങ് പൂർണ്ണം',
@@ -6472,11 +6472,11 @@
64736473 'fogg-select_new_file' => 'Kies nuwe lêer',
64746474 'fogg-select_url' => 'URL selecteren',
64756475 'fogg-save_local_file' => 'Ogg opslaan',
6476 - 'fogg-check_for_fogg' => 'Firefogg aan het controleren ...',
 6476+ 'fogg-check_for_firefogg' => 'Firefogg aan het controleren ...',
64776477 'fogg-installed' => 'Firefogg is geïnstalleerd',
6478 - 'fogg-for_improved_uplods' => 'Voor verbeterde uploads:',
 6478+ 'fogg-for_improved_uploads' => 'Voor verbeterde uploads:',
64796479 'fogg-please_install' => '<a href="$1">Installeer Firefogg</a>. Meer <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">over Firefogg</a>',
6480 - 'fogg-use_latest_fox' => 'Installeer alstublieft eerst <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (of een latere versie).
 6480+ 'fogg-use_latest_firefox' => 'Installeer alstublieft eerst <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (of een latere versie).
64816481 <i>Kom daarna terug naar deze pagina om de uitbreiding <b>Firefogg</b> te installeren.</i>',
64826482 'fogg-passthrough_mode' => 'Het geselecteerde bestand is al een Ogg-bestand of geen videobestand',
64836483 'fogg-transcoding' => 'Bezig met het converteren van video naar Ogg',
@@ -6778,11 +6778,11 @@
67796779 'fogg-select_new_file' => 'Seleccionatz un fichièr novèl',
67806780 'fogg-select_url' => 'Seleccionatz una URL',
67816781 'fogg-save_local_file' => 'Salvar al format Ogg',
6782 - 'fogg-check_for_fogg' => 'Verificacion de Firefogg ...',
 6782+ 'fogg-check_for_firefogg' => 'Verificacion de Firefogg ...',
67836783 'fogg-installed' => 'Firefogg es installat',
6784 - 'fogg-for_improved_uplods' => 'Per de telecargaments melhorats :',
 6784+ 'fogg-for_improved_uploads' => 'Per de telecargaments melhorats :',
67856785 'fogg-please_install' => '<a href="$1">Installer Firefogg</a>. Mai d\'entresenhas <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">sus Firefogg</a>',
6786 - 'fogg-use_latest_fox' => 'D\'en primièr, installatz <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (o mai recent). <i>Puèi tornatz sus aquesta pagina per installar l\'extension <b>Firefogg</b>.</i>',
 6786+ 'fogg-use_latest_firefox' => 'D\'en primièr, installatz <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (o mai recent). <i>Puèi tornatz sus aquesta pagina per installar l\'extension <b>Firefogg</b>.</i>',
67876787 'fogg-passthrough_mode' => "Lo fichièr qu'avètz seleccionat es ja al format Ogg o es pas un fichièr vidèo",
67886788 'fogg-transcoding' => "Encodatge d'una vidèo al format Ogg",
67896789 'fogg-encoding-done' => 'Encodatge acabat',
@@ -7061,11 +7061,11 @@
70627062 'fogg-select_new_file' => 'Wybierz nowy plik',
70637063 'fogg-select_url' => 'Wybierz adres URL',
70647064 'fogg-save_local_file' => 'Zapisz w formacie Ogg',
7065 - 'fogg-check_for_fogg' => 'Sprawdzanie czy używasz Firefogg ...',
 7065+ 'fogg-check_for_firefogg' => 'Sprawdzanie czy używasz Firefogg ...',
70667066 'fogg-installed' => 'Firefogg jest zainstalowany',
7067 - 'fogg-for_improved_uplods' => 'Dla poprawy przesyłania:',
 7067+ 'fogg-for_improved_uploads' => 'Dla poprawy przesyłania:',
70687068 'fogg-please_install' => '<a href="$1">Zainstaluj Firefogg</a>. Więcej <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">o Firefogg</a>',
7069 - 'fogg-use_latest_fox' => 'Należy najpierw zainstalować <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (lub nowszy). <i>Następnie wejść ponownie na tę stronę, aby zainstalować rozszerzenie <b>Firefogg.</b></i>',
 7069+ 'fogg-use_latest_firefox' => 'Należy najpierw zainstalować <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (lub nowszy). <i>Następnie wejść ponownie na tę stronę, aby zainstalować rozszerzenie <b>Firefogg.</b></i>',
70707070 'fogg-passthrough_mode' => 'Wybrany przez Ciebie plik jest już w formacie Ogg lub nie jest plikiem wideo',
70717071 'fogg-transcoding' => 'Kodowanie wideo do formatu Ogg',
70727072 'fogg-encoding-done' => 'Kodowanie zakończone',
@@ -7266,9 +7266,9 @@
72677267 'fogg-save_local_file' => 'Gravar Ogg',
72687268 'fogg-check_for_fogg' => 'A procurar o Firefogg...',
72697269 'fogg-installed' => 'Firefogg está instalado',
7270 - 'fogg-for_improved_uplods' => 'Para optimizar os carregamentos:',
 7270+ 'fogg-for_improved_uploads' => 'Para optimizar os carregamentos:',
72717271 'fogg-please_install' => '<a href="$1">Instalar o Firefogg</a>. Mais <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">informações sobre o Firefogg</a>.',
7272 - 'fogg-use_latest_fox' => 'Por favor, instale primeiro o <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (ou versão mais recente). <i>Depois volte a esta página para instalar a extensão <b>Firefogg</b>.</i>',
 7272+ 'fogg-use_latest_firefox' => 'Por favor, instale primeiro o <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (ou versão mais recente). <i>Depois volte a esta página para instalar a extensão <b>Firefogg</b>.</i>',
72737273 'fogg-passthrough_mode' => 'O ficheiro seleccionado já é de formato Ogg ou não é um ficheiro de vídeo',
72747274 'fogg-transcoding' => 'Codificar vídeo para Ogg',
72757275 'fogg-encoding-done' => 'Codificação finalizada',
@@ -7498,11 +7498,11 @@
74997499 'fogg-select_new_file' => 'Выберите новый файл',
75007500 'fogg-select_url' => 'Выберите URL',
75017501 'fogg-save_local_file' => 'Сохранить Ogg',
7502 - 'fogg-check_for_fogg' => 'Проверка Firefogg …',
 7502+ 'fogg-check_for_firefogg' => 'Проверка Firefogg …',
75037503 'fogg-installed' => 'Firefogg установлен',
7504 - 'fogg-for_improved_uplods' => 'Для улучшенных загрузок:',
 7504+ 'fogg-for_improved_uploads' => 'Для улучшенных загрузок:',
75057505 'fogg-please_install' => '<a href="$1">Установить Firefogg</a>. Подробнее <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">о Firefogg</a>',
7506 - 'fogg-use_latest_fox' => 'Пожалуйста, сначала установите <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (или выше). <i>Затем повторно обратитесь к этой странице, чтобы установить расширение <b>Firefogg</b>.</i>',
 7506+ 'fogg-use_latest_firefox' => 'Пожалуйста, сначала установите <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (или выше). <i>Затем повторно обратитесь к этой странице, чтобы установить расширение <b>Firefogg</b>.</i>',
75077507 'fogg-passthrough_mode' => 'Выбранный файл уже Ogg или не является видео-файлом',
75087508 'fogg-transcoding' => 'Перекодирование видео в Ogg',
75097509 'fogg-encoding-done' => 'Перекодирование завершено',
@@ -7812,11 +7812,11 @@
78137813 'fogg-select_new_file' => 'Vybrať nový súbor',
78147814 'fogg-select_url' => 'Vybrať URL',
78157815 'fogg-save_local_file' => 'Uložiť Ogg',
7816 - 'fogg-check_for_fogg' => 'Kontroluje sa Firefogg ...',
 7816+ 'fogg-check_for_firefogg' => 'Kontroluje sa Firefogg ...',
78177817 'fogg-installed' => 'Firefogg je nainštalovaný',
7818 - 'fogg-for_improved_uplods' => 'Na vylepšenie nahrávania:',
 7818+ 'fogg-for_improved_uploads' => 'Na vylepšenie nahrávania:',
78197819 'fogg-please_install' => '<a href="$1">si nainštalujte Firefogg</a>. Ďalšie informácie o <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">Firefogg</a>',
7820 - 'fogg-use_latest_fox' => 'Najprv si prosím nainštalujte <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (alebo novší). <i>Po opätovnom navštívení tejto stránky si nainštalujte rozšírenie <b>Firefogg</b>.</i>',
 7820+ 'fogg-use_latest_firefox' => 'Najprv si prosím nainštalujte <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (alebo novší). <i>Po opätovnom navštívení tejto stránky si nainštalujte rozšírenie <b>Firefogg</b>.</i>',
78217821 'fogg-passthrough_mode' => 'Váš vybraný súbor je už Ogg alebo to nie je videosúbor',
78227822 'fogg-transcoding' => 'Prebieha prekódovanie videosúboru do Ogg',
78237823 'fogg-encoding-done' => 'Prekódovanie dokončené',
@@ -7937,11 +7937,11 @@
79387938 'fogg-select_new_file' => 'Välj ny fil',
79397939 'fogg-select_url' => 'Välj URL',
79407940 'fogg-save_local_file' => 'Spara Ogg',
7941 - 'fogg-check_for_fogg' => 'Kollar om Firefogg är installerat...',
 7941+ 'fogg-check_for_firefogg' => 'Kollar om Firefogg är installerat...',
79427942 'fogg-installed' => 'Firefogg är installerat',
7943 - 'fogg-for_improved_uplods' => 'För förbättrade uppladdningar:',
 7943+ 'fogg-for_improved_uploads' => 'För förbättrade uppladdningar:',
79447944 'fogg-please_install' => '<a href="$1">Installera Firefogg</a>. Mer <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">om Firefogg</a> (på engelska).',
7945 - 'fogg-use_latest_fox' => 'Vänligen installera först <a href="http://www.mozilla.com/sv-SE/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (eller senare). <i>Gå sedan tillbaka till den här sidan för att installera tillägget <b>Firefogg</b>.</i>',
 7945+ 'fogg-use_latest_firefox' => 'Vänligen installera först <a href="http://www.mozilla.com/sv-SE/firefox/upgrade.html?from=firefogg">Firefox 3.5</a> (eller senare). <i>Gå sedan tillbaka till den här sidan för att installera tillägget <b>Firefogg</b>.</i>',
79467946 'fogg-passthrough_mode' => 'Den valda filen är redan i formatet Ogg eller också är den inte en videofil över huvud taget',
79477947 'fogg-transcoding' => 'Kodar om videon till Ogg...',
79487948 'fogg-encoding-done' => 'Kodningen har avslutats',
@@ -8164,11 +8164,11 @@
81658165 'fogg-select_new_file' => 'Yeni dosyayı seç',
81668166 'fogg-select_url' => 'URLyi seç',
81678167 'fogg-save_local_file' => "Ogg'u kaydet",
8168 - 'fogg-check_for_fogg' => 'Firefogg kontrol ediliyor ...',
 8168+ 'fogg-check_for_firefogg' => 'Firefogg kontrol ediliyor ...',
81698169 'fogg-installed' => 'Firefogg yüklendi',
8170 - 'fogg-for_improved_uplods' => 'Gelişmiş yüklemeler için:',
 8170+ 'fogg-for_improved_uploads' => 'Gelişmiş yüklemeler için:',
81718171 'fogg-please_install' => '<a href="$1">Firefogg\'u yükle</a>. <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">Firefogg hakkında</a> daha fazla',
8172 - 'fogg-use_latest_fox' => 'Lütfen önce <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a>\'i (ya da sonrası) yükleyin. <i>Daha sonra <b>Firefogg</b> eklentisini yüklemek için bu sayfayı tekrar ziyaret edin.</i>',
 8172+ 'fogg-use_latest_firefox' => 'Lütfen önce <a href="http://www.mozilla.com/en-US/firefox/upgrade.html?from=firefogg">Firefox 3.5</a>\'i (ya da sonrası) yükleyin. <i>Daha sonra <b>Firefogg</b> eklentisini yüklemek için bu sayfayı tekrar ziyaret edin.</i>',
81738173 'fogg-passthrough_mode' => 'Seçtiğiniz dosya zaten Ogg ya da bir video dosyası değil',
81748174 'fogg-transcoding' => "Video Ogg'a kodlanıyor",
81758175 'fogg-encoding-done' => 'Kodlama tamamlandı',
@@ -8429,7 +8429,7 @@
84308430 'fogg-select_new_file' => 'Selessiona file novo',
84318431 'fogg-select_url' => 'Selessiona indirisso (URL)',
84328432 'fogg-save_local_file' => 'Salva come Ogg',
8433 - 'fogg-check_for_fogg' => "So' drio sercar el Firefogg...",
 8433+ 'fogg-check_for_firefogg' => "So' drio sercar el Firefogg...",
84348434 'fogg-installed' => 'El Firefogg el xe instalà',
84358435 'fogg-transcoding' => "So' drio codificar el video in formato Ogg",
84368436 'fogg-encoding-done' => 'Codifica conpletà',
@@ -8667,11 +8667,11 @@
86688668 'fogg-select_new_file' => 'Chọn tập tin mới',
86698669 'fogg-select_url' => 'Chọn URL',
86708670 'fogg-save_local_file' => 'Lưu thành Ogg',
8671 - 'fogg-check_for_fogg' => 'Đang tìm cho Firefogg …',
 8671+ 'fogg-check_for_firefogg' => 'Đang tìm cho Firefogg …',
86728672 'fogg-installed' => 'Firefogg đã được cài đặt',
8673 - 'fogg-for_improved_uplods' => 'Để tải lên tiện hơn:',
 8673+ 'fogg-for_improved_uploads' => 'Để tải lên tiện hơn:',
86748674 'fogg-please_install' => '<a href="$1">Cài Firefogg</a>. Thêm <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg?uselang=vi">chi tiết về Firefogg</a>',
8675 - 'fogg-use_latest_fox' => 'Xin hãy cài đặt <a href="http://vi.www.mozilla.com/vi/?from=firefogg">Firefox 3.5</a> (trở lên) trước tiên. <i>Sau đó, hãy trở lại trang này để cài đặt phần mở rộng <b>Firefogg</b>.</i>',
 8675+ 'fogg-use_latest_firefox' => 'Xin hãy cài đặt <a href="http://vi.www.mozilla.com/vi/?from=firefogg">Firefox 3.5</a> (trở lên) trước tiên. <i>Sau đó, hãy trở lại trang này để cài đặt phần mở rộng <b>Firefogg</b>.</i>',
86768676 'fogg-preview' => 'Xem trước video',
86778677 'fogg-hidepreview' => 'Ẩn phần xem trước',
86788678 'fogg-help-sticky' => 'Trợ giúp (nhấn chuột để giữ)',
Index: trunk/phase3/js2/mwEmbed/libAddMedia/mvBaseUploadInterface.js
@@ -1,5 +1,5 @@
22 /**
3 - * The base Upload Interface for uploading.
 3+ * The base upload interface.
44 *
55 * This base upload class is optionally extended by Firefogg
66 *
@@ -9,7 +9,7 @@
1010 "mwe-upload-in-progress" : "Upload in progress (do not close this window)",
1111 "mwe-upload-transcoded-status" : "Transcoded",
1212 "mwe-uploaded-status" : "Uploaded",
13 - "mwe-upload-stats-fileprogres" : "$1 of $2",
 13+ "mwe-upload-stats-fileprogress" : "$1 of $2",
1414 "mwe-upload_completed" : "Your upload is complete",
1515 "mwe-upload_done" : "<a href=\"$1\">Your upload <i>should be<\/i> accessible<\/a>.",
1616 "mwe-upload-unknown-size" : "Unknown size",
@@ -30,414 +30,562 @@
3131 });
3232
3333 var default_bui_options = {
34 - 'api_url':null,
35 - 'parent_uploader':null,
36 - 'edit_from':null,
 34+ 'api_url': null,
 35+ 'parent_uploader': null,
 36+ 'form': null,
3737 'done_upload_cb': null,
38 - 'target_edit_from':null,
 38+ 'form_selector': null,
3939
4040 // Default upload mode is 'api'
4141 'upload_mode': 'api'
4242
4343 }
44 -var mvBaseUploadInterface = function( iObj ){
45 - return this.init( iObj );
 44+var mvBaseUploadInterface = function( options ) {
 45+ return this.init( options );
4646 }
 47+
4748 mvBaseUploadInterface.prototype = {
48 - parent_uploader:false,
49 - formData:{}, // The form data to be submitted
50 - warnings_sessionkey:null,
51 - chunks_supported:true,
52 - form_post_override:false,
53 - http_copy_upload : false,
54 - action_done:false,
55 - // The edit token:
56 - etoken:false,
57 - init: function( iObj ){
58 - if(!iObj)
59 - iObj = {};
60 - // Inherit iObj properties:
61 - $j.extend( this, default_bui_options, iObj);
62 - js_log( "init mvBaseUploadInterface:: " + this.api_url);
 49+ parent_uploader: false,
 50+ formData: {}, // The form data to be submitted
 51+ warnings_sessionkey: null,
 52+ chunks_supported: true,
 53+ form_post_override: false,
 54+ http_copy_upload : null,
 55+ action_done: false,
 56+ editToken: false,
 57+
 58+ // The DOM node for the upload form
 59+ form: false,
 60+
 61+ /**
 62+ * Object initialisation
 63+ */
 64+ init: function( options ) {
 65+ if ( !options )
 66+ options = {};
 67+ $j.extend( this, default_bui_options, options );
 68+ js_log( "init mvBaseUploadInterface:: " + this.api_url );
6369 },
64 - setupForm:function(){
65 - js_log("Base::setupForm::");
 70+
 71+ /**
 72+ * Set up the upload form, register onsubmit handler.
 73+ * May remap it to use the API field names.
 74+ */
 75+ setupForm: function() {
 76+ js_log( "Base::setupForm::" );
6677 var _this = this;
6778 // Set up the local pointer to the edit form:
68 - _this.editForm = _this.getEditForm();
69 - if( _this.editForm ){
70 -
71 - // If in api re-map the upload form to api: (we have to do this BEFORE the users selects a file)
72 - if( _this.upload_mode == 'api'){
73 - _this.doRemapFormToApi();
74 - }
75 -
76 - // Set up the org_onsubmit if not set:
77 - if( typeof( _this.org_onsubmit ) == 'undefined' && _this.editForm.onsubmit )
78 - _this.org_onsubmit = _this.editForm.onsubmit;
79 -
80 -
81 - // Set up the submit action:
82 - $j( _this.editForm ).submit( function(){
83 - js_log('setupForm.onSubmit:');
84 -
85 - // Set the upload mode:
86 - _this.setWgUploadSelect();
87 -
88 - // Run the original onsubmit (if not run yet set flag to avoid excessive chaining )
89 - if( typeof( _this.org_onsubmit ) == 'function' ){
90 - if( ! _this.org_onsubmit() ){
91 - //error in org submit return false;
92 - return false;
93 - }
94 - }
95 - // Check for post action override:
96 - if( _this.form_post_override ){
97 - js_log('form_post_override is true do form proccesing:');
98 - return true;
99 - }
100 - // Get the input form data in flat json:
101 - js_log('update formData::');
102 - var tmpAryData = $j( _this.editForm ).serializeArray();
103 - for(var i=0; i < tmpAryData.length; i++){
104 - if( tmpAryData[i]['name'] )
105 - _this.formData[ tmpAryData[i]['name'] ] = tmpAryData[i]['value'];
106 - }
107 - // Put into a try catch so we are sure to return false:
108 - try{
109 - debugger;
110 - // Get a clean loader:
111 - _this.dispProgressOverlay();
 79+ this.form = this.getForm();
 80+ if ( !this.form ) {
 81+ js_log( "Upload form not found!" );
 82+ return;
 83+ }
11284
113 - // For some unknown reason we have to drop down the #p-search z-index:
114 - $j('#p-search').css('z-index', 1);
 85+ // If we're in API mode, re-map the upload form to API.
 86+ if ( this.upload_mode == 'api' ) {
 87+ this.remapFormToApi();
 88+ }
11589
116 - // Select upload mode:
117 - _this.detectUploadMode();
118 - }catch(e){
119 - js_log('::error in dispProgressOverlay or detectUploadMode');
120 - }
121 -
122 - // Don't submit the form we will do the post in ajax
 90+ // Set up the orig_onsubmit if not set:
 91+ if ( typeof( this.orig_onsubmit ) == 'undefined' && this.form.onsubmit ) {
 92+ this.orig_onsubmit = this.form.onsubmit;
 93+ }
 94+
 95+ // Set up the submit action:
 96+ $j( this.form ).submit( function() {
 97+ _this.onSubmit();
 98+ } );
 99+ },
 100+
 101+ /**
 102+ * onsubmit handler for the upload form
 103+ */
 104+ onSubmit: function() {
 105+ js_log( 'Base::onSubmit:' );
 106+
 107+ // Run the original onsubmit (if not run yet set flag to avoid excessive chaining)
 108+ if ( typeof( this.orig_onsubmit ) == 'function' ) {
 109+ if ( ! this.orig_onsubmit() ) {
 110+ //error in orig submit return false;
123111 return false;
124 - });
125 - }
126 - $j('#testcat').click(function(){
127 - $j( _this.editForm ).submit();
128 - });
129 - },
130 - detectUploadMode:function( callback ){
 112+ }
 113+ }
 114+ // Check for post action override
 115+ if ( this.form_post_override ) {
 116+ js_log( 'form_post_override is true, do ordinary form submit' );
 117+ return true;
 118+ }
 119+
 120+ // Get the input form data into an array
 121+ js_log( 'update formData::' );
 122+ var data = $j( this.form ).serializeArray();
 123+ this.formData = {};
 124+ for ( var i = 0; i < data.length; i++ ) {
 125+ if ( data[i]['name'] )
 126+ this.formData[ data[i]['name'] ] = data[i]['value'];
 127+ }
 128+ // Put into a try catch so we are sure to return false:
 129+ try {
 130+ // Get a clean loader:
 131+ // FIXME: this function does not exist in this class
 132+ this.displayProgressOverlay();
 133+
 134+ // For some unknown reason we have to drop down the #p-search z-index:
 135+ $j( '#p-search' ).css( 'z-index', 1 );
 136+
 137+ var _this = this;
 138+ this.detectUploadMode( function( mode ) {
 139+ _this.doUpload();
 140+ } );
 141+ } catch( e ) {
 142+ js_log( '::error in displayProgressOverlay or doUpload' );
 143+ }
 144+
 145+ // Don't submit the form we will do the post in ajax
 146+ return false;
 147+ }
 148+
 149+ /**
 150+ * Determine the correct upload mode.
 151+ *
 152+ * If this.upload_mode is autodetect, this runs an API call to find out if MW
 153+ * supports uploading. It then sets the upload mode when this call returns.
 154+ *
 155+ * When done detecting, or if detecting is unnecessary, it calls the callback
 156+ * with the upload mode as the first parameter.
 157+ */
 158+ detectUploadMode: function( callback ) {
131159 var _this = this;
132 - js_log('detectUploadMode::' + _this.upload_mode);
133 - // Check the upload mode:
134 - if( _this.upload_mode == 'autodetect' ){
135 - js_log('detectUploadMode::' + _this.upload_mode + ' api:' + _this.api_url);
136 - if( ! _this.api_url )
137 - return js_error( 'Error: can\'t autodetect mode without api url' );
138 - do_api_req( {
139 - 'data': { 'action' : 'paraminfo', 'modules' : 'upload' },
140 - 'url' : _this.api_url
141 - }, function(data){
142 - if( typeof data.paraminfo == 'undefined' || typeof data.paraminfo.modules == 'undefined' )
143 - return js_error( 'Error: bad api results' );
144 - if( typeof data.paraminfo.modules[0].classname == 'undefined'){
145 - js_log( 'Autodetect Upload Mode: \'post\' ');
146 - _this.upload_mode = 'post';
147 - }else{
148 - js_log( 'Autodetect Upload Mode: api ' );
149 - _this.upload_mode = 'api';
150 - //check to see if chunks are supported:
151 - for( var i in data.paraminfo.modules[0].parameters ){
152 - var pname = data.paraminfo.modules[0].parameters[i].name;
153 - if( pname == 'enablechunks' ){
154 - js_log( 'this.chunks_supported = true' );
155 - _this.chunks_supported = true;
156 - break;
 160+ js_log( 'detectUploadMode::' + _this.upload_mode );
 161+ // Check the upload mode
 162+ if ( _this.upload_mode == 'detect_in_progress' ) {
 163+ // Don't send another request, wait for the pending one.
 164+ } else if ( !_this.isCopyUpload() ) {
 165+ callback( 'post' );
 166+ } else if ( _this.upload_mode == 'autodetect' ) {
 167+ js_log( 'detectUploadMode::' + _this.upload_mode + ' api:' + _this.api_url );
 168+ if( !_this.api_url ) {
 169+ js_error( 'Error: can\'t autodetect mode without api url' );
 170+ return;
 171+ }
 172+
 173+ // Don't send multiple requests
 174+ _this.upload_mode = 'detect_in_progress';
 175+
 176+ // FIXME: move this to configuration and avoid this API request
 177+ do_api_req(
 178+ {
 179+ 'data': { 'action' : 'paraminfo', 'modules' : 'upload' },
 180+ 'url' : _this.api_url
 181+ },
 182+ function( data ) {
 183+ if ( typeof data.paraminfo == 'undefined'
 184+ || typeof data.paraminfo.modules == 'undefined' )
 185+ {
 186+ return js_error( 'Error: bad api results' );
 187+ }
 188+ if ( typeof data.paraminfo.modules[0].classname == 'undefined' ) {
 189+ js_log( 'Autodetect Upload Mode: \'post\' ' );
 190+ _this.upload_mode = 'post';
 191+ callback( 'post' );
 192+ } else {
 193+ js_log( 'Autodetect Upload Mode: api ' );
 194+ _this.upload_mode = 'api';
 195+ // Check to see if chunks are supported
 196+ for ( var i in data.paraminfo.modules[0].parameters ) {
 197+ var pname = data.paraminfo.modules[0].parameters[i].name;
 198+ if( pname == 'enablechunks' ) {
 199+ js_log( 'this.chunks_supported = true' );
 200+ _this.chunks_supported = true;
 201+ break;
 202+ }
157203 }
 204+ callback( 'api' );
158205 }
159206 }
160 - js_log("do call: doUploadSwitch");
161 - _this.doUploadSwitch();
162 - });
163 - }else{
164 - _this.doUploadSwitch();
 207+ );
 208+ } else if ( _this.upload_mode == 'api' ) {
 209+ callback( 'api' );
 210+ } else if ( _this.upload_mode == 'post' ) {
 211+ callback( 'post' );
 212+ } else {
 213+ js_error( 'Error: unrecongized upload mode: ' + _this.upload_mode );
165214 }
166215 },
167 - //@@NOTE this could probably be deprecated in favor of automated input
168 - doRemapFormToApi:function(){
169 - var _this = this;
170 - if( !_this.api_url )
 216+
 217+ /**
 218+ * Do an upload, with the mode given by this.upload_mode
 219+ */
 220+ doUpload: function() {
 221+ if ( this.upload_mode == 'api' ) {
 222+ _this.doApiCopyUpload();
 223+ } else if ( this.upload_mode == 'post' ) {
 224+ _this.doPostUpload();
 225+ } else {
 226+ js_error( 'Error: unrecongized upload mode: ' + this.upload_mode );
 227+ }
 228+ }
 229+
 230+ /**
 231+ * Change the upload form so that when submitted, it sends a request to
 232+ * the MW API.
 233+ *
 234+ * This is rather ugly, but solutions are constrained by the fact that
 235+ * file inputs can't be moved around or recreated after the user has
 236+ * selected a file in them, which they may well do before DOM ready.
 237+ */
 238+ remapFormToApi: function() {
 239+ if ( !this.api_url )
171240 return false;
172 -
173 - //add the action api
174 - //$j(_this.editForm).attr('action', _this.api_url);
175 -
176 - //add api url
177 - //add api action:
178 - if( $j(_this.editForm).find("[name='action']").length == 0)
179 - $j(_this.editForm).append('<input type="hidden" name="action" value="upload">');
180241
181 - //add json format
182 - if( $j(_this.editForm).find("[name='format']").length == 0)
183 - $j(_this.editForm).append('<input type="hidden" name="format" value="jsonfm">');
 242+ var form = $j( this.form );
184243
185 - //map a new hidden form
186 - $j(_this.editForm).find("[name='wpUploadFile']").attr('name', 'file');
187 - $j(_this.editForm).find("[name='wpDestFile']").attr('name', 'filename');
188 - $j(_this.editForm).find("[name='wpUploadDescription']").attr('name', 'comment');
189 - $j(_this.editForm).find("[name='wpEditToken']").attr('name', 'token');
190 - $j(_this.editForm).find("[name='wpIgnoreWarning']").attr('name', 'ignorewarnings');
191 - $j(_this.editForm).find("[name='wpWatchthis']").attr('name', 'watch');
192 -
 244+ // Set the form action
 245+ form.attr('action', _this.api_url);
 246+
 247+ // Add API action
 248+ if ( form.find( "[name='action']" ).length == 0 )
 249+ form.append( '<input type="hidden" name="action" value="upload">' );
 250+
 251+ // Add JSON format
 252+ if ( form.find( "[name='format']" ).length == 0 )
 253+ form.append( '<input type="hidden" name="format" value="jsonfm">' );
 254+
 255+ // Map a new hidden form
 256+ form.find( "[name='wpUploadFile']" ).attr( 'name', 'file' );
 257+ form.find( "[name='wpDestFile']" ).attr( 'name', 'filename' );
 258+ form.find( "[name='wpUploadDescription']" ).attr( 'name', 'comment' );
 259+ form.find( "[name='wpEditToken']" ).attr( 'name', 'token' );
 260+ form.find( "[name='wpIgnoreWarning']" ).attr( 'name', 'ignorewarnings' );
 261+ form.find( "[name='wpWatchthis']" ).attr( 'name', 'watch' );
193262 },
194 - setWgUploadSelect: function(){
195 - if( $j('#wpSourceTypeFile').length == 0 || $j('#wpSourceTypeFile').get(0).checked ){
196 - this.http_copy_upload = false;
197 - }else if( $j('#wpSourceTypeUrl').get(0).checked ){
198 - this.http_copy_upload = true;
 263+
 264+ /**
 265+ * Returns true if the current form has copy upload selected, false otherwise.
 266+ */
 267+ isCopyUpload: function() {
 268+ if ( this.http_copy_upload == null ) {
 269+ if ( $j( '#wpSourceTypeFile' ).length == 0
 270+ || $j( '#wpSourceTypeFile' ).get( 0 ).checked )
 271+ {
 272+ this.http_copy_upload = false;
 273+ } else if ( $j('#wpSourceTypeURL').get( 0 ).checked ) {
 274+ this.http_copy_upload = true;
 275+ }
199276 }
 277+ return this.http_copy_upload;
200278 },
201 - doUploadSwitch:function(){
 279+
 280+ /**
 281+ * Do an upload by submitting the form
 282+ */
 283+ doPostUpload: function() {
202284 var _this = this;
203 - js_log('mvUPload:doUploadSwitch():' + _this.upload_mode);
204 - //issue a normal post request
205 - if( _this.upload_mode == 'api' && ! _this.http_copy_upload ){
206 - //get the token from the page:
207 - _this.etoken = $j("#wpEditToken").val();
208 -
209 - //@@TODO check for sendAsBinnary to support firefox/html5 progress on upload
 285+ var form = $j( _this.form );
 286+ js_log( 'mvBaseUploadInterface.doPostUpload' );
210287
211 - //set the form target to iframe target:
212 - _this.iframeId = 'f_' + ($j('iframe').length + 1);
213 -
214 - //add the iframe
215 - $j("body").append('<iframe src="javascript:false;" id="' + _this.iframeId + '" ' +
216 - 'name="' + _this.iframeId + '" style="display:none;" ></iframe>');
217 - $j(_this.editForm).attr('target', _this.iframeId);
 288+ // Issue a normal post request
 289+ // Get the token from the page
 290+ _this.editToken = $j( "#wpEditToken" ).val();
218291
219 - //set up the done binding
220 - $j('#' + _this.iframeId).load(function(){
221 - _this.proccessIframeResult( $j(this).get(0) );
222 - });
223 - //set the action to the api url:
224 - $j(_this.editForm).attr('action', _this.api_url );
225 -
226 - js_log('do iframe form submit to: ' + $j(_this.editForm).attr('target') );
227 - js_log(' destName:' + $j(_this.editForm).find("[name='filename']").val() );
228 -
229 -
230 - //do post override
231 - _this.form_post_override = true;
232 - //reset the done with action flag:
233 - _this.action_done = false;
234 -
235 - /*js_log('run editForm submit()');
236 - var tmpAryData = $j(_this.editForm).serializeArray();
237 - for(var i=0; i < tmpAryData.length; i++){
238 - if( tmpAryData[i]['name'] )
239 - js_log('name: ' + tmpAryData[i]['name'] + ' = ' + tmpAryData[i]['value']);
240 - }*/
241 - $j( _this.editForm ).submit();
 292+ //@@TODO check for sendAsBinary to support Firefox/HTML5 progress on upload
242293
243 - return false;
244 - }else if( _this.upload_mode == 'api' ){
245 - js_log('doHttpUpload (no form submit) ');
246 - //if the api is supported.. && source type is http do upload with http status updates
247 - var httpUpConf ={
248 - 'url' : $j('#wpUploadFileURL').val(),
249 - 'filename' : $j('#wpDestFile').val(),
250 - 'comment' : $j('#wpUploadDescription').val(),
251 - 'watch' : ($j('#wpWatchthis').is(':checked'))?'true':'false',
252 - 'ignorewarnings': ($j('#wpIgnoreWarning').is(':checked'))?'true':'false'
253 - }
254 - //check for editToken
255 - _this.etoken = $j("#wpEditToken").val();
256 - _this.doHttpUpload( httpUpConf );
257 - }else{
258 - js_error( 'Error: unrecongized upload mode: ' + _this.upload_mode );
 294+
 295+ // Add the iframe
 296+ _this.iframeId = 'f_' + ( $j( 'iframe' ).length + 1 );
 297+ $j( "body" ).append( '<iframe src="javascript:false;" id="' + _this.iframeId + '" ' +
 298+ 'name="' + _this.iframeId + '" style="display:none;" ></iframe>' );
 299+
 300+ // Set the form target to the iframe
 301+ form.attr( 'target', _this.iframeId );
 302+
 303+ // Set up the completion callback
 304+ $j( '#' + _this.iframeId ).load( function() {
 305+ _this.processIframeResult( $j( this ).get( 0 ) );
 306+ });
 307+
 308+ // Set the action to the API URL:
 309+ form.attr( 'action', _this.api_url );
 310+
 311+ js_log( 'Do iframe form submit to: ' + form.attr( 'target' ) );
 312+ js_log( ' destName:' + form.find( "[name='filename']" ).val() );
 313+
 314+ // Do post override
 315+ _this.form_post_override = true;
 316+ // Reset the done with action flag
 317+ _this.action_done = false;
 318+
 319+ form.submit();
 320+ },
 321+
 322+ /**
 323+ * Do an upload by submitting an API request
 324+ */
 325+ doApiCopyUpload: function() {
 326+ js_log( 'mvBaseUploadInterface.doApiCopyUpload' );
 327+ js_log( 'doHttpUpload (no form submit) ' );
 328+ var httpUpConf = {
 329+ 'url' : $j( '#wpUploadFileURL' ).val(),
 330+ 'filename' : $j( '#wpDestFile' ).val(),
 331+ 'comment' : $j( '#wpUploadDescription' ).val(),
 332+ 'watch' : ( $j( '#wpWatchthis' ).is( ':checked' ) ) ? 'true' : 'false',
 333+ 'ignorewarnings': ($j('#wpIgnoreWarning' ).is( ':checked' ) ) ? 'true' : 'false'
259334 }
260 - return false;
 335+ //check for editToken
 336+ this.editToken = $j( "#wpEditToken" ).val();
 337+ this.doHttpUpload( httpUpConf );
261338 },
262 - proccessIframeResult:function(iframe){
 339+
 340+ /**
 341+ * Process the result of the form submission, returned to an iframe.
 342+ * This is the iframe's onload event.
 343+ */
 344+ processIframeResult: function( iframe ) {
263345 var _this = this;
264346 var doc = iframe.contentDocument ? iframe.contentDocument : frames[iframe.id].document;
265 - // fixing Opera 9.26
266 - if (doc.readyState && doc.readyState != 'complete'){
 347+ // Fix for Opera 9.26
 348+ if ( doc.readyState && doc.readyState != 'complete' ) {
267349 return;
268350 }
269 - // fixing Opera 9.64
270 - if (doc.body && doc.body.innerHTML == "false"){
 351+ // Fix for Opera 9.64
 352+ if ( doc.body && doc.body.innerHTML == "false" ) {
271353 return;
272354 }
273355 var response;
274 - if (doc.XMLDocument){
275 - // response is a xml document IE property
 356+ if ( doc.XMLDocument ) {
 357+ // The response is a document property in IE
276358 response = doc.XMLDocument;
277 - } else if (doc.body){
278 - // get the json str:
279 - json_str = $j(doc.body).find('pre').html();
280 - js_log('iframe:json::' + json_str + "\nbody:" + $j(doc.body).html() );
281 - //htmlentties
282 - if (json_str) {
283 - response = window["eval"]("(" +json_str + ")");
 359+ } else if ( doc.body ) {
 360+ // Get the json string
 361+ json = $j( doc.body ).find( 'pre' ).text();
 362+ js_log( 'iframe:json::' + json_str + "\nbody:" + $j( doc.body ).html() );
 363+ if ( json ) {
 364+ response = window["eval"]( "(" + json + ")" );
284365 } else {
285366 response = {};
286367 }
287368 } else {
288369 // response is a xml document
289 - var response = doc;
 370+ response = doc;
290371 }
291 - //do proccess the api result
292 - _this.processApiResult( response );
 372+ // Process the API result
 373+ _this.processApiResult( response );
293374 },
294 - doHttpUpload:function( opt ){
 375+
 376+ /**
 377+ * Do a generic action=upload API request and monitor its progress
 378+ */
 379+ doHttpUpload: function( params ) {
295380 var _this = this;
296 - //make sure to display the progress win:
297 - _this.dispProgressOverlay();
298 -
299 - //set the http box to loading (in case we don't get an update for some time)
300 - $j('#dlbox-centered').html( '<h5>' + _this.getProgressTitle() + '</h5>' +
301 - mv_get_loading_img( 'left:40%;top:20%')
302 - );
303 - //setup request:
304 - var req = {
305 - 'action' : 'upload',
306 - 'asyncdownload' : true //do async download
 381+ // Display the progress overlay (again)
 382+ _this.displayProgressOverlay();
 383+
 384+ // Set the HTTP box to "loading", in case we don't get an update for some time
 385+ $j( '#dlbox-centered' ).html( '<h5>' + _this.getProgressTitle() + '</h5>' +
 386+ mv_get_loading_img( 'left:40%;top:20%' )
 387+ );
 388+
 389+ // Set up the request
 390+ var request = {
 391+ 'action' : 'upload',
 392+ 'asyncdownload' : true // Do async download
307393 };
308 - //set config from options:
309 - $j.extend(req, opt);
310394
311 - //else try and get a token:
312 - if(!_this.etoken && _this.api_url){
313 - js_log('Error:doHttpUpload: missing token');
314 - }else{
315 - req['token'] =_this.etoken;
 395+ // Add any parameters specified by the caller
 396+ for ( key in params ) {
 397+ if ( !request[key] ) {
 398+ request[key] = params[key];
 399+ }
316400 }
317 - //reset the done with action flag:
 401+
 402+ // Add the edit token (if available)
 403+ if( !_this.editToken && _this.api_url ) {
 404+ js_log( 'Error:doHttpUpload: missing token' );
 405+ } else {
 406+ request['token'] =_this.editToken;
 407+ }
 408+
 409+ // Reset the done with action flag
318410 _this.action_done = false;
319 - //do the api req
 411+
 412+ //do the api request
320413 do_api_req({
321 - 'data': req,
 414+ 'data': request,
322415 'url' : _this.api_url
323 - }, function( data ){
 416+ }, function( data ) {
324417 _this.processApiResult( data );
325418 });
326419 },
327 - doAjaxUploadStatus:function() {
328 - var _this = this;
329 -
 420+
 421+ /**
 422+ * Start periodic checks of the upload status using XHR
 423+ */
 424+ doAjaxUploadStatus: function() {
 425+ var _this = this;
 426+
330427 //set up the progress display for status updates:
331 - _this.dispProgressOverlay();
332 - var req = {
333 - 'action' : 'upload',
 428+ this.displayProgressOverlay();
 429+ this.upload_status_request = {
 430+ 'action' : 'upload',
334431 'httpstatus' : 'true',
335432 'sessionkey' : _this.upload_session_key
336433 };
337 - //add token if present:
338 - if(this.etoken)
339 - req['token'] = this.etoken;
 434+ // Add token if present
 435+ if ( this.editToken )
 436+ this.upload_status_request['token'] = this.editToken;
340437
341 - var uploadStatus = function(){
342 - //do the api request:
343 - do_api_req({
344 - 'data':req,
345 - 'url' : _this.api_url
346 - }, function( data ){
347 - //@@check if we are done
348 - if( data.upload['apiUploadResult'] ){
349 - //update status to 100%
350 - _this.updateProgress( 1 );
351 - //see if we need JSON
352 - mvJsLoader.doLoad( [
353 - 'JSON'
354 - ],function(){
355 - var apiResult = {};
356 - try{
357 - apiResult = JSON.parse ( data.upload['apiUploadResult'] ) ;
358 - }catch (e){
359 - //could not parse api result
360 - js_log('errro: could not parse apiUploadResult ')
361 - }
362 - _this.processApiResult( apiResult );
363 - });
364 - return ;
365 - }
 438+ // Trigger an initial request (subsequent ones will be done by a timer)
 439+ this.onAjaxUploadStatusTimer();
 440+ }
366441
367 - //@@ else update status:
368 - if( data.upload['content_length'] && data.upload['loaded'] ){
369 - //we have content length we can show percentage done:
370 - var perc = data.upload['loaded'] / data.upload['content_length'];
371 - //update the status:
372 - _this.updateProgress( perc );
373 - //special case update the file progress where we have data size:
374 - $j('#up-status-container').html(
375 - gM('mwe-upload-stats-fileprogres', [
376 - $mw.lang.formatSize( data.upload['loaded'] ),
377 - $mw.lang.formatSize( data.upload['content_length'] )
378 - ]
379 - )
380 - );
381 - }else if( data.upload['loaded'] ){
382 - _this.updateProgress( 1 );
383 - js_log('just have loaded (no cotent length: ' + data.upload['loaded']);
384 - //for lack of content-length requests:
385 - $j('#up-status-container').html(
386 - gM('mwe-upload-stats-fileprogres', [
387 - $mw.lang.formatSize( data.upload['loaded'] ),
388 - gM('mwe-upload-unknown-size')
389 - ]
390 - )
391 - );
 442+ /**
 443+ * This is called when the timer which separates XHR requests elapses.
 444+ * It starts a new request.
 445+ */
 446+ onAjaxUploadStatusTimer: function() {
 447+ var _this = this;
 448+ //do the api request:
 449+ do_api_req(
 450+ {
 451+ 'data': this.upload_status_request,
 452+ 'url' : this.api_url
 453+ },
 454+ function ( data ) {
 455+ _this.onAjaxUploadStatusResponse( data );
 456+ }
 457+ );
 458+ },
 459+
 460+ /**
 461+ * Called when a response to an upload status query is available.
 462+ * Starts the timer for the next upload status check.
 463+ */
 464+ onAjaxUploadStatusResponse: function( data ) {
 465+ var _this = this;
 466+ //@@check if we are done
 467+ if ( data.upload['apiUploadResult'] ) {
 468+ //update status to 100%
 469+ _this.updateProgress( 1 );
 470+ //see if we need JSON
 471+ mvJsLoader.doLoad( [
 472+ 'JSON'
 473+ ], function() {
 474+ var apiResult = {};
 475+ try {
 476+ apiResult = JSON.parse( data.upload['apiUploadResult'] ) ;
 477+ } catch ( e ) {
 478+ //could not parse api result
 479+ js_log( 'errro: could not parse apiUploadResult' )
392480 }
393 - if( _this.api_url == 'proxy'){
394 - //do the updates a bit more sporadically every 4.2 seconds
395 - setTimeout(uploadStatus, 4200);
396 - }else{
397 - //(we got a result) set it to 100ms + your server update interval (in our case 2s)
398 - setTimeout(uploadStatus, 2100);
399 - }
 481+ _this.processApiResult( apiResult );
400482 });
 483+ return ;
401484 }
402 - uploadStatus();
 485+
 486+ //@@ else update status:
 487+ if ( data.upload['content_length'] && data.upload['loaded'] ) {
 488+ //we have content length we can show percentage done:
 489+ var fraction = data.upload['loaded'] / data.upload['content_length'];
 490+ //update the status:
 491+ _this.updateProgress( fraction );
 492+ //special case update the file progress where we have data size:
 493+ $j( '#up-status-container' ).html(
 494+ gM( 'mwe-upload-stats-fileprogress',
 495+ [
 496+ $mw.lang.formatSize( data.upload['loaded'] ),
 497+ $mw.lang.formatSize( data.upload['content_length'] )
 498+ ]
 499+ )
 500+ );
 501+ } else if( data.upload['loaded'] ) {
 502+ _this.updateProgress( 1 );
 503+ js_log( 'just have loaded (no cotent length: ' + data.upload['loaded'] );
 504+ //for lack of content-length requests:
 505+ $j( '#up-status-container' ).html(
 506+ gM( 'mwe-upload-stats-fileprogress',
 507+ [
 508+ $mw.lang.formatSize( data.upload['loaded'] ),
 509+ gM( 'mwe-upload-unknown-size' )
 510+ ]
 511+ )
 512+ );
 513+ }
 514+ if ( _this.api_url == 'proxy' ) {
 515+ // Do the updates a bit less often: every 4.2 seconds
 516+ var timeout = 4200;
 517+ } else {
 518+ // We got a result: set timeout to 100ms + your server update
 519+ // interval (in our case 2s)
 520+ var timeout = 2100;
 521+ }
 522+ setTimeout(
 523+ function() {
 524+ _this.onAjaxUploadStatusTimer();
 525+ },
 526+ timeout );
403527 },
404 - apiUpdateErrorCheck:function( apiRes ){
 528+
 529+ /**
 530+ * Returns true if an action=upload API result was successful, false otherwise
 531+ */
 532+ isApiSuccess: function( apiRes ) {
 533+ if ( apiRes.error || ( apiRes.upload && apiRes.upload.result == "Failure" ) ) {
 534+ return false;
 535+ }
 536+ if ( apiRes.upload && apiRes.upload.error ) {
 537+ return false;
 538+ }
 539+ if ( apiRes.upload && apiRes.upload.warnings ) {
 540+ return false;
 541+ }
 542+ return true;
 543+ },
 544+
 545+ /**
 546+ * Given the result of an action=upload API request, display the error message
 547+ * to the user.
 548+ */
 549+ showApiError: function( apiRes ) {
405550 var _this = this;
406 - if( apiRes.error || ( apiRes.upload && apiRes.upload.result == "Failure" ) ){
407 - //gennerate the error button:
408 - var bObj = {};
409 - bObj[ gM('mwe-return-to-form') ] = function(){
410 - _this.form_post_override = false;
411 - $j(this).dialog('close');
412 - };
 551+ if ( apiRes.error || ( apiRes.upload && apiRes.upload.result == "Failure" ) ) {
 552+ // Generate the error button
 553+ var buttons = {};
 554+ buttons[ gM( 'mwe-return-to-form' ) ] = function() {
 555+ _this.form_post_override = false;
 556+ $j( this ).dialog( 'close' );
 557+ };
413558
414559 //@@TODO should be refactored to more specialUpload page type error handling
415560
416 - //check a few places for the error code:
417 - var error_code=0;
418 - var errorReplaceArg='';
419 - if( apiRes.error && apiRes.error.code ){
 561+ // Check a few places for the error code
 562+ var error_code = 0;
 563+ var errorReplaceArg = '';
 564+ if ( apiRes.error && apiRes.error.code ) {
420565 error_code = apiRes.error.code;
421 - }else if( apiRes.upload.code ){
422 - if(typeof apiRes.upload.code == 'object'){
423 - if( apiRes.upload.code[0] ){
 566+ } else if ( apiRes.upload.code ) {
 567+ if ( typeof apiRes.upload.code == 'object' ) {
 568+ if ( apiRes.upload.code[0] ) {
424569 error_code = apiRes.upload.code[0];
425570 }
426 - if( apiRes.upload.code['status'] ){
 571+ if ( apiRes.upload.code['status'] ) {
427572 error_code = apiRes.upload.code['status'];
428 - if(apiRes.upload.code['filtered'])
429 - errorReplaceArg =apiRes.upload.code['filtered'];
 573+ if ( apiRes.upload.code['filtered'] )
 574+ errorReplaceArg = apiRes.upload.code['filtered'];
430575 }
431 - }else{
 576+ } else {
432577 apiRes.upload.code;
433578 }
434579 }
435580
436581 var error_msg = '';
437 - if(typeof apiRes.error == 'string')
 582+ if ( typeof apiRes.error == 'string' )
438583 error_msg = apiRes.error;
439 - //error space is too large so we don't front load it
440 - //this upload error space replicates code in: SpecialUpload.php::processUpload()
441 - //would be nice if we refactored that to the upload api.(problem is some need special actions)
 584+
 585+ // There are many possible error messages here, so we don't load all
 586+ // message text in advance, instead we use gMsgLoadRemote() for some.
 587+ //
 588+ // This code is similar to the error handling code formerly in
 589+ // SpecialUpload::processUpload()
442590 var error_msg_key = {
443591 '2' : 'largefileserver',
444592 '3' : 'emptyfile',
@@ -445,7 +593,7 @@
446594 '5' : 'illegalfilename'
447595 };
448596
449 - //@@todo: need to write conditionals that mirror SpecialUpload for handling these error types:
 597+ //@@todo: handle these error types
450598 var error_onlykey = {
451599 '1': 'BEFORE_PROCESSING',
452600 '6': 'PROTECTED_PAGE',
@@ -456,332 +604,437 @@
457605 '11': 'UPLOAD_VERIFICATION_ERROR',
458606 '12': 'UPLOAD_WARNING',
459607 '13': 'INTERNAL_ERROR',
460 - '14': 'MIN_LENGHT_PARTNAME'
 608+ '14': 'MIN_LENGTH_PARTNAME'
461609 }
462610
463 - //do a remote call to get the error msg:
464 - if(!error_code || error_code == 'unknown-error'){
465 - if(typeof JSON != 'undefined'){
466 - js_log('Error: apiRes: ' + JSON.stringify( apiRes) );
 611+ if ( !error_code || error_code == 'unknown-error' ) {
 612+ if ( typeof JSON != 'undefined' ) {
 613+ js_log( 'Error: apiRes: ' + JSON.stringify( apiRes ) );
467614 }
468 - if( apiRes.upload.error == 'internal-error'){
 615+ if ( apiRes.upload.error == 'internal-error' ) {
 616+ // Do a remote message load
469617 errorKey = apiRes.upload.details[0];
470 - gMsgLoadRemote(errorKey, function(){
471 - _this.updateProgressWin( gM( 'mwe-uploaderror' ), gM( errorKey ), bObj );
 618+ gMsgLoadRemote( errorKey, function() {
 619+ _this.updateProgressWin( gM( 'mwe-uploaderror' ), gM( errorKey ), buttons );
472620
473621 });
474622 return false;
475623 }
476624
477 - _this.updateProgressWin( gM('mwe-uploaderror'), gM('mwe-unknown-error') + '<br>' + error_msg, bObj );
 625+ _this.updateProgressWin(
 626+ gM('mwe-uploaderror'),
 627+ gM('mwe-unknown-error') + '<br>' + error_msg,
 628+ buttons );
478629 return false;
479 - }else{
480 - if(apiRes.error && apiRes.error.info ){
481 - _this.updateProgressWin( gM('mwe-uploaderror'), apiRes.error.info ,bObj);
482 - return false;
483 - }else{
484 - if(typeof error_code == 'number' && typeof error_msg_key[error_code] == 'undefined' ){
485 - if(apiRes.upload.code.finalExt){
486 - _this.updateProgressWin( gM('mwe-uploaderror'), gM('mwe-wgfogg_warning_bad_extension', apiRes.upload.code.finalExt) , bObj);
487 - }else{
488 - _this.updateProgressWin( gM('mwe-uploaderror'), gM('mwe-unknown-error') + ' : ' + error_code, bObj);
489 - }
490 - }else{
491 - js_log('get key: ' + error_msg_key[ error_code ])
492 - gMsgLoadRemote( error_msg_key[ error_code ], function(){
493 - _this.updateProgressWin( gM('mwe-uploaderror'), gM( error_msg_key[ error_code ], errorReplaceArg ), bObj);
494 - });
495 - js_log("api.error");
496 - }
497 - return false;
 630+ }
 631+
 632+ if ( apiRes.error && apiRes.error.info ) {
 633+ _this.updateProgressWin( gM( 'mwe-uploaderror' ), apiRes.error.info, buttons );
 634+ return false;
 635+ }
 636+
 637+ if ( typeof error_code == 'number'
 638+ && typeof error_msg_key[error_code] == 'undefined' )
 639+ {
 640+ if ( apiRes.upload.code.finalExt ) {
 641+ _this.updateProgressWin(
 642+ gM( 'mwe-uploaderror' ),
 643+ gM( 'mwe-wgfogg_warning_bad_extension', apiRes.upload.code.finalExt ),
 644+ buttons );
 645+ } else {
 646+ _this.updateProgressWin(
 647+ gM( 'mwe-uploaderror' ),
 648+ gM( 'mwe-unknown-error' ) + ' : ' + error_code,
 649+ buttons );
498650 }
 651+ return false;
499652 }
 653+
 654+ js_log( 'get key: ' + error_msg_key[ error_code ] )
 655+ gMsgLoadRemote( error_msg_key[ error_code ], function() {
 656+ _this.updateProgressWin(
 657+ gM( 'mwe-uploaderror' ),
 658+ gM( error_msg_key[ error_code ], errorReplaceArg ),
 659+ buttons );
 660+ });
 661+ js_log( "api.error" );
 662+ return false;
500663 }
501 - //check for upload.error type erros.
502 - if( apiRes.upload && apiRes.upload.error){
503 - js_log(' apiRes.upload.error: ' + apiRes.upload.error );
504 - _this.updateProgressWin( gM('mwe-uploaderror'), gM('mwe-unknown-error') + '<br>', bObj);
 664+
 665+ // Check upload.error
 666+ if ( apiRes.upload && apiRes.upload.error ) {
 667+ js_log( ' apiRes.upload.error: ' + apiRes.upload.error );
 668+ _this.updateProgressWin(
 669+ gM( 'mwe-uploaderror' ),
 670+ gM( 'mwe-unknown-error' ) + '<br>',
 671+ buttons );
505672 return false;
506673 }
507 - //check for known warnings:
508 - if(apiRes.upload && apiRes.upload.warnings ){
509 - //debugger;
 674+
 675+ // Check for warnings:
 676+ if ( apiRes.upload && apiRes.upload.warnings ) {
510677 var wmsg = '<ul>';
511 - for(var wtype in apiRes.upload.warnings){
 678+ for ( var wtype in apiRes.upload.warnings ) {
512679 var winfo = apiRes.upload.warnings[wtype]
513 - wmsg+='<li>';
514 - switch(wtype){
 680+ wmsg += '<li>';
 681+ switch ( wtype ) {
515682 case 'duplicate':
516683 case 'exists':
517 - if(winfo[1] && winfo[1].title && winfo[1].title.mTextform){
518 - wmsg += gM('mwe-file-exists-duplicate') +' '+
519 - '<b>' + winfo[1].title.mTextform + '</b>';
520 - }else{
 684+ if ( winfo[1] && winfo[1].title && winfo[1].title.mTextform ) {
 685+ wmsg += gM( 'mwe-file-exists-duplicate' ) + ' ' +
 686+ '<b>' + winfo[1].title.mTextform + '</b>';
 687+ } else {
521688 //misc error (weird that winfo[1] not present
522 - wmsg += gM('mwe-upload-misc-error') + ' ' + wtype;
 689+ wmsg += gM( 'mwe-upload-misc-error' ) + ' ' + wtype;
523690 }
524 - break;
 691+ break;
525692 case 'file-thumbnail-no':
526 - wmsg += gM('mwe-file-thumbnail-no', winfo);
527 - break;
 693+ wmsg += gM( 'mwe-file-thumbnail-no', winfo );
 694+ break;
528695 default:
529 - wmsg += gM('mwe-upload-misc-error') + ' ' + wtype;
530 - break;
 696+ wmsg += gM( 'mwe-upload-misc-error' ) + ' ' + wtype;
 697+ break;
531698 }
532 - wmsg+='</li>';
 699+ wmsg += '</li>';
533700 }
534 - wmsg+='</ul>';
535 - if( apiRes.upload.sessionkey)
536 - _this.warnings_sessionkey = apiRes.upload.sessionkey;
 701+ wmsg += '</ul>';
 702+ if ( apiRes.upload.sessionkey )
 703+ _this.warnings_sessionkey = apiRes.upload.sessionkey;
537704
538 - var bObj = {};
539 - bObj[ gM('mwe-ignorewarning') ] = function() {
540 - //check if we have a stashed key:
541 - if( _this.warnings_sessionkey ){
542 - //set to "loading"
 705+ // Create the "ignore warning" button
 706+ var buttons = {};
 707+ buttons[ gM( 'mwe-ignorewarning' ) ] = function() {
 708+ //check if we have a stashed key:
 709+ if ( _this.warnings_sessionkey ) {
 710+ //set to "loading"
543711 $j( '#upProgressDialog' ).html( mv_get_loading_img() );
544712 //setup loading:
545713 var req = {
546 - 'action' : 'upload',
 714+ 'action': 'upload',
547715 'sessionkey': _this.warnings_sessionkey,
548 - 'ignorewarnings':1,
549 - 'filename': $j('#wpDestFile').val(),
550 - 'token' : _this.etoken
551 - };
 716+ 'ignorewarnings': 1,
 717+ 'filename': $j( '#wpDestFile' ).val(),
 718+ 'token' : _this.editToken
 719+ };
552720 //run the upload from stash request
553 - do_api_req({
554 - 'data': req,
555 - 'url' : _this.api_url
556 - }, function( data ){
557 - _this.processApiResult( data );
558 - });
559 - }else{
560 - js_log('No session key re-sending upload')
 721+ do_api_req(
 722+ {
 723+ 'data': req,
 724+ 'url' : _this.api_url
 725+ },
 726+ function( data ) {
 727+ _this.processApiResult( data );
 728+ }
 729+ );
 730+ } else {
 731+ js_log( 'No session key re-sending upload' )
561732 //do a stashed upload
562 - $j('#wpIgnoreWarning').attr('checked', true);
 733+ $j( '#wpIgnoreWarning' ).attr( 'checked', true );
563734 $j( _this.editForm ).submit();
564735 }
565736 };
566 - bObj[ gM('mwe-return-to-form') ] = function(){
567 - $j(this).dialog('close');
 737+ // Create the "return to form" button
 738+ bObj[ gM( 'mwe-return-to-form' ) ] = function() {
 739+ $j( this ).dialog( 'close' );
568740 _this.form_post_override = false;
569741 }
570 - _this.updateProgressWin( gM('mwe-uploadwarning'), '<h3>' + gM('mwe-uploadwarning') + '</h3>' +wmsg + '<p>',bObj);
 742+ // Show warning
 743+ _this.updateProgressWin(
 744+ gM( 'mwe-uploadwarning' ),
 745+ '<h3>' + gM( 'mwe-uploadwarning' ) + '</h3>' + wmsg + '<p>',
 746+ bObj );
571747 return false;
572748 }
573 - //should be "OK"
 749+ // No error!
574750 return true;
575751 },
576 - processApiResult: function( apiRes ){
 752+
 753+ /**
 754+ * Process the result of an action=upload API request. Display the result
 755+ * to the user.
 756+ */
 757+ processApiResult: function( apiRes ) {
577758 var _this = this;
578 - js_log('processApiResult::');
579 - //check for upload api error:
580 - // {"upload":{"result":"Failure","error":"unknown-error","code":{"status":5,"filtered":"NGC2207%2BIC2163.jpg"}}}
581 - if( _this.apiUpdateErrorCheck(apiRes) === false){
582 - //error returned false (updated and
 759+ js_log( 'processApiResult::' );
 760+ if ( !_this.isApiSuccess( apiRes ) ) {
 761+ // Error detected, show it to the user
 762+ _this.showApiError( apiRes );
583763 return false;
584 - }else{
585 - //check for upload_session key for async upload:
586 - if( apiRes.upload && apiRes.upload.upload_session_key ){
587 - //set the session key
588 - _this.upload_session_key = apiRes.upload.upload_session_key;
 764+ }
 765+ if ( apiRes.upload && apiRes.upload.upload_session_key ) {
 766+ // Async upload, do AJAX status polling
 767+ _this.upload_session_key = apiRes.upload.upload_session_key;
 768+ _this.doAjaxUploadStatus();
 769+ js_log( "set upload_session_key: " + _this.upload_session_key );
 770+ return;
 771+ }
589772
590 - //do ajax upload status:
591 - _this.doAjaxUploadStatus();
592 - js_log("set upload_session_key: " + _this.upload_session_key);
593 - return ;
 773+ if ( apiRes.upload.imageinfo && apiRes.upload.imageinfo.descriptionurl ) {
 774+ var url = apiRes.upload.imageinfo.descriptionurl;
 775+
 776+ // Upload complete.
 777+ // Call the completion callback if available.
 778+ if ( _this.done_upload_cb && typeof _this.done_upload_cb == 'function' ) {
 779+ js_log( "call done_upload_cb" );
 780+ // This overrides our normal completion handling so we close the
 781+ // dialog immediately.
 782+ $j( '#upProgressDialog' ).dialog( 'close' );
 783+ _this.done_upload_cb( apiRes.upload );
 784+ return false;
594785 }
595786
596 - if( apiRes.upload.imageinfo && apiRes.upload.imageinfo.descriptionurl ){
597 - var url = apiRes.upload.imageinfo.descriptionurl;
598 - //check done action:
599 - if( _this.done_upload_cb && typeof _this.done_upload_cb == 'function'){
600 - js_log("call done_upload_cb");
601 - //close up shop:
602 - $j('#upProgressDialog').dialog('close');
603 - //call the callback:
604 - _this.done_upload_cb( apiRes.upload );
605 - return false;
606 - }else{
607 - var bObj = {};
608 - bObj[ gM('mwe-return-to-form')] = function(){
609 - $j(this).dialog('close');
610 - _this.form_post_override = false;
611 - }
612 - bObj[ gM('mwe-go-to-resource') ] = function(){
613 - window.location = url;
614 - };
615 - _this.action_done = true;
616 - _this.updateProgressWin( gM('mwe-successfulupload'), gM( 'mwe-upload_done', url), bObj);
617 - js_log('apiRes.upload.imageinfo::'+url);
618 - return true;
619 - }
 787+ var bObj = {};
 788+ // "Return" button
 789+ bObj[ gM( 'mwe-return-to-form' ) ] = function() {
 790+ $j( this ).dialog( 'close' );
 791+ _this.form_post_override = false;
620792 }
 793+ // "Go to resource" button
 794+ bObj[ gM('mwe-go-to-resource') ] = function() {
 795+ window.location = url;
 796+ };
 797+ _this.action_done = true;
 798+ _this.updateProgressWin(
 799+ gM( 'mwe-successfulupload' ),
 800+ gM( 'mwe-upload_done', url),
 801+ bObj );
 802+ js_log( 'apiRes.upload.imageinfo::' + url );
 803+ return true;
621804 }
622805 },
623 - updateProgressWin:function(title_txt, msg, buttons){
 806+
 807+ /**
 808+ * Update the progress window to display a given message, with a given
 809+ * list of buttons below it.
 810+ * @param title_txt Plain text
 811+ * @param msg HTML
 812+ * @param buttons See http://docs.jquery.com/UI/Dialog#option-buttons
 813+ */
 814+ updateProgressWin: function( title_txt, msg, buttons ) {
624815 var _this = this;
625 - if(!title_txt)
626 - title_txt = _this.getProgressTitle();
627 - if(!msg)
628 - msg = mv_get_loading_img( 'left:40%;top:40px;');
629 - $j( '#upProgressDialog' ).dialog('option', 'title', title_txt );
630 - $j( '#upProgressDialog' ).html( msg );
631 - if(buttons){
632 - $j('#upProgressDialog').dialog('option','buttons', buttons);
633 - }else{
634 - //@@todo should fix jquery ui to not use object keys as user msg's
635 - var bObj = {};
636 - bObj[ gM('mwe-ok') ] = function(){
637 - $j(this).dialog('close');
638 - };
639 - $j('#upProgressDialog').dialog('option','buttons', bObj);
640 - }
 816+
 817+ if ( !title_txt )
 818+ title_txt = _this.getProgressTitle();
 819+
 820+ if ( !msg )
 821+ msg = mv_get_loading_img( 'left:40%;top:40px;' );
 822+
 823+ if ( !buttons ) {
 824+ // If no buttons are specified, add a close button
 825+ buttons = {};
 826+ buttons[ gM( 'mwe-ok' ) ] = function() {
 827+ $j( this ).dialog( 'close' );
 828+ };
 829+ }
 830+
 831+ $j( '#upProgressDialog' ).dialog( 'option', 'title', title_txt );
 832+ $j( '#upProgressDialog' ).html( msg );
 833+ $j( '#upProgressDialog' ).dialog( 'option', 'buttons', buttons );
641834 },
642 - getProgressTitle:function(){
643 - return gM('mwe-upload-in-progress');
 835+
 836+ /**
 837+ * Get the default title of the progress window
 838+ */
 839+ getProgressTitle: function() {
 840+ return gM( 'mwe-upload-in-progress' );
644841 },
645 - getEditForm:function(){
646 - if( this.target_edit_from && $j( this.target_edit_from ).length != 0){
647 - return $j( this.target_edit_from ).get(0);
 842+
 843+ /**
 844+ * Get the DOMNode of the form element we are rewriting.
 845+ * Returns false if it can't be found.
 846+ */
 847+ getForm: function() {
 848+ if ( this.form_selector && $j( this.form_selector ).length != 0 ) {
 849+ return $j( this.form_selector ).get( 0 );
 850+ } else {
 851+ js_log( "mvBaseUploadInterface.getForm(): no form_selector" );
 852+ return false;
648853 }
649 - //just return the first form fond on the page.
650 - return $j('form :first').get(0);
651854 },
652 - updateProgress:function( perc ){
653 - //js_log('update progress: ' + perc);
654 - $j( '#up-progressbar' ).progressbar('value', parseInt( perc * 100 ) );
655 - $j( '#up-pstatus' ).html( parseInt( perc * 100 ) + '% - ' );
 855+
 856+ /**
 857+ * Update the progress bar to a given completion fraction (between 0 and 1)
 858+ */
 859+ updateProgress: function( fraction ) {
 860+ //js_log('update progress: ' + fraction);
 861+ $j( '#up-progressbar' ).progressbar( 'value', parseInt( fraction * 100 ) );
 862+ $j( '#up-pstatus' ).html( parseInt( fraction * 100 ) + '% - ' );
656863 },
657 - /*update to jQuery.ui progress display type */
658 - dispProgressOverlay:function(){
659 - var _this = this;
660 -
661 - //remove old instance:
662 - if($j('#upProgressDialog').length !=0 ){
663 - $j('#upProgressDialog').dialog( 'destroy' ).remove();
664 - }
665 - //re add it:
666 - $j('body').append('<div id="upProgressDialog" ></div>');
667864
668 - $j('#upProgressDialog').dialog({
669 - title:_this.getProgressTitle(),
670 - bgiframe: true,
671 - modal: true,
672 - draggable:true,
673 - width:400,
674 - heigh:200,
675 - beforeclose: function(event, ui) {
676 - if( event.button==0 && _this.action_done === false){
677 - return _this.cancel_action();
678 - }else{
679 - //click on button (don't do close action);
680 - return true;
681 - }
682 - },
683 - buttons: _this.cancel_button()
684 - });
685 - $j('#upProgressDialog').html(
686 - '<div id="up-pbar-container" style="width:90%;height:15px;" >' +
687 - '<div id="up-progressbar" style="height:15px;"></div>' +
688 - '<div id="up-status-container">'+
689 - '<span id="up-pstatus">0% - </span> ' +
690 - '<span id="up-status-state">' + gM('mwe-uploaded-status') + '</span> ' +
691 - '</div>'+
692 - '</div>'
693 - )
694 - //just display an empty progress window
695 - $j('#upProgressDialog').dialog('open');
 865+ /**
 866+ * Show a dialog box reporting upload progress and status
 867+ */
 868+ displayProgressOverlay: function() {
 869+ var _this = this;
696870
697 - //setup progress bar:
698 - $j('#up-progressbar').progressbar({
699 - value:0
700 - });
 871+ // Remove the old instance if present
 872+ if( $j( '#upProgressDialog' ).length != 0 ) {
 873+ $j( '#upProgressDialog' ).dialog( 'destroy' ).remove();
 874+ }
 875+ // Add a new one
 876+ $j( 'body' ).append( '<div id="upProgressDialog" ></div>' );
 877+
 878+ $j( '#upProgressDialog' ).dialog( {
 879+ title: _this.getProgressTitle(),
 880+ bgiframe: true,
 881+ modal: true,
 882+ draggable: true,
 883+ width: 400,
 884+ heigh: 200,
 885+ beforeclose: function( event, ui ) {
 886+ // If the upload is not complete, ask the user if they want to cancel
 887+ if ( event.button == 0 && _this.action_done === false ) {
 888+ _this.onCancel();
 889+ return false;
 890+ } else {
 891+ // Complete already, allow close
 892+ return true;
 893+ }
 894+ },
 895+ buttons: _this.getCancelButton()
 896+ } );
 897+ $j( '#upProgressDialog' ).html(
 898+ '<div id="up-pbar-container" style="width:90%;height:15px;" >' +
 899+ '<div id="up-progressbar" style="height:15px;"></div>' +
 900+ '<div id="up-status-container">' +
 901+ '<span id="up-pstatus">0% - </span> ' +
 902+ '<span id="up-status-state">' + gM( 'mwe-uploaded-status' ) + '</span> ' +
 903+ '</div>'+
 904+ '</div>'
 905+ );
 906+ // Open the empty progress window
 907+ $j( '#upProgressDialog' ).dialog( 'open' );
 908+
 909+ // Create progress bar
 910+ $j( '#up-progressbar' ).progressbar({
 911+ value: 0
 912+ });
701913 },
702 - cancel_button:function(){
703 - var _this = this;
704 - var cancelBtn = new Array();
705 - cancelBtn[ gM('mwe-cancel') ] = function(){
706 - return _this.cancel_action(this)
707 - };
708 - return cancelBtn;
 914+
 915+ /**
 916+ * Get a standard cancel button in the jQuery.ui dialog format
 917+ */
 918+ getCancelButton: function() {
 919+ var _this = this;
 920+ var cancelBtn = new Array();
 921+ cancelBtn[ gM( 'mwe-cancel' ) ] = function() {
 922+ return _this.onCancel( this )
 923+ };
 924+ return cancelBtn;
709925 },
710 - cancel_action : function( dlElm ){
 926+
 927+ /**
 928+ * UI cancel button handler.
 929+ * Show a dialog box asking the user whether they want to cancel an upload.
 930+ * FIXME: doesn't work at all.
 931+ */
 932+ onCancel: function( dlElm ) {
711933 //confirm:
712 - if( confirm( gM('mwe-cancel-confim') )){
 934+ if ( confirm( gM( 'mwe-cancel-confim' ) ) ) {
713935 //@@todo (cancel the encode / upload)
714 - $j(this).dialog('close');
 936+ $j( this ).dialog( 'close' );
715937 }
716938 }
717939 };
718940
719 -//add some jquery binding helpers
720 -(function($) {
 941+// jQuery plugins
 942+
 943+( function( $ ) {
721944 /**
722 - * doDestCheck checks the destination
 945+ * Check the upload destination filename for conflicts and show a conflict
 946+ * error message if there is one
723947 */
724 - $.fn.doDestCheck = function( opt ){
 948+ $.fn.doDestCheck = function( opt ) {
725949 var _this = this;
726 - js_log('doDestCheck::' + _this.selector);
 950+ js_log( 'doDestCheck::' + _this.selector );
727951
728 - //set up option defaults;
729 - if(!opt.warn_target)
 952+ // Set up option defaults
 953+ if ( !opt.warn_target )
730954 opt.warn_target = '#wpDestFile-warning';
731 -
732 - //add the wpDestFile-warning target:
733 - if( $j( '#wpDestFile-warning' ).length == 0 )
734 - $j('#mw-htmlform-options tr:last').after('<tr><td></td><td id="wpDestFile-warning"></td></tr>');
735 -
736 - //empty target warn:
 955+
 956+ // Add the wpDestFile-warning row
 957+ if ( $j( '#wpDestFile-warning' ).length == 0 ) {
 958+ $j( '#mw-htmlform-options tr:last' )
 959+ .after( '<tr><td></td><td id="wpDestFile-warning"></td></tr>' );
 960+ }
 961+
 962+ // Remove any existing warning
737963 $j( opt.warn_target ).empty();
738 -
739 - //show loading
740 - $j( _this.selector ).append('<img id="mw-spinner-wpDestFile" src ="'+ stylepath + '/common/images/spinner.gif" />');
741 -
742 - //try and get a thumb of the current file (check its destination)
743 - do_api_req({
744 - 'data':{
745 - 'titles': 'File:' + $j(_this.selector).val(),//@@todo we may need a more clever way to get a the filename
746 - 'prop': 'imageinfo',
747 - 'iiprop':'url|mime|size',
748 - 'iiurlwidth': 150
749 - }
750 - },function(data){
751 - //remove spinner:
752 - $j('#mw-spinner-wpDestFile').remove();
753 - if(data && data.query && data.query.pages){
754 - if( data.query.pages[-1] ){
755 - //all good no file there
756 - }else{
757 - for( var page_id in data.query.pages ) {
758 - if( data.query.pages[ page_id ].imageinfo ) {
759 - var ntitle = ( data.query.normalized)? data.query.normalized[0].to : data.query.pages[ page_id ].title
760 - var img = data.query.pages[ page_id ].imageinfo[0];
761 - $j('#wpDestFile-warning').html(
762 - gM('mwe-fileexists', ntitle) +
763 - '<div class="thumb tright">' +
764 - '<div style="width: ' + ( parseInt(img.thumbwidth)+2 ) + 'px;" class="thumbinner">' +
765 - '<a title="' + ntitle + '" class="image" href="' + img.descriptionurl + '">' +
766 - '<img width="' + img.thumbwidth + '" height="' + img.thumbheight + '" border="0" class="thumbimage" ' +
767 - 'src="' + img.thumburl + '"' +
768 - ' alt="' + ntitle + '"/>' +
769 - '</a>' +
770 - '<div class="thumbcaption">' +
771 - '<div class="magnify">' +
772 - '<a title="' + gM('thumbnail-more') + '" class="internal" ' +
773 - 'href="' + img.descriptionurl +'"><img width="15" height="11" alt="" ' +
774 - 'src="' + stylepath + "/common/images/magnify-clip.png\" />" +
775 - '</a>'+
776 - '</div>'+
777 - gM('mwe-fileexists-thumb') +
778 - '</div>' +
779 - '</div>'+
780 - '</div>'
781 - );
782 - }
 964+
 965+ // Show the AJAX spinner
 966+ $j( _this.selector )
 967+ .append( '<img id="mw-spinner-wpDestFile" ' +
 968+ 'src ="' + stylepath + '/common/images/spinner.gif" />' );
 969+
 970+ // Do the destination check
 971+ do_api_req(
 972+ {
 973+ 'data': {
 974+ //@@todo we may need a more clever way to get a the filename
 975+ 'titles': 'File:' + $j( _this.selector ).val(),
 976+ 'prop': 'imageinfo',
 977+ 'iiprop': 'url|mime|size',
 978+ 'iiurlwidth': 150
 979+ }
 980+ },
 981+ function( data ) {
 982+ // Remove spinner
 983+ $j( '#mw-spinner-wpDestFile' ).remove();
 984+
 985+ if ( !data || !data.query || !data.query.pages ) {
 986+ // Ignore a null result
 987+ return;
 988+ }
 989+
 990+ if ( data.query.pages[-1] ) {
 991+ // No conflict found
 992+ return;
 993+ }
 994+ for ( var page_id in data.query.pages ) {
 995+ if ( !data.query.pages[ page_id ].imageinfo ) {
 996+ continue;
783997 }
 998+
 999+ // Conflict found, show warning
 1000+ if ( data.query.normalized ) {
 1001+ var ntitle = data.query.normalized[0].to;
 1002+ } else {
 1003+ var ntitle = data.query.pages[ page_id ].title
 1004+ }
 1005+ var img = data.query.pages[ page_id ].imageinfo[0];
 1006+ $j( '#wpDestFile-warning' ).html(
 1007+ gM( 'mwe-fileexists', ntitle ) +
 1008+ '<div class="thumb tright">' +
 1009+ '<div ' +
 1010+ 'style="width: ' + ( parseInt( img.thumbwidth ) + 2 ) + 'px;" ' +
 1011+ 'class="thumbinner">' +
 1012+ '<a ' +
 1013+ 'title="' + ntitle + '" ' +
 1014+ 'class="image" ' +
 1015+ 'href="' + img.descriptionurl + '">' +
 1016+ '<img ' +
 1017+ 'width="' + img.thumbwidth + '" ' +
 1018+ 'height="' + img.thumbheight + '" ' +
 1019+ 'border="0" ' +
 1020+ 'class="thumbimage" ' +
 1021+ 'src="' + img.thumburl + '" ' +
 1022+ 'alt="' + ntitle + '"/>' +
 1023+ '</a>' +
 1024+ '<div class="thumbcaption">' +
 1025+ '<div class="magnify">' +
 1026+ '<a title="' + gM('thumbnail-more') + '" class="internal" ' +
 1027+ 'href="' + img.descriptionurl +'">' +
 1028+ '<img width="15" height="11" alt="" ' +
 1029+ 'src="' + stylepath + "/common/images/magnify-clip.png\" />" +
 1030+ '</a>' +
 1031+ '</div>' +
 1032+ gM( 'mwe-fileexists-thumb' ) +
 1033+ '</div>' +
 1034+ '</div>' +
 1035+ '</div>'
 1036+ );
7841037 }
7851038 }
786 - });
 1039+ );
7871040 }
788 -})(jQuery);
 1041+})( jQuery );
Index: trunk/phase3/js2/mwEmbed/libAddMedia/mvAdvFirefogg.js
@@ -1,5 +1,5 @@
22 /*
3 - * Adds advanced firefogg support (let you control and structure advanced controls over many aspects of video encoding)
 3+ * Advanced Firefogg support. Lets you control many aspects of video encoding.
44 */
55
66 //@@todo put all msg text into loadGM json
@@ -14,7 +14,7 @@
1515 "fogg-cg-advAudio" : "Advanced audio encoding controls",
1616 "fogg-preset-custom" : "Custom settings",
1717 "fogg-webvideo-desc" : "Web video Theora, Vorbis 400 kbit\/s and 400px maximum width",
18 - "fogg-savebandwith-desc" : "Low bandwith Theora, Vorbis 164 kbit\/s and 200px maximum width",
 18+ "fogg-savebandwidth-desc" : "Low bandwidth Theora, Vorbis 164 kbit\/s and 200px maximum width",
1919 "fogg-highquality-desc" : "High quality Theora, Vorbis 1080px maximum width",
2020 "fogg-videoQuality-title" : "Video quality",
2121 "fogg-videoQuality-help" : "Used to set the <i>visual quality<\/i> of the encoded video (not used if you set bitrate in advanced controls below).",
@@ -39,7 +39,7 @@
4040 "fogg-framerate-title" : "Frame rate",
4141 "fogg-framerate-help" : "The video frame rate. More about <a target=\"_new\" href=\"http:\/\/en.wikipedia.org\/wiki\/Frame_rate\">frame rate<\/a>.",
4242 "fogg-aspect-title" : "Aspect ratio",
43 - "fogg-aspect-help" : "The video aspect ratio can be fraction 4:3 or 16:9. More about <a target=\"_new\" href=\"http:\/\/en.wikipedia.org\/wiki\/Aspect_ratio_%28image%29\">aspect ratios<\/a>.",
 43+ "fogg-aspect-help" : "The video aspect ratio can be 4:3 or 16:9. More about <a target=\"_new\" href=\"http:\/\/en.wikipedia.org\/wiki\/Aspect_ratio_%28image%29\">aspect ratios<\/a>.",
4444 "fogg-keyframeInterval-title" : "Key frame interval",
4545 "fogg-keyframeInterval-help" : "The keyframe interval in frames. Note: Most codecs force keyframes if the difference between frames is greater than keyframe encode size. More about <a href=\"http:\/\/en.wikipedia.org\/wiki\/I-frame\">keyframes<\/a>.",
4646 "fogg-denoise-title" : "Denoise filter",
@@ -48,7 +48,7 @@
4949 "fogg-novideo-help" : "disable video in the output",
5050 "fogg-audioBitrate-title" : "Audio bitrate",
5151 "fogg-samplerate-title" : "Audio sampling rate",
52 - "fogg-samplerate-help" : "set output samplerate (in Hz).",
 52+ "fogg-samplerate-help" : "set output sample rate (in Hz).",
5353 "fogg-noaudio-title" : "No audio",
5454 "fogg-noaudio-help" : "disable audio in the output",
5555 "fogg-title-title" : "Title",
@@ -69,41 +69,40 @@
7070 "fogg-contact-help" : "Contact link"
7171 });
7272
73 -var mvAdvFirefogg = function( iObj ){
 73+var mvAdvFirefogg = function( iObj ) {
7474 return this.init( iObj );
7575 }
7676 var default_mvAdvFirefogg_config = {
77 - // Which config groups to include
78 - 'config_groups' : ['preset', 'range', 'quality', 'meta', 'advVideo', 'advAudio'],
 77+ // Config groups to include
 78+ 'config_groups': [ 'preset', 'range', 'quality', 'meta', 'advVideo', 'advAudio' ],
7979
8080 // If you want to load any custom presets must follow the mvAdvFirefogg.presetConf json outline below
81 - 'custom_presets' : {},
 81+ 'custom_presets': {},
8282
83 - // Any firefog config properties that may need to be excluded from options
84 - 'exclude_settings' : [],
 83+ // Any Firefog config properties that may need to be excluded from options
 84+ 'exclude_settings': [],
8585
86 - // The control container (where we put all the controls)
87 - 'target_control_container':false
 86+ // The control container
 87+ 'target_control_container': false
8888 }
8989
9090 mvAdvFirefogg.prototype = {
91 - //the global groupings and titles for for configuration options :
92 - config_groups : [ 'preset', 'range', 'quality', 'meta', 'advVideo', 'advAudio'],
93 - //list of pre-sets:
 91+ // The configuration group names
 92+ config_groups: [ 'preset', 'range', 'quality', 'meta', 'advVideo', 'advAudio' ],
9493
95 - //local instance encoder config:
96 - default_local_settings:{
97 - 'd' : 'webvideo',
98 - 'type' : 'select',
 94+ // Default configuration for this class
 95+ default_local_settings: {
 96+ 'default': 'webvideo',
 97+ 'type': 'select',
9998 'selectVal': ['webvideo'],
100 - 'group' : "preset",
101 - 'pSet' : {
102 - 'custom':{
 99+ 'group': "preset",
 100+ 'presets': {
 101+ 'custom': {
103102 'descKey': 'fogg-preset-custom',
104103 'conf': {}
105104 },
106105 'webvideo': {
107 - 'desc': gM('fogg-webvideo-desc'),
 106+ 'desc': gM( 'fogg-webvideo-desc' ),
108107 'conf': {
109108 'maxSize' : 400,
110109 'videoBitrate' : 544,
@@ -111,8 +110,8 @@
112111 'noUpscaling' : true,
113112 }
114113 },
115 - 'savebandwith': {
116 - 'desc': gM('fogg-savebandwith-desc'),
 114+ 'savebandwidth': {
 115+ 'desc': gM( 'fogg-savebandwidth-desc' ),
117116 'conf': {
118117 'maxSize' : 200,
119118 'videoBitrate' : 164,
@@ -123,8 +122,8 @@
124123 'noUpscaling' : true
125124 }
126125 },
127 - 'hqstream':{
128 - 'desc': gM('fogg-highquality-desc'),
 126+ 'hqstream': {
 127+ 'desc': gM( 'fogg-highquality-desc' ),
129128 'conf': {
130129 'maxSize' : 1080,
131130 'videoQuality' : 6,
@@ -134,717 +133,851 @@
135134 },
136135 }
137136 },
 137+
 138+ // Customised configuration hashtable
138139 local_settings: {},
139140
140 - //core firefogg default encoder configuration
141 - //see encoder options here: http://www.firefogg.org/dev/index.html
142 -
143 -
144 - default_encoder_config : {
145 - //base quality settings:
 141+ // Core Firefogg default encoder configuration
 142+ // See encoder options here: http://www.firefogg.org/dev/index.html
 143+ default_encoder_config: {
 144+ // Base quality settings
146145 'videoQuality': {
147 - 'd' : 5,
148 - 'range' : {'min':0,'max':10},
149 - 'type' : 'slider',
150 - 'group' : 'quality'
 146+ 'default' : 5,
 147+ 'range' : { 'min': 0,'max': 10 },
 148+ 'type' : 'slider',
 149+ 'group' : 'quality'
151150 },
152 - 'starttime':{
153 - 'type' : "float",
154 - 'group' : "range"
 151+ 'starttime': {
 152+ 'type' : "float",
 153+ 'group' : "range"
155154 },
156 - 'endtime':{
157 - 'type' : "float",
158 - 'group' : "range"
 155+ 'endtime': {
 156+ 'type' : "float",
 157+ 'group' : "range"
159158 },
160159 'audioQuality': {
161 - 'd' : 1,
162 - 'range' : {'min':-1,'max':10},
163 - 'type' : 'slider',
164 - 'group' : 'quality',
 160+ 'default' : 1,
 161+ 'range' : { 'min': -1, 'max': 10 },
 162+ 'type' : 'slider',
 163+ 'group' : 'quality',
165164 },
166 - 'videoCodec':{
167 - 'd' : "theora",
168 - 'selectVal' : ['theora'],
169 - 'type' : "select",
170 - 'group' : "quality"
 165+ 'videoCodec': {
 166+ 'default' : "theora",
 167+ 'selectVal' : [ 'theora' ],
 168+ 'type' : "select",
 169+ 'group' : "quality"
171170 },
172 - 'audioCodec':{
173 - 'd' : "vorbis",
174 - 'selectVal' : ['vorbis'],
175 - 'type' : "select",
176 - 'group' : "quality"
 171+ 'audioCodec': {
 172+ 'default' : "vorbis",
 173+ 'selectVal' : [ 'vorbis' ],
 174+ 'type' : "select",
 175+ 'group' : "quality"
177176 },
178177 'width': {
179 - 'range' : {'min':0,'max':1080},
180 - 'step' : 4,
181 - 'type' : 'slider',
182 - 'group' : "quality"
 178+ 'range' : { 'min': 0, 'max': 1080 },
 179+ 'step' : 4,
 180+ 'type' : 'slider',
 181+ 'group' : "quality"
183182 },
184183 'height': {
185 - 'range' : {'min':0,'max':1080},
186 - 'step' : 4,
187 - 'type' : "slider",
188 - 'group' : "quality"
 184+ 'range' : { 'min': 0, 'max' : 1080 },
 185+ 'step' : 4,
 186+ 'type' : "slider",
 187+ 'group' : "quality"
189188 },
190 - //advanced Video control configs:
191 - 'videoBitrate':{
192 - 'range' : {'min':1, 'max':16778},
193 - 'type' : "slider",
194 - 'group' : "advVideo",
 189+
 190+ // Advanced video control
 191+ 'videoBitrate': {
 192+ 'range' : { 'min' : 1, 'max' : 16778 },
 193+ 'type' : "slider",
 194+ 'group' : "advVideo",
195195 } ,
196 - 'twopass':{
197 - 'type' : "boolean",
198 - 'group' : "advVideo"
 196+ 'twopass': {
 197+ 'type' : "boolean",
 198+ 'group' : "advVideo"
199199 },
200 - 'framerate':{
201 - 'd' : '24',
202 - 'selectVal' : ['12', '16', {'24000:1001':'23.97'}, '24', '25', {'30000:1001':'29.97'}, '30'],
203 - 'type' : "select",
204 - 'group' : "advVideo"
 200+ 'framerate': {
 201+ 'default' : '24',
 202+ 'selectVal' : [ '12', '16', { '24000:1001' : '23.97' }, '24', '25',
 203+ { '30000:1001' : '29.97' }, '30' ],
 204+ 'type' : "select",
 205+ 'group' : "advVideo"
205206 },
206 - 'aspect':{
207 - 'd' : '4:3',
208 - 'type' : "select",
209 - 'selectVal' : ['4:3', '16:9'],
210 - 'group' : "advVideo"
 207+ 'aspect': {
 208+ 'default' : '4:3',
 209+ 'type' : "select",
 210+ 'selectVal' : [ '4:3', '16:9' ],
 211+ 'group' : "advVideo"
211212 },
212 - 'keyframeInterval':{
213 - 'd' : '64',
214 - 'range' : {'min':0,'max':65536},
 213+ 'keyframeInterval': {
 214+ 'default' : '64',
 215+ 'range' : { 'min': 0, 'max': 65536 },
215216 'numberType': 'force keyframe every $1 frames',
216 - 'type' : 'int',
217 - 'group' : 'advVideo'
 217+ 'type' : 'int',
 218+ 'group' : 'advVideo'
218219 },
219 - 'denoise':{
220 - 'type' : "boolean",
221 - 'group' : 'advVideo'
 220+ 'denoise': {
 221+ 'type' : "boolean",
 222+ 'group' : 'advVideo'
222223 },
223 - 'novideo':{
224 - 'type' : "boolean",
225 - 'group' : 'advVideo'
 224+ 'novideo': {
 225+ 'type' : "boolean",
 226+ 'group' : 'advVideo'
226227 },
227228
228 - //advanced Audio control Config:
229 - 'audioBitrate':{
230 - 'range' : {'min':32,'max':500},
 229+ // Advanced audio control
 230+ 'audioBitrate': {
 231+ 'range' : { 'min': 32, 'max': 500 },
231232 'numberType': '$1 kbs',
232 - 'type' : 'slider'
 233+ 'type' : 'slider'
233234 },
234 - 'samplerate':{
235 - 'type' : 'select',
236 - 'selectVal' : [{'22050':'22 kHz'}, {'44100':'44 khz'}, {'48000':'48 khz'}],
237 - 'formatSelect' : function(val){
238 - return (Math.round(val/100)*10) + ' Hz';
 235+ 'samplerate': {
 236+ 'type' : 'select',
 237+ 'selectVal' : [ { '22050': '22 kHz' }, { '44100': '44 khz' }, { '48000': '48 khz' } ],
 238+ 'formatSelect' : function( val ) {
 239+ return ( Math.round( val / 100 ) * 10 ) + ' Hz';
239240 }
240241 },
241 - 'noaudio':{
242 - 'type' : 'boolean',
243 - 'group' : 'advAudio'
 242+ 'noaudio': {
 243+ 'type' : 'boolean',
 244+ 'group' : 'advAudio'
244245 },
245246
246 - //meta tags:
247 - 'title':{
248 - 'type' : 'string',
249 - 'group' : 'meta'
 247+ // Meta tags
 248+ 'title': {
 249+ 'type' : 'string',
 250+ 'group' : 'meta'
250251 },
251 - 'artist':{
252 - 'type' : 'string',
253 - 'group' : 'meta'
 252+ 'artist': {
 253+ 'type' : 'string',
 254+ 'group' : 'meta'
254255 },
255 - 'date':{
256 - 'group' : 'meta',
257 - 'type' : 'date'
 256+ 'date': {
 257+ 'group' : 'meta',
 258+ 'type' : 'date'
258259 },
259 - 'location':{
260 - 'type' : 'string',
261 - 'group' : 'meta'
 260+ 'location': {
 261+ 'type' : 'string',
 262+ 'group' : 'meta'
262263 },
263 - 'organization':{
264 - 'type' : 'string',
265 - 'group' : 'meta'
 264+ 'organization': {
 265+ 'type' : 'string',
 266+ 'group' : 'meta'
266267 },
267 - 'copyright':{
268 - 'type' : 'string',
269 - 'group' : 'meta'
 268+ 'copyright': {
 269+ 'type' : 'string',
 270+ 'group' : 'meta'
270271 },
271 - 'license':{
272 - 'type' : 'string',
 272+ 'license': {
 273+ 'type' : 'string',
273274 },
274 - 'contact':{
275 - 'type' : 'string',
276 - 'group' : 'meta'
 275+ 'contact': {
 276+ 'type' : 'string',
 277+ 'group' : 'meta'
277278 }
278279 },
279 - init:function( iObj ){
280 - //setup a "supported" iObj:
281 - for(var i in iObj){
282 - if( typeof default_mvAdvFirefogg_config [i] != 'undefined' ){
283 - this[i] = iObj[i];
 280+
 281+ /**
 282+ * Initialise this object
 283+ */
 284+ init: function( options ) {
 285+ // Set up a supported object:
 286+ for ( var key in options ) {
 287+ if ( typeof default_mvAdvFirefogg_config[key] != 'undefined' ) {
 288+ this[key] = options[key];
284289 }
285290 }
286 - //inherit the base mvFirefogg class:
287 - var myFogg = new mvFirefogg( iObj );
288 - for(var i in myFogg){
289 - if( typeof this[i] != 'undefined'){
290 - this[ 'basefogg_' + i ] = myFogg[i];
291 - }else{
292 - this[ i ] = myFogg[i];
 291+ // Inherit the base mvFirefogg class:
 292+ var baseFirefogg = new mvFirefogg( options );
 293+ for ( var key in baseFirefogg ) {
 294+ if ( typeof this[key] != 'undefined' ) {
 295+ this[ 'basefogg_' + key ] = baseFirefogg[ key ];
 296+ } else {
 297+ this[ key ] = baseFirefogg[ key ];
293298 }
294299 }
295300 },
296 - setupForm:function(){
297 - //call base firefogg form setup
 301+
 302+ setupForm: function() {
298303 basefogg_setupForm();
 304+ this.createControls();
 305+ this.bindControls();
 306+ },
299307
300 - //gennerate the control html
301 - this.doControlHTML();
302 -
303 - //setup control bindings:
304 - this.doControlBindings();
305 -
306 - },
307 - doControlHTML: function(){
308 - js_log("adv doControlHTML");
 308+ createControls: function() {
 309+ js_log( "adv createControls" );
309310 var _this = this;
310 - //load presets from cookie:
 311+ // Load presets from the cookie
311312 this.loadEncSettings();
312313
313 - //add base control buttons:
314 - this.basefogg_doControlHTML();
 314+ // Add the base control buttons
 315+ this.basefogg_createControls();
315316
316 - //build the config group outpouts
317 - var gdout ='';
318 - $j.each(this.config_groups, function(inx, group_key){
319 - gdout+= '<div> '+
320 - '<h3><a href="#" class="gd_'+group_key+'" >' + gM('fogg-cg-'+group_key) + '</a></h3>'+
321 - '<div>';
322 - //output that group control options:
323 - gdout+='<table width="' + ($j(_this.selector).width()-60) + '" ><tr><td width="35%"></td><td width="65%"></td></tr>';
324 - //output the special prset output
325 - if(group_key=='preset'){
326 - gdout += _this.proccessPresetControl();
 317+ // Build the config group output
 318+ var gdout = '';
 319+ $j.each( this.config_groups, function( inx, group_key ) {
 320+ gdout += '<div> ' +
 321+ '<h3><a href="#" class="gd_' + group_key + '" >' +
 322+ gM( 'fogg-cg-' + group_key ) + '</a></h3>' +
 323+ '<div>';
 324+ // Output this group's control options:
 325+ gdout += '<table width="' + ( $j( _this.selector ).width() - 60 ) + '" >' +
 326+ '<tr><td width="35%"></td><td width="65%"></td></tr>';
 327+ // If this is the preset group, output the preset control
 328+ if ( group_key == 'preset' ) {
 329+ gdout += _this.getPresetControlHtml();
327330 }
328 - for(var cK in _this.default_encoder_config){
329 - var cConf = _this.default_encoder_config[cK];
330 - if(cConf.group == group_key){
331 - gdout+= _this.proccessCkControlHTML( cK );
 331+ // Output the encoder config controls
 332+ for ( var configKey in _this.default_encoder_config ) {
 333+ var confEntry = _this.default_encoder_config[ configKey ];
 334+ if( confEntry.group == group_key ) {
 335+ gdout += _this.getConfigControlHtml( configKey );
332336 }
333337 }
334 - gdout+='</table>';
335 - gdout+= '</div>' +
336 - '</div>';
337 -
 338+ gdout += '</table></div></div>';
338339 });
339 - //add the control container:
340 - if(!this.target_control_container){
 340+ // Add the control container
 341+ if( !this.target_control_container ) {
341342 this.target_control_container = this.selector + ' .control_container';
342 - //set the target contorl container to height
343 - $j(this.selector).append( '<p><div class="control_container"></div>' );
 343+ $j( this.selector ).append( '<p><div class="control_container"></div>' );
344344 }
345 - //hide the container and add the output
346 - $j(this.target_control_container).hide();
347 - $j(this.target_control_container).html( gdout );
348 -
 345+ // Hide the container and add the output
 346+ $j( this.target_control_container ).hide();
 347+ $j( this.target_control_container ).html( gdout );
349348 },
350 - //custom advanced target rewrites:
351 - getTargetHtml:function(target){
352 - if( target=='target_btn_select_file' ||
353 - target=='target_btn_select_new_file'||
354 - target=='target_btn_save_local_file'){
355 - var icon = (target=='target_btn_save_local_file')?'ui-icon-video':'ui-icon-folder-open';
356 - return '<a class="ui-state-default ui-corner-all ui-icon_link '+
357 - target +'" href="#"><span class="ui-icon ' + icon + '"/>' +
358 - gM( 'fogg-' + target.substring(11) ) +
359 - '</a>';
360 - }else if( target=='target_btn_select_url'){
361 - //return the btnHtml:
362 - return $j.btnHtml( gM( 'fogg-' + target.substring(11) ), target, 'link');
363349
364 - }else if( target=='target_use_latest_fox' ||
365 - target=='target_please_install' ||
366 - target == 'target_passthrough_mode'){
367 - return '<div style="margin-top:1em;padding: 0pt 0.7em;" class="ui-state-error ui-corner-all ' +
368 - target + '">' +
369 - '<p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-alert"/>'+
370 - gM( 'fogg-' + target.substring(7)) +'</p>'+
371 - '</div>';
372 - }else if( target == 'target_input_file_name'){
373 - return '<br><br><input style="" class="text ui-widget-content ui-corner-all ' + target + '" '+
374 - 'type="text" value="' + gM( 'fogg-' + target.substring(11)) + '" size="60" /> ';
375 - }else{
376 - js_log('call : basefogg_getTargetHtml');
377 - return this.basefogg_getTargetHtml(target);
 350+ // Custom advanced target rewrites
 351+ getControlHtml: function( target ) {
 352+ switch ( target ) {
 353+ case 'target_btn_select_file':
 354+ case 'target_btn_select_new_file':
 355+ case 'target_btn_save_local_file':
 356+ var icon;
 357+ if ( target == 'target_btn_save_local_file' ) {
 358+ icon = 'ui-icon-video'
 359+ } else {
 360+ icon = 'ui-icon-folder-open';
 361+ }
 362+ var linkText = gM( target.replace( /^target_btn_/, 'fogg-' ) );
 363+ return '<a class="ui-state-default ui-corner-all ui-icon_link ' +
 364+ target + '" href="#"><span class="ui-icon ' + icon + '"/>' +
 365+ linkText +
 366+ '</a>';
 367+ case 'target_btn_select_url':
 368+ return $j.btnHtml( gM( 'fogg-select_url' ), target, 'link' );
 369+ case 'target_use_latest_firefox':
 370+ case 'target_please_install':
 371+ case 'target_passthrough_mode':
 372+ var text = gM( target.replace( '/^target_', 'fogg-' ) );
 373+ return
 374+ '<div ' +
 375+ 'style="margin-top:1em;padding: 0pt 0.7em;" ' +
 376+ 'class="ui-state-error ui-corner-all ' +
 377+ target + '">' +
 378+ '<p>' +
 379+ '<span style="float: left; margin-right: 0.3em;" ' +
 380+ 'class="ui-icon ui-icon-alert"/>' +
 381+ text +
 382+ '</p>' +
 383+ '</div>';
 384+ case 'target_input_file_name':
 385+ var text = gM( 'fogg-input_file_name' );
 386+ return '<br><br><input style="" ' +
 387+ 'class="text ui-widget-content ui-corner-all ' + target + '" ' +
 388+ 'type="text" value="' + text + '" size="60" /> ';
 389+ default:
 390+ js_log( 'call : basefogg_getTargetHtml' );
 391+ return this.basefogg_getTargetHtml( target );
378392 }
379393 },
380 - proccessPresetControl:function(){
381 - var out='';
 394+
 395+ getPresetControlHtml: function() {
 396+ var out = '';
382397 var _this = this;
383 - js_log('proccessPresetControl::');
384 - if(typeof this.local_settings.pSet!= 'undefined' ){
385 - out+= '<select class="_preset_select">';
386 - $j.each(this.local_settings.pSet, function(pKey, pSet){
387 - var pDesc = (pSet.descKey) ? gM(pSet.descKey) : pSet.desc;
388 - var sel = (_this.local_settings.d == pKey)?' selected':'';
389 - out+='<option value="'+pKey+'" '+sel+'>'+ pDesc+'</option>';
 398+ js_log( 'getPresetControlHtml::' );
 399+ if ( typeof this.local_settings.presets != 'undefined' ) {
 400+ out += '<select class="_preset_select">';
 401+ $j.each( this.local_settings.presets, function( presetKey, preset ) {
 402+ var presetDesc = preset.descKey ? gM( preset.descKey ) : preset.desc;
 403+ var sel = ( _this.local_settings['default'] == presetKey ) ? ' selected' : '';
 404+ out += '<option value="' + presetKey + '" ' + sel + '>' + presetDesc + '</option>';
390405 });
391 - out+='</select>';
392 - }
 406+ out += '</select>';
 407+ }
393408 return out;
394409 },
395 - proccessCkControlHTML:function( cK ){
396 - var cConf = this.default_encoder_config[cK];
397 - var out ='';
398 - out+='<tr><td valign="top">'+
399 - '<label for="_' + cK + '">' +
400 - gM( 'fogg-' + cK + '-title') + ':' +
401 - '<span title="' + gM('fogg-help-sticky') + '" class="help_'+ cK + ' ui-icon ui-icon-info" style="float:left"></span>'+
402 - '</label></td><td valign="top">';
403 - //if we don't value for this:
404 - var dv = ( this.default_encoder_config[cK].d ) ? this.default_encoder_config[cK].d : '';
405 - //switch on the config type
406 - switch( cConf.type ){
 410+
 411+ getConfigControlHtml : function( configKey ) {
 412+ var configEntry = this.default_encoder_config[configKey];
 413+ var out = '';
 414+ out += '<tr><td valign="top">' +
 415+ '<label for="_' + configKey + '">' +
 416+ gM( 'fogg-' + configKey + '-title' ) + ':' +
 417+ '<span title="' + gM( 'fogg-help-sticky' ) + '" ' +
 418+ 'class="help_' + configKey + ' ui-icon ui-icon-info" style="float:left">' +
 419+ '</span>' +
 420+ '</label></td><td valign="top">';
 421+ // Get the default value (or an empty string if there is no default)
 422+
 423+ var defaultValue = this.default_encoder_config[configKey]['default'];
 424+ if ( !defaultValue ) {
 425+ defaultValue = '';
 426+ }
 427+ var type = configEntry.type; // shortcut
 428+
 429+ // Switch on the config type
 430+ switch( type ) {
407431 case 'string':
408432 case 'date':
409433 case 'int':
410434 case 'float':
411 - var size = ( cConf.type =='string' ||cConf.type == 'date' )?'14':'4';
412 - out+= '<input size="' + size + '" type="text" class="_' + cK + ' text ui-widget-content ui-corner-all" value="' + dv + '" >' ;
413 - break;
 435+ var size = ( type == 'string' || type == 'date' ) ? '14' : '4';
 436+ out += '<input ' +
 437+ 'size="' + size + '" ' +
 438+ 'type="text" ' +
 439+ 'class="_' + configKey + ' text ui-widget-content ui-corner-all" ' +
 440+ 'value="' + defaultValue + '" >';
 441+ break;
414442 case 'boolean':
415 - var checked_attr = (dv===true)?' checked="true"':'';
416 - out+='<input type="checkbox" class="_'+cK+ ' ui-widget-content ui-corner-all" ' + checked_attr + '>';
417 - break;
 443+ var checked_attr = ( defaultValue === true ) ? ' checked="true"' : '';
 444+ out += '<input ' +
 445+ 'type="checkbox" ' +
 446+ 'class="_' + configKey + ' ui-widget-content ui-corner-all" ' +
 447+ checked_attr + '>';
 448+ break;
418449 case 'slider':
419 - var strMax = this.default_encoder_config[ cK ].range.max + '';
420 - maxdigits = strMax.length +1;
421 - out+= '<input type="text" maxlength="'+maxdigits+'" size="' +maxdigits + '" '+
422 - 'class="_'+cK+ ' text ui-widget-content ui-corner-all" style="display:inline;border:0; color:#f6931f; font-weight:bold;" ' +
423 - 'value="' + dv + '" >' +
424 - '<div class="slider_' + cK + '"></div>';
425 - break;
 450+ var strMax = this.default_encoder_config[ configKey ].range.max + '';
 451+ maxDigits = strMax.length + 1;
 452+ out += '<input ' +
 453+ 'type="text" ' +
 454+ 'maxlength="' + maxDigits + '" ' +
 455+ 'size="' + maxDigits + '" ' +
 456+ 'class="_' + configKey + ' text ui-widget-content ui-corner-all" ' +
 457+ 'style="display:inline;border:0; color:#f6931f; font-weight:bold;" ' +
 458+ 'value="' + defaultValue + '" >' +
 459+ '<div class="slider_' + configKey + '"></div>';
 460+ break;
426461 case 'select':
427 - out+= '<select class="_' + cK + '">'+
 462+ out += '<select class="_' + configKey + '">' +
428463 '<option value=""> </option>';
429 - for(var i in cConf.selectVal){
430 - var val = cConf.selectVal[i];
431 - if(typeof val == 'string'){
432 - var sel = ( cConf.selectVal[i] == val)?' selected':'';
433 - out+= '<option value="'+val+'"'+sel+'>'+val+'</option>';
434 - }else if(typeof val == 'object'){
435 - for(var key in val){
 464+ for ( var i in configEntry.selectVal ) {
 465+ var val = configEntry.selectVal[i];
 466+ if ( typeof val == 'string' ) {
 467+ var sel = ( configEntry.selectVal[i] == val ) ? ' selected' : '';
 468+ out += '<option value="' + val + '"'+sel+'>' + val + '</option>';
 469+ } else if ( typeof val == 'object' ) {
 470+ for ( var key in val ) {
436471 hr_val = val[key];
437472 }
438 - var sel = ( cConf.selectVal[i] == key )?' selected':'';
 473+ var sel = ( configEntry.selectVal[i] == key ) ? ' selected' : '';
439474
440 - out+= '<option value="'+key+'"'+sel+'>'+hr_val+'</option>';
 475+ out += '<option value="' + key + '"' + sel + '>' + hr_val + '</option>';
441476 }
442477 }
443 - out+='</select>';
444 - break;
 478+ out += '</select>';
 479+ break;
445480 }
446 - //output the help row:
447 - out+='<div class="helpRow_' + cK + '">'+
448 - '<span class="helpClose_' + cK + ' ui-icon ui-icon-circle-close" '+
449 - 'title="Close Help"'+
450 - 'style="float:left"/>'+
451 - gM('fogg-'+ cK + '-help') +
452 - '</div>';
453 - out+='</td></tr><tr><td colspan="2" height="10"></td></tr>';
 481+ // output the help row:
 482+ out += '<div class="helpRow_' + configKey + '">' +
 483+ '<span class="helpClose_' + configKey + ' ui-icon ui-icon-circle-close" ' +
 484+ 'title="Close Help"' +
 485+ 'style="float:left"/>' +
 486+ gM( 'fogg-'+ configKey + '-help' ) +
 487+ '</div>';
 488+ out += '</td></tr><tr><td colspan="2" height="10"></td></tr>';
454489 return out;
455490 },
456 - selectByUrl:function(){
457 - var urlValue = prompt("Please enter the source media url you would like to transcode from.","http://");
458 - if( urlValue ){
459 - //update the mode:
460 - this.sourceMode = 'url';
461 - this.sourceUrl = urlValue;
462 - this.selectFoggActions();
463 - this.autoEncoderSettings();
464 - //update the input target
465 - $j(this.target_input_file_name).unbind().val( urlValue ).removeAttr('readonly');
 491+
 492+ /**
 493+ * Show a dialog box asking the user to select a source URL.
 494+ * FIXME: half-written, doesn't work at all.
 495+ */
 496+ selectSourceUrl: function() {
 497+ // FIXME: i18n
 498+ var url = prompt( "Please enter the source media url you would like " +
 499+ "to transcode from.", "http://" );
 500+ if ( !url ) {
 501+ return;
466502 }
 503+
 504+ // update the mode:
 505+ this.sourceMode = 'url';
 506+ this.sourceUrl = url;
 507+ this.clearSourceInfoCache();
 508+ this.updateSourceFileUI();
 509+ // update the input target
 510+ $j( this.target_input_file_name )
 511+ .unbind()
 512+ .val( url )
 513+ .removeAttr( 'readonly' );
467514 },
468 - doControlBindings:function(){
 515+
 516+ bindControls: function() {
469517 var _this = this;
470 - _this.basefogg_doControlBindings();
471 - //show the select by url if present:
472 - /*$j( this.target_btn_select_url ).unbind(
473 - ).attr('disabled', false
474 - ).css({'display':'inline'}
475 - ).click(function(){
476 - _this.selectByUrl();
477 - });
 518+ _this.basefogg_bindControls();
 519+
 520+ // Show the select by URL if present
 521+ /*$j( this.target_btn_select_url ).unbind()
 522+ .attr( 'disabled', false )
 523+ .css( { 'display': 'inline' } )
 524+ .click( function() {
 525+ _this.selectSourceUrl();
 526+ });
478527 */
479528
 529+ // Hide the base advanced controls until a file is selected:
 530+ $j( this.target_control_container ).hide();
480531
481 - //hide the base advanced controls untill a file is selected:
482 - $j(this.target_control_container).hide();
483 -
484532 var helpState = {};
485 - //do some display tweeks:
486 - js_log('tw:' + $j(this.selector).width() +
487 - 'ssf:' + $j(this.target_btn_select_new_file).width() +
488 - 'sf:' + $j(this.target_btn_save_local_file).width() );
 533+ // Do some display tweaks
 534+ js_log( 'tw:' + $j( this.selector ).width() +
 535+ ' ssf:' + $j( this.target_btn_select_new_file ).width() +
 536+ ' sf:' + $j( this.target_btn_save_local_file ).width() );
489537
490 - //set width to 250
491 - $j(this.target_input_file_name).width( 250 );
 538+ // Set width to 250
 539+ $j( this.target_input_file_name ).width( 250 );
492540
493 - //special preset action:
494 - $j(this.selector + ' ._preset_select').change(function(){
495 - _this.updatePresetSelection( $j(this).val() );
 541+ // Special preset action
 542+ $j( this.selector + ' ._preset_select' ).change( function() {
 543+ _this.updatePresetSelection( $j( this ).val() );
496544 });
497545
498 - //bind control actions
499 - for(var cK in this.default_encoder_config){
500 - var cConf = this.default_encoder_config[cK];
501 -
502 - //initial state is hidden:
503 - $j( this.selector + ' .helpRow_' + cK).hide();
504 - $j(this.selector + ' .help_' + cK).click(function(){
505 - //get the ckId (assume its the last class)
506 - var cK = _this.getClassId(this, 'help_');
 546+ // Bind control actions
 547+ for ( var configKey in this.default_encoder_config ) {
 548+ var confEntry = this.default_encoder_config[configKey];
507549
508 - if(helpState[cK]){
509 - $j(_this.selector + ' .helpRow_' + cK).hide('slow');
510 - helpState[cK] = false;
511 - }else{
512 - $j(_this.selector + ' .helpRow_' + cK).show('slow');
513 - helpState[cK] = true;
514 - }
515 - return false;
516 - }).hover(
517 - function(){
518 - //get the ckId (assume its the last class)
519 - var cK = _this.getClassId(this, 'help_');
520 - $j( _this.selector + ' .helpRow_' + cK).show('slow');
521 - },function(){
522 - var cK = _this.getClassId(this, 'help_');
523 - if(!helpState[cK])
524 - $j( _this.selector + ' .helpRow_' + cK).hide('slow')
525 - }
526 - );
527 - $j( _this.selector + ' .helpClose_' + cK).click(function(){
528 - js_log("close help: " +cK);
529 - //get the ckId (assume its the last class)
530 - var cK = _this.getClassId(this, 'helpClose_');
531 - $j(_this.selector + ' .helpRow_' + cK).hide('slow');
532 - helpState[cK] = false;
533 - return false;
534 - }).css('cursor', 'pointer');
 550+ // Initial state is hidden
 551+ $j( this.selector + ' .helpRow_' + configKey ).hide();
535552
536 - //setup bindings for change values: (validate input)
537 -
538 - switch( cConf.type ){
 553+ $j( this.selector + ' .help_' + configKey )
 554+ .click(
 555+ function() {
 556+ // Get the config key (assume it's the last class)
 557+ var configKey = _this.getClassId( this, 'help_' );
 558+
 559+ if ( helpState[configKey] ) {
 560+ $j( _this.selector + ' .helpRow_' + configKey ).hide( 'slow' );
 561+ helpState[configKey] = false;
 562+ } else {
 563+ $j( _this.selector + ' .helpRow_' + configKey ).show( 'slow' );
 564+ helpState[configKey] = true;
 565+ }
 566+ return false;
 567+ }
 568+ )
 569+ .hover(
 570+ function() {
 571+ // get the config key (assume it's the last class)
 572+ var configKey = _this.getClassId( this, 'help_' );
 573+ $j( _this.selector + ' .helpRow_' + configKey ).show( 'slow' );
 574+ },
 575+ function() {
 576+ var configKey = _this.getClassId( this, 'help_' );
 577+ if( !helpState[configKey] )
 578+ $j( _this.selector + ' .helpRow_' + configKey ).hide( 'slow' )
 579+ }
 580+ );
 581+
 582+ $j( this.selector + ' .helpClose_' + configKey )
 583+ .click(
 584+ function() {
 585+ js_log( "close help: " + configKey );
 586+ // get the config key (assume it's the last class)
 587+ var configKey = _this.getClassId( this, 'helpClose_' );
 588+ $j( _this.selector + ' .helpRow_' + configKey ).hide( 'slow' );
 589+ helpState[configKey] = false;
 590+ return false;
 591+ }
 592+ )
 593+ .css( 'cursor', 'pointer' );
 594+
 595+ // Set up bindings for the change events (validate input)
 596+
 597+ switch ( confEntry.type ) {
539598 case 'boolean':
540 - $j(_this.selector + ' ._'+cK).click(function(){
541 - _this.updateLocalValue( _this.getClassId(this), $j(this).is(":checked") );
542 - _this.updatePresetSelection('custom');
543 - })
544 - break;
 599+ $j( this.selector + ' ._' + configKey)
 600+ .click( function() {
 601+ _this.updateLocalValue( _this.getClassId( this ),
 602+ $j( this ).is( ":checked" ) );
 603+ _this.updatePresetSelection( 'custom' );
 604+ });
 605+ break;
545606 case 'select':
546607 case 'string':
547608 case 'int':
548609 case 'float':
549610 //@@check if we have a validate function on the string
550 - $j(_this.selector + ' ._'+cK).change(function(){
551 - $j(this).val( _this.updateLocalValue(
552 - _this.getClassId(this),
553 - $j(this).val() ));
554 - _this.updatePresetSelection('custom');
 611+ $j( this.selector + ' ._' + configKey ).change( function() {
 612+ $j( this ).val( _this.updateLocalValue(
 613+ _this.getClassId( this ),
 614+ $j( this ).val() ) );
 615+ _this.updatePresetSelection( 'custom' );
555616 })
556 - break;
 617+ break;
557618 case 'date':
558 - $j(_this.selector + ' ._'+cK).datepicker({
 619+ $j( this.selector + ' ._' + configKey ).datepicker({
559620 changeMonth: true,
560621 changeYear: true,
561622 dateFormat: 'd MM, yy',
562 - onSelect: function(dateText) {
563 - _this.updateInterfaceValue(_this.getClassId(this), dateText);
 623+ onSelect: function( dateText ) {
 624+ _this.updateInterfaceValue( _this.getClassId( this ), dateText );
564625 }
565626 });
566 - break;
 627+ break;
567628 case 'slider':
568 - $j(this.selector + ' .slider_' + cK ).slider({
 629+ var sliderId = _this.getClassId( this, 'slider_' );
 630+ $j( this.selector + ' .slider_' + configKey ).slider({
569631 range: "min",
570632 animate: true,
571 - step: (cConf.step)?cConf.step:1,
572 - value: $j( this.selector +' ._' + cK ).val(),
573 - min: this.default_encoder_config[ cK ].range.min,
574 - max: this.default_encoder_config[ cK ].range.max,
575 - slide: function(event, ui) {
576 - $j( _this.selector + ' ._' + _this.getClassId(this, 'slider_') ).val( ui.value );
577 -
578 - //maintain source video aspect ratio:
579 - if(_this.getClassId(this, 'slider_') == 'width'){
580 - var hv = parseInt((_this.sourceFileInfo.video[0]['height']/_this.sourceFileInfo.video[0]['width'])* ui.value );
581 - //update the height value: the new height value is > that original the slider:
582 - if(hv > _this.updateInterfaceValue('height', hv))
 633+ step: confEntry.step ? confEntry.step : 1,
 634+ value: $j( this.selector + ' ._' + configKey ).val(),
 635+ min: this.default_encoder_config[ configKey ].range.min,
 636+ max: this.default_encoder_config[ configKey ].range.max,
 637+ slide: function( event, ui ) {
 638+ $j( _this.selector + ' ._' + sliderId ).val( ui.value );
 639+
 640+ // Maintain source video aspect ratio
 641+ if ( sliderId == 'width' ) {
 642+ var sourceHeight = _this.sourceFileInfo.video[0]['height'];
 643+ var sourceWidth = _this.sourceFileInfo.video[0]['width'];
 644+ var newHeight = parseInt( sourceHeight / sourceWidth * ui.value );
 645+ // Reject the update if the new height is above the maximum
 646+ if ( newHeight > _this.updateInterfaceValue( 'height', newHeight ) )
583647 return false;
584648 }
585 - if(_this.getClassId(this, 'slider_') == 'height'){
586 - var wv = parseInt((_this.sourceFileInfo.video[0]['width']/_this.sourceFileInfo.video[0]['height'])* ui.value );
587 - //update the height value: the new height value is > that original the slider:
588 - if(wv > _this.updateInterfaceValue('width', wv))
 649+ if ( sliderId == 'height' ) {
 650+ var sourceHeight = _this.sourceFileInfo.video[0]['height'];
 651+ var sourceWidth = _this.sourceFileInfo.video[0]['width'];
 652+ var newWidth = parseInt( sourceWidth / sourceHeight * ui.value );
 653+ // Reject the update if the new width is above the maximum
 654+ if ( newWidth > _this.updateInterfaceValue( 'width', wv ) )
589655 return false;
590656 }
591657 },
592 - change: function(event, ui){
593 - //update the local settings
594 - _this.updateLocalValue( _this.getClassId(this, 'slider_'), ui.value);
595 - _this.updatePresetSelection('custom');
 658+ change: function( event, ui ) {
 659+ _this.updateLocalValue( sliderId, ui.value );
 660+ _this.updatePresetSelection( 'custom' );
596661 }
597 - })
598 - $j( this.selector +' ._' + cK).change(function(){
599 - var scid = _this.getClassId(this);
600 - var valdVal = _this.updateLocalValue(scid.substr(1),$j(this).val() );
601 - _this.updatePresetSelection('custom');
602 - //(validate user form input)
603 - $j(this).val(valdVal);
604 - //update the slider
605 - js_log("update: " + _this.selector + ' .slider' + scid);
606 - $j(_this.selector + ' .slider'+ scid).slider('option', 'value', valdVal );
607662 });
608 - break
 663+
 664+ $j( this.selector + ' ._' + configKey ).change( function() {
 665+ var classId = _this.getClassId( this );
 666+ var validValue = _this.updateLocalValue( classId.substr( 1 ),
 667+ $j( this ).val() );
 668+ _this.updatePresetSelection( 'custom' );
 669+ // Change it to the validated value
 670+ $j( this ).val( validValue );
 671+ // update the slider
 672+ js_log( "update: " + _this.selector + ' .slider' + classId );
 673+ $j( _this.selector + ' .slider' + classId )
 674+ .slider( 'option', 'value', validValue );
 675+ });
 676+ break;
609677 }
610678 }
611 -
612 - $j(this.target_control_container).accordion({
 679+
 680+ $j( this.target_control_container ).accordion({
613681 header: "h3",
614682 collapsible: true,
615683 active: false,
616684 fillSpace: true
617685 });
618686
619 - //do config value updates if any
 687+ // Do the config value updates if there are any
620688 this.updateValuesInHtml();
621689 },
622 - updatePresetSelection:function( pKey ){
623 - //update the local key:
624 - this.local_settings.d = pKey;
625 - //js_log('update preset desc: '+ pKey);
626 - var pset_desc = '';
627 - if(this.local_settings.pSet[ pKey ].desc){
628 - pset_desc = this.local_settings.pSet[ pKey ].desc;
629 - }else{
630 - pset_desc = gM('fogg-preset-'+ pKey);
 690+
 691+ /**
 692+ * Update the UI due to a change in preset
 693+ */
 694+ updatePresetSelection: function( presetKey ) {
 695+ // Update the local configuration
 696+ this.local_settings['default'] = presetKey;
 697+ // js_log( 'update preset desc: ' + presetKey );
 698+ var presetDesc = '';
 699+ if ( this.local_settings.presets[presetKey].desc ) {
 700+ presetDesc = this.local_settings.presets[presetKey].desc;
 701+ } else {
 702+ presetDesc = gM( 'fogg-preset-' + presetKey );
631703 }
632 - //update the preset title:
633 - $j( this.selector + ' .gd_preset' ).html(
634 - gM('fogg-cg-preset', pset_desc)
635 - );
636 - //update the selector
637 - $j(this.selector + ' ._preset_select').val(pKey);
 704+ // Update the preset title
 705+ $j( this.selector + ' .gd_preset' )
 706+ .html( gM( 'fogg-cg-preset', presetDesc ) );
 707+ // update the selector
 708+ $j( this.selector + ' ._preset_select' ).val( presetKey );
638709 },
 710+
639711 /*
640 - * updates the interface
 712+ * Update the interface due to a change in a particular config key
641713 */
642 - updateInterfaceValue:function(confKey, val){
 714+ updateInterfaceValue: function( confKey, val ) {
643715 var _this = this;
644 - if(!val){
645 - return ;
 716+ if ( !val ) {
 717+ return;
646718 }
647 - //js_log('updateInterfaceValue:: ' + confKey + ' v:' + val + ' cv:'+ _this.selector + '._'+ confKey+' len:' + $j(_this.selector + ' ._'+confKey).length );
648 - //lookup the type
649 - if(typeof this.default_encoder_config[confKey] == 'undefined'){
650 - js_error('error: missing default key: '+ confKey);
 719+ // Look up the type
 720+ if ( typeof this.default_encoder_config[confKey] == 'undefined' ) {
 721+ js_error( 'error: missing default key: ' + confKey );
651722 return false;
652723 }
653724
654 - //update the local value (if not already up-to-date
655 - if( this.local_settings.pSet['custom']['conf'][confKey] != val ){
656 - val = this.updateLocalValue(confKey, val);
 725+ // Update the local value (if it's not already up-to-date)
 726+ if ( this.local_settings.presets['custom']['conf'][confKey] != val ) {
 727+ val = this.updateLocalValue( confKey, val );
657728 }
658 - //update the text filed:
659 - $j(_this.selector + ' ._'+confKey).val( val );
660 - //update the interaface widget:
661 - switch(this.default_encoder_config[confKey].type){
 729+ // Update the text field
 730+ $j( _this.selector + ' ._' + confKey ).val( val );
 731+ // Update the interface widget
 732+ switch ( this.default_encoder_config[confKey].type ) {
662733 case 'slider':
663 - $j(_this.selector + ' .slider_' + confKey).slider('option',
664 - 'value', $j(_this.selector + ' ._'+ confKey).val() );
665 - break;
 734+ $j( _this.selector + ' .slider_' + confKey )
 735+ .slider( 'option', 'value', $j( _this.selector + ' ._' + confKey ).val() );
 736+ break;
666737 }
667738 return val;
668739 },
669 - updateLocalValue:function(confKey, value){
670 - //update the local value (return the value we acutally set)
671 - if(typeof this.default_encoder_config[confKey] == 'undefined'){
672 - js_log("Error:could not update conf key:" + confKey)
673 - return value;
 740+
 741+ /**
 742+ * Validate the new config setting, fixing its type and bounding it within a
 743+ * range if required. Update the configuration with the validated value and
 744+ * return it.
 745+ */
 746+ updateLocalValue: function( confKey, value ) {
 747+ if ( typeof this.default_encoder_config[confKey] == 'undefined' ) {
 748+ js_log( "Error: could not update conf key: " + confKey )
 749+ return value;
674750 }
675 - dec = this.default_encoder_config[confKey];
676 - if(dec.range){
677 - value = parseInt(value);
678 - var min = ( dec.range.local_min) ? dec.range.local_min :dec.range.min;
679 - if(value < min)
 751+ var confEntry = this.default_encoder_config[confKey];
 752+ var range = confEntry.range;
 753+ if ( range ) {
 754+ value = parseInt( value );
 755+ var min = ( range.local_min ) ? range.local_min : range.min;
 756+ if ( value < min )
680757 value = min;
681 - var max = ( dec.range.local_max) ? dec.range.local_max : dec.range.max
682 - if(value > max)
 758+ var max = ( range.local_max ) ? range.local_max : range.max;
 759+ if (value > max )
683760 value = max;
684761 }
685 - if(dec.type=='int')
686 - value = parseInt(value);
 762+ if ( confEntry.type == 'int' )
 763+ value = parseInt( value );
687764
688 - //step value:
689 - /*if(dec.step){
690 - if((value % dec.step)!=0){
691 - value = value - (value % dec.step);
 765+ // step value:
 766+ /* if( confEntry.step ) {
 767+ if ( ( value % confEntry.step ) != 0 ) {
 768+ value = value - (value % confEntry.step);
692769 }
693770 }*/
694771
695 - js_log('update:local_settings:custom:conf:'+ confKey + ' = ' + value);
696 - this.local_settings.pSet['custom']['conf'][confKey] = value;
 772+ js_log( 'update:local_settings:custom:conf:' + confKey + ' = ' + value );
 773+ this.local_settings.presets['custom']['conf'][confKey] = value;
697774
698775 return value;
699776 },
700 - getLocalValue:function(confKey){
701 - return this.local_settings.pSet['custom']['conf'][confKey];
 777+
 778+ /**
 779+ * Get a local config value from the custom preset
 780+ */
 781+ getLocalValue: function( confKey ) {
 782+ return this.local_settings.presets['custom']['conf'][confKey];
702783 },
703 - getClassId:function(elm, rmstr){
704 - var elmclass = $j(elm).attr("class").split(' ').slice(0,1).toString();
705 - if(rmstr){
706 - return elmclass.replace( rmstr, '' );
707 - }else{
708 - //strip leading underscore:
709 - return (elmclass[0]=='_')?elmclass.substr(1):elmclass;
 784+
 785+ /**
 786+ * Given an element or selector, get its primary class, and strip a given
 787+ * prefix from it.
 788+ *
 789+ * If no prefix is given, "_" is assumed.
 790+ */
 791+ getClassId: function( element, prefix ) {
 792+ var eltClass = $j( element ).attr( "class" ).split( ' ' ).slice( 0, 1 ).toString();
 793+
 794+ if ( !prefix ) {
 795+ prefix = '_';
710796 }
 797+ if ( eltClass.substr( 0, prefix.length ) == prefix ) {
 798+ eltClass = eltClass.substr( prefix.length );
 799+ }
 800+ return eltClass;
711801 },
712 - /*
713 - * sets up the autoEncoder settings
 802+
 803+ /**
 804+ * Get the appropriate encoder settings for the current Firefogg object,
 805+ * into which a video has already been selected. Overrides the base method.
714806 */
715 - autoEncoderSettings:function(){
716 - var _this = this;
717 - //do the base encoder settings setup:
718 - this.basefogg_autoEncoderSettings();
719 -
720 - //special case see if we already have ogg video in adv encoder expose encode settings anyway:
721 - if( _this.isOggFormat() ){
722 - _this.encoder_settings['passthrough'] = false;
 807+ getEncoderSettings: function() {
 808+ if ( this.current_encoder_settings != null ) {
 809+ return this.current_encoder_settings;
723810 }
724 -
725 - //make sure we are "encoding" if not display not a video file eror:
726 - if( this.encoder_settings['passthrough'] ){
727 - js_log("in passthrough mode (hide control)");
728 - //hide all controls
729 - //display not encodable video
730 - $j(this.target_control_container).hide('slow');
731 - $j(this.target_passthrough_mode).show('slow');
732 - return ;
 811+
 812+ // Call the base function
 813+ // Note that settings will be a reference and can be modified
 814+ var settings = this.basefogg_getEncoderSettings();
 815+
 816+ // Allow re-encoding of files that are already ogg (unlike in the base class)
 817+ if ( this.isOggFormat() ) {
 818+ settings['passthrough'] = false;
733819 }
734 - //restore display:
735 - $j(this.target_control_container).show('slow');
736 - $j(this.target_passthrough_mode).hide('slow');
 820+ },
737821
738 - //do setup settings based on local_settings /default_encoder_config with sourceFileInfo
739 - //see: http://firefogg.org/dev/sourceInfo_example.html
740 - var setValues = function(k, val, maxVal) {
741 - if( k !== false){
742 - //update the value if unset:
743 - _this.updateLocalValue(k, val);
 822+ /**
 823+ * Do the necessary UI updates due to the source file changing.
 824+ * Overrides the parent method.
 825+ */
 826+ updateSourceFileUI: function() {
 827+ var _this = this;
 828+
 829+ // Call the parent
 830+ _this.basefogg_updateSourceFileUI();
 831+
 832+ var settings = this.getEncoderSettings();
 833+ var fileInfo = this.getSourceFileInfo();
 834+
 835+ // In passthrough mode, hide encoder controls
 836+ if ( settings['passthrough'] ) {
 837+ js_log( "in passthrough mode (hide control)" );
 838+ $j( this.target_control_container ).hide( 'slow' );
 839+ $j( this.target_passthrough_mode ).show( 'slow' );
 840+ return;
 841+ }
 842+
 843+ // Show encoder controls
 844+ $j( this.target_control_container ).show( 'slow' );
 845+ $j( this.target_passthrough_mode ).hide( 'slow' );
 846+
 847+ // do set up settings based on local_settings /default_encoder_config with sourceFileInfo
 848+ // see: http://firefogg.org/dev/sourceInfo_example.html
 849+ var setValues = function( k, val, maxVal ) {
 850+ if ( k !== false ) {
 851+ // update the value if unset:
 852+ _this.updateLocalValue( k, val );
744853 }
745 - if( maxVal ){
746 - //update the local range:
747 - if(_this.default_encoder_config[k].range){
 854+ if ( maxVal ) {
 855+ // update the local range:
 856+ if ( _this.default_encoder_config[k].range ) {
748857 _this.default_encoder_config[k].range.local_max = maxVal;
749858 }
750859 }
751860 }
752 - //container level settings
753 - for(var i in this.sourceFileInfo){
754 - var val = this.sourceFileInfo[i];
 861+ // container level settings
 862+ for ( var i in fileInfo ) {
 863+ var val = fileInfo[i];
755864 var k = false;
756 - var maxVal= false;
757 - switch(i){
758 - //do nothing with these:
 865+ var maxVal = false;
 866+ switch ( i ) {
 867+ // do nothing with these:
759868 case 'bitrate':
760869 k = 'videoBitrate';
761 - maxVal = (val*2 > this.default_encoder_config[k])?this.default_encoder_config[k]:val*2;
762 - break;
 870+ if ( val * 2 > this.default_encoder_config[k] ) {
 871+ maxVal = this.default_encoder_config[k];
 872+ } else {
 873+ maxVal = val * 2;
 874+ }
 875+ break;
763876 }
764 - setValues(k, val, maxVal);
 877+ setValues( k, val, maxVal );
765878 }
766 - //video stream settings
767 - for(var i in this.sourceFileInfo.video[0]){
768 - var val = this.sourceFileInfo.video[0][i];
 879+ // video stream settings
 880+ for ( var i in fileInfo.video[0] ) {
 881+ var val = fileInfo.video[0][i];
769882 var k = false;
770883 var maxVal= false;
771 - switch(i){
 884+ switch( i ) {
772885 case 'width':
773886 case 'height':
774887 k = i;
775888 maxVal = val;
776 - break;
 889+ break;
777890 }
778 - setValues(k, val, maxVal);
 891+ setValues( k, val, maxVal );
779892 }
780 - //audio stream settings, assumes for now there is only one stream
781 - for(var i in this.sourceFileInfo.audio[0]){
782 - var val = this.sourceFileInfo.audio[0][i];
 893+ // audio stream settings, assumes for now thare is only one stream
 894+ for ( var i in fileInfo.audio[0] ) {
 895+ var val = fileInfo.audio[0][i];
783896 var k = false;
784 - var maxVal= false;
785 - switch(i){
 897+ var maxVal = false;
 898+ switch ( i ) {
786899 case 'bitrate':
787900 k = 'audioBitrate';
788 - maxVal = (val*2 > this.default_encoder_config[k])?this.default_encoder_config[k]:val*2;
789 - break;
 901+ if ( val * 2 > this.default_encoder_config[k] ) {
 902+ maxVal = this.default_encoder_config[k];
 903+ } else {
 904+ maxVal = val * 2;
 905+ }
 906+ break;
790907 }
791 - setValues(k, val, maxVal);
 908+ setValues( k, val, maxVal );
792909 }
793910
794 - //set all values to new default ranges & update slider:
795 - $j.each(this.default_encoder_config, function(inx, val){
796 - if($j(_this.selector + ' ._'+inx).length!=0){
797 - if(typeof val.range != 'undefined'){
798 - //udate slider range
799 - var new_max = (val.range.local_max)?val.range.local_max: val.range.max
800 - $j( _this.selector + ' .slider_'+inx).slider('option', 'max', new_max);
 911+ // set all values to new default ranges & update slider:
 912+ $j.each( this.default_encoder_config, function( inx, val ) {
 913+ if ( $j( _this.selector + ' ._' + inx ).length != 0 ) {
 914+ if ( typeof val.range != 'undefined' ) {
 915+ // update slider range
 916+ var new_max = (val.range.local_max) ? val.range.local_max : val.range.max
 917+ $j( _this.selector + ' .slider_' + inx ).slider( 'option', 'max', new_max );
801918
802 - //update slider/input value:
803 - _this.updateInterfaceValue(inx, _this.local_settings.pSet['custom']['conf'][inx]);
 919+ // update slider/input value:
 920+ _this.updateInterfaceValue( inx,
 921+ _this.local_settings.presets['custom']['conf'][inx] );
804922 }
805923 }
806924 });
807 - //update values
 925+ // update values
808926 this.updateValuesInHtml();
809927 },
810 - doEncode:function(){
811 - //update the encoder settings (from local settings)
812 - pKey = this.local_settings.d;
813 - this.encoder_settings = this.local_settings.pSet[ pKey ].conf;
 928+
 929+ doEncode: function() {
 930+ // update the encoder settings (from local settings)
 931+ pKey = this.local_settings['default'];
 932+ this.encoder_settings = this.local_settings.presets[ pKey ].conf;
814933 this.basefogg_doEncode();
815934 },
816 - updateValuesInHtml:function(){
817 - js_log('updateValuesInHtml::');
 935+
 936+ /**
 937+ * Set the HTML control values to whatever is currently present in this.local_settings
 938+ */
 939+ updateValuesInHtml: function() {
 940+ js_log( 'updateValuesInHtml::' );
818941 var _this = this;
819 - var pKey = this.local_settings.d;
 942+ var pKey = this.local_settings['default'];
820943 this.updatePresetSelection( pKey );
821944
822 - //set the actual HTML & widgets based on any local settings values:
823 - $j.each(_this.local_settings.pSet['custom']['conf'], function(inx, val){
824 - if($j(_this.selector + ' ._'+inx).length !=0){
825 - $j(_this.selector + ' ._'+inx).val( val );
 945+ // set the actual HTML & widgets based on any local settings values:
 946+ $j.each( _this.local_settings.presets['custom']['conf'], function( inx, val ) {
 947+ if ( $j( _this.selector + ' ._' + inx ).length != 0 ) {
 948+ $j( _this.selector + ' ._' + inx ).val( val );
826949 }
827950 });
828951 },
829 - //restors settings from a cookie if you have them)
830 - loadEncSettings:function( force ){
831 - if($j.cookie('fogg_encoder_config')){
832 - js_log("load:fogg_encoder_config from cookie ");
833 - this.local_settings = JSON.parse( $j.cookie('fogg_settings') );
 952+
 953+ /**
 954+ * Restore settings from a cookie (if available)
 955+ */
 956+ loadEncSettings: function( force ) {
 957+ if ( $j.cookie( 'fogg_encoder_config' ) ) {
 958+ js_log( "load:fogg_encoder_config from cookie " );
 959+ this.local_settings = JSON.parse( $j.cookie( 'fogg_settings' ) );
834960 }
835 - //set to default if not loaded yet:
836 - if( this.local_settings && this.local_settings.pSet && this.local_settings.pSet['custom']['conf']){
837 - js_log('local settings already populated');
838 - }else{
839 - this.local_settings = this.default_local_settings;
 961+ // set to default if not loaded yet:
 962+ if ( this.local_settings && this.local_settings.presets
 963+ && this.local_settings.presets['custom']['conf'] )
 964+ {
 965+ js_log( 'local settings already populated' );
 966+ } else {
 967+ this.local_settings = this.default_local_settings;
840968 }
 969+ },
841970
 971+ /**
 972+ * Clear preset settings
 973+ * FIXME: not called, does nothing
 974+ */
 975+ clearSettings: function( force ) {
842976 },
843 - //clear preset settings:
844 - clearSettings:function(force){
845977
846 - },
847 - //save settings to the cookie
848 - saveEncSettings:function(){
849 - $j.cookie('fogg_settings', JSON.stringify( this.local_settings ) );
 978+ /**
 979+ * Save the current encoder settings to a cookie.
 980+ */
 981+ saveEncSettings: function() {
 982+ $j.cookie( 'fogg_settings', JSON.stringify( this.local_settings ) );
850983 }
851984 };
Index: trunk/phase3/js2/mwEmbed/libAddMedia/mvFirefogg.js
@@ -1,5 +1,5 @@
2 -/* adds firefogg support.
3 -* autodetects: new upload api or old http POST.
 2+/* Firefogg support.
 3+ * autodetects: new upload api or old http POST.
44 */
55
66 loadGM({
@@ -7,11 +7,11 @@
88 "fogg-select_new_file" : "Select new file",
99 "fogg-select_url" : "Select URL",
1010 "fogg-save_local_file" : "Save Ogg",
11 - "fogg-check_for_fogg" : "Checking for Firefogg...",
 11+ "fogg-check_for_firefogg" : "Checking for Firefogg...",
1212 "fogg-installed" : "Firefogg is installed",
13 - "fogg-for_improved_uplods" : "For improved uploads:",
 13+ "fogg-for_improved_uploads" : "For improved uploads:",
1414 "fogg-please_install" : "<a href=\"$1\">Install Firefogg<\/a>. More <a href=\"http:\/\/commons.wikimedia.org\/wiki\/Commons:Firefogg\">about Firefogg<\/a>.",
15 - "fogg-use_latest_fox" : "Please first install <a href=\"http:\/\/www.mozilla.com\/en-US\/firefox\/upgrade.html?from=firefogg\">Firefox 3.5<\/a> (or later). <i>Then revisit this page to install the <b>Firefogg<\/b> extension.<\/i>",
 15+ "fogg-use_latest_firefox" : "Please first install <a href=\"http:\/\/www.mozilla.com\/en-US\/firefox\/upgrade.html?from=firefogg\">Firefox 3.5<\/a> (or later). <i>Then revisit this page to install the <b>Firefogg<\/b> extension.<\/i>",
1616 "fogg-passthrough_mode" : "Your selected file is already Ogg or not a video file",
1717 "fogg-transcoding" : "Encoding video to Ogg...",
1818 "fogg-encoding-done" : "Encoding complete",
@@ -20,599 +20,876 @@
2121 "fogg-hidepreview" : "Hide preview"
2222 });
2323
24 -var firefogg_install_links = {
25 - 'macosx': 'http://firefogg.org/macosx/Firefogg.xpi',
26 - 'win32': 'http://firefogg.org/win32/Firefogg.xpi',
27 - 'linux' : 'http://firefogg.org/linux/Firefogg.xpi'
 24+var firefogg_install_links = {
 25+ 'macosx': 'http://firefogg.org/macosx/Firefogg.xpi',
 26+ 'win32': 'http://firefogg.org/win32/Firefogg.xpi',
 27+ 'linux': 'http://firefogg.org/linux/Firefogg.xpi'
2828 };
2929
3030 var default_firefogg_options = {
31 - // What to do when finished uploading
32 - 'done_upload_cb':false,
33 - // If firefoog is enabled
34 - 'fogg_enabled':false,
35 - // The api url to upload to
36 - 'api_url':null,
37 - // The passthrough flag (enables un-modified uploads)
 31+ // Callback for upload completion
 32+ 'done_upload_cb': false,
 33+
 34+ // True if Firefogg is enabled in the client
 35+ 'have_firefogg': false,
 36+
 37+ // The API URL to upload to
 38+ 'api_url': null,
 39+
 40+ // True when a file is uploaded without re-encoding
3841 'passthrough': false,
39 - // If we will be showing the encoder interface
 42+
 43+ // True if we will be showing the encoder interface
4044 'encoder_interface': false,
41 - // If we want to limit the library functionality to "only firefoog" (no upload or progress bars)
42 - 'only_fogg': false,
4345
44 - // Callbacks:
45 - 'new_source_cb': false, //called on source name update passes along source name
 46+ // True if we want to limit the library functionality to "only firefogg"
 47+ // (no upload or progress bars)
 48+ 'only_firefogg': false,
4649
47 - // Target control container or form (can't be left null)
 50+ // Callback which is called when the source name changes
 51+ 'new_source_cb': false,
 52+
 53+ // CSS selector identifying the target control container or form (can't be left null)
4854 'selector': '',
4955
50 - // If not rewriting a form we are encoding local.
51 - 'form_rewrite': false,
 56+ // May be "upload" to if we are rewriting an upload form, or "local" if we are encoding a local file
 57+ 'form_type': 'local',
5258
53 - // Target buttons:
 59+ // CSS selector for the select file button
5460 'target_btn_select_file': false,
 61+
 62+ // CSS selector for the select new file button
5563 'target_btn_select_new_file': false,
5664
57 - //'target_btn_select_url': false,
 65+ // CSS selector for the save local file button
5866 'target_btn_save_local_file': false,
 67+
 68+ // CSS selector for the input file name button
5969 'target_input_file_name': false,
6070
 71+ // CSS selector for the "checking for firefogg..." message div
 72+ 'target_check_for_firefogg': false,
6173
62 - // Target install descriptions
63 - 'target_check_for_fogg': false,
 74+ // CSS selector for the "firefogg is installed" message div
6475 'target_installed': false,
 76+
 77+ // CSS selector for the "please install firefogg" message div
6578 'target_please_install': false,
66 - 'target_use_latest_fox': false,
67 -
68 - // Status:
69 - 'target_passthrough_mode':false,
7079
71 - // If firefogg should take over the form submit action
72 - 'firefogg_form_action':true,
73 -
74 - // If we should show a preview of encoding progress
75 - 'show_preview':false
76 -}
 80+ // CSS selector for the "please use Firefox 3.5" message div
 81+ 'target_use_latest_firefox': false,
7782
 83+ // CSS selector for the message div warning that passthrough mode is enabled
 84+ 'target_passthrough_mode': false,
7885
79 -var mvFirefogg = function(iObj){
80 - return this.init( iObj );
81 -}
82 -mvFirefogg.prototype = { //extends mvBaseUploadInterface
 86+ // True if firefogg should take over the form submit action
 87+ 'firefogg_form_action': true,
8388
84 - min_firefogg_version : '0.9.9.5',
85 - fogg_enabled : false, //if firefogg is enabled or not.
86 - encoder_settings:{ //@@todo allow server to set this
 89+ // True if we should show a preview of the encoding progress
 90+ 'show_preview': false
 91+};
 92+
 93+
 94+var mvFirefogg = function( options ) {
 95+ return this.init( options );
 96+};
 97+
 98+mvFirefogg.prototype = { // extends mvBaseUploadInterface
 99+ min_firefogg_version: '0.9.9.5',
 100+ default_encoder_settings: { // @@todo allow the server to set these
87101 'maxSize' : '400',
88102 'videoBitrate' : '544',
89103 'audioBitrate' : '96',
90104 'noUpscaling' : true
91105 },
92 - sourceFileInfo: {},
93 - ogg_extensions: ['ogg', 'ogv', 'oga'],
94 - video_extensions: ['avi', 'mov', 'mp4', 'mp2', 'mpeg', 'mpeg2', 'mpeg4', 'dv', 'wmv'],
 106+ have_firefogg: null, // lazy initialised, use getFirefogg()
 107+ current_encoder_settings: null, // lazy initialised, use getEncoderSettings()
 108+ sourceFileInfo: null, // lazy initialised, use getSourceFileInfo()
 109+ ogg_extensions: [ 'ogg', 'ogv', 'oga' ],
 110+ video_extensions: [ 'avi', 'mov', 'mp4', 'mp2', 'mpeg', 'mpeg2', 'mpeg4', 'dv', 'wmv' ],
95111
96112 passthrough: false,
97113 sourceMode: 'file',
98114
99 - init: function( iObj ){
100 - if(!iObj)
101 - iObj = {};
 115+ /**
 116+ * Object initialisation
 117+ */
 118+ init: function( options ) {
 119+ if ( !options )
 120+ options = {};
102121
103 - // If we have no api_url set upload to "post"
104 - if(!iObj.api_url)
105 - iObj.upload_mode = 'post';
 122+ // If we have no api_url, set upload mode to "post"
 123+ if ( !options.api_url )
 124+ options.upload_mode = 'post';
106125
107 - // Inherit iObj properties:
108 - for(var i in default_firefogg_options){
109 - if(iObj[i]){
110 - this[i] = iObj[i];
111 - }else{
 126+ // Set options
 127+ for ( var i in default_firefogg_options ) {
 128+ if ( options[i] ) {
 129+ this[i] = options[i];
 130+ } else {
112131 this[i] = default_firefogg_options[i];
113132 }
114133 }
115 - // Check if we want to limit the usage:
116 - if(!this.only_fogg){
117 - var myBUI = new mvBaseUploadInterface( iObj );
118134
119 - // Standard extends code:
120 - for(var i in myBUI){
121 - if(this[i]){
 135+ // Inherit from mvBaseUploadInterface (unless we're in only_firefogg mode)
 136+ if ( !this.only_firefogg ) {
 137+ var myBUI = new mvBaseUploadInterface( options );
 138+
 139+ // Prefix conflicting members with pe_
 140+ for ( var i in myBUI ) {
 141+ if ( this[i] ) {
122142 this['pe_'+ i] = myBUI[i];
123 - }else{
 143+ } else {
124144 this[i] = myBUI[i];
125145 }
126146 }
127147 }
128148
129 - if(!this.selector){
 149+ if ( !this.selector ) {
130150 js_log('firefogg: missing selector ');
131151 }
132152 },
133 - doRewrite:function( callback ){
 153+
 154+ /**
 155+ * Rewrite the upload form, or create our own upload controls for local transcoding.
 156+ * Called from $j.firefogg(), in mv_embed.js.
 157+ */
 158+ doRewrite: function( callback ) {
134159 var _this = this;
135 - js_log('sel len: ' + this.selector + '::' + $j(this.selector).length + ' tag:'+ $j(this.selector).get(0).tagName);
136 - if( $j(this.selector).length >=0 ){
137 -
138 - if( $j(this.selector).get(0).tagName.toLowerCase() == 'input' ){
139 - _this.form_rewrite = true;
 160+ js_log( 'sel len: ' + this.selector + '::' + $j( this.selector ).length +
 161+ ' tag:' + $j( this.selector ).get( 0 ).tagName );
 162+ if ( $j( this.selector ).length >= 0 ) {
 163+ if ( $j( this.selector ).get( 0 ).tagName.toLowerCase() == 'input' ) {
 164+ _this.form_type = 'upload';
140165 }
141166 }
142 - // Check if we are rewriting an input or a form:
143 - if( this.form_rewrite ){
 167+ if ( this.form_type == 'upload' ) {
 168+ // Initialise existing upload form
144169 this.setupForm();
145 - }else{
146 - this.doControlHTML();
147 - this.doControlBindings();
 170+ } else {
 171+ // Create our own form controls
 172+ this.createControls();
 173+ this.bindControls();
148174 }
149175
150 - // doRewrite is done:
151 - if(callback)
 176+ if ( callback )
152177 callback();
153178 },
154 - doControlHTML: function( ){
 179+
 180+ /**
 181+ * Create controls for local transcoding and add them to the page
 182+ */
 183+ createControls: function() {
155184 var _this = this;
156185 var out = '';
157 - $j.each(default_firefogg_options, function(target, na){
158 - if(target.substring(0, 6)=='target'){
159 - //js_log('check for target html: ' + target);
160 - // Check for the target if missing add to the output:
161 - if( _this[target] === false){
162 - out += _this.getTargetHtml(target) + ' ';
 186+ $j.each( default_firefogg_options, function( target, na ) {
 187+ if ( /^target/.test( target ) ) {
 188+ // Create the control if it doesn't already exist
 189+ if( _this[target] === false ) {
 190+ out += _this.getControlHtml(target) + ' ';
163191 // Update the target selector
164 - _this[target] = _this.selector + ' .' + target;
 192+ _this[target] = _this.selector + ' .' + target;
165193 }
166194 }
167195 });
168196 $j( this.selector ).append( out ).hide();
169197 },
170 - getTargetHtml:function(target){
171 - if( target.substr(7,3)=='btn'){
172 - return '<input style="" class="' + target + '" type="button" value="' + gM( 'fogg-' + target.substring(11)) + '"/> ';
173 - }else if(target.substr(7,5)=='input'){
174 - return '<input style="" class="' + target + '" type="text" value="' + gM( 'fogg-' + target.substring(11)) + '"/> ';
175 - }else{
176 - return '<div style="" class="' + target + '" >'+ gM('fogg-'+ target.substring(7)) + '</div> ';
 198+
 199+ /**
 200+ * Get the HTML for the control with a particular name
 201+ */
 202+ getControlHtml: function( target ) {
 203+ if ( /^target_btn_/.test( target ) ) {
 204+ // Button
 205+ var msg = gM( target.replace( /^target_btn_/, 'fogg-' ) );
 206+ return '<input style="" ' +
 207+ 'class="' + target + '" ' +
 208+ 'type="button" ' +
 209+ 'value="' + msg + '"/> ';
 210+ } else if ( /^target_input_/.test( target ) ) {
 211+ // Text input
 212+ var msg = gM( target.replace( /^target_input_/, 'fogg-' ) );
 213+ return '<input style="" ' +
 214+ 'class="' + target + '" ' +
 215+ 'type="text" ' +
 216+ 'value="' + msg + '"/> ';
 217+ } else if ( /^target_/.test( target ) ) {
 218+ // Message
 219+ var msg = gM( target.replace( '/^target_/', 'fogg-' ) );
 220+ return '<div style="" class="' + target + '" >' + msg + '</div> ';
 221+ } else {
 222+ js_error( 'Invalid target: ' + target );
 223+ return '';
177224 }
178225 },
179 - doControlBindings: function(){
 226+
 227+ /**
 228+ * Set up events for the controls which were created with createControls()
 229+ */
 230+ bindControls: function() {
180231 var _this = this;
181232
182 - // Hide all targets:
183 - var hide_target_list='';
184 - var coma='';
185 - $j.each( default_firefogg_options, function(target, na) {
186 - if(target.substring(0, 6)=='target'){
187 - hide_target_list+=coma + _this[target];
188 - coma=',';
 233+ // Hide all controls
 234+ var hide_target_list = '';
 235+ var comma = '';
 236+ $j.each( default_firefogg_options, function( target, na ) {
 237+ if ( /^target/.test( target ) ) {
 238+ hide_target_list += comma + _this[target];
 239+ comma = ',';
189240 }
190241 });
191 -
192 - // Hide all but check-for-fogg
193242 $j( hide_target_list ).hide();
194 - // Now that the proper set of items has been hiiden show:
 243+
 244+ // Now show the form
195245 $j( _this.selector ).show();
196 -
197 - // Check for firefogg
198 - if( _this.firefoggCheck() ){
199246
200 - // If rewriting the form lets keep the text input around:
201 - if( _this.form_rewrite )
 247+ if ( _this.firefoggCheck() ) {
 248+ // Firefogg enabled
 249+ // If we're in upload mode, show the input filename
 250+ if ( _this.form_type == 'upload' )
202251 $j( _this.target_input_file_name ).show();
203252
204 - // Show select file:
205 - $j( this.target_btn_select_file ).unbind(
206 - ).attr('disabled', false
207 - ).css({'display':'inline'}
208 - ).click(function(){
209 - _this.selectFogg();
 253+ // Show the select file button
 254+ $j( this.target_btn_select_file )
 255+ .unbind()
 256+ .attr( 'disabled', false )
 257+ .css( { 'display': 'inline' } )
 258+ .click( function() {
 259+ _this.selectSourceFile();
 260+ } );
 261+
 262+ // Set up the click handler for the filename box
 263+ $j( this.target_input_file_name )
 264+ .unbind()
 265+ .attr( 'readonly', 'readonly' )
 266+ .click( function() {
 267+ _this.selectSourceFile();
210268 });
 269+ } else {
 270+ // Firefogg disabled
 271+ // FIXME: move this elsewhere. None of this is related to binding.
211272
212 - //also setup the text file display on Click to select file:
213 - $j(this.target_input_file_name).unbind().attr('readonly', 'readonly').click(function(){
214 - _this.selectFogg();
215 - })
 273+ // Show the "use latest Firefox" message if necessary
 274+ if ( !( $j.browser.mozilla && $j.browser.version >= '1.9.1' ) ) {
 275+ js_log( 'show use latest::' + _this.target_use_latest_firefox );
 276+ if ( _this.target_use_latest_firefox ) {
 277+ if ( _this.form_type == 'upload' )
 278+ $j( _this.target_use_latest_firefox )
 279+ .prepend( gM( 'fogg-for_improved_uploads' ) );
216280
217 - }else{
218 - // First check firefox version:
219 - if(!( $j.browser.mozilla && $j.browser.version >= '1.9.1' )) {
220 - js_log( 'show use latest::' + _this.target_use_latest_fox );
221 - if( _this.target_use_latest_fox ){
222 - if( _this.form_rewrite )
223 - $j( _this.target_use_latest_fox ).prepend( gM('fogg-for_improved_uplods') );
224 -
225 - $j( _this.target_use_latest_fox ).show();
 281+ $j( _this.target_use_latest_firefox ).show();
226282 }
227 - return ;
 283+ return;
228284 }
229285
230 - // If rewriting form use upload msg text
231 - var upMsg = (_this.form_rewrite) ? gM('fogg-for_improved_uplods') : '';
232 - $j( _this.target_please_install ).html( upMsg + gM('fogg-please_install', _this.getOSlink() )).css('padding', '10px').show();
 286+ // Otherwise show the "install Firefogg" message
 287+ // FIXME: getFirefoggInstallUrl() may return false, this is not handled
 288+ var upMsg = ( _this.form_type == 'upload' ) ? gM( 'fogg-for_improved_uploads' ) : '';
 289+ $j( _this.target_please_install )
 290+ .html( upMsg + gM( 'fogg-please_install', _this.getFirefoggInstallUrl() ) )
 291+ .css( 'padding', '10px' )
 292+ .show();
233293 }
234 - // Setup the target save local file bindings:
235 - $j( _this.target_btn_save_local_file ).unbind().click(function(){
236 - _this.saveLocalFogg();
237 - });
 294+
 295+ // Set up the click handler for the "save local file" button
 296+ $j( _this.target_btn_save_local_file )
 297+ .unbind()
 298+ .click( function() {
 299+ _this.doLocalEncodeAndSave();
 300+ } );
238301 },
 302+
239303 /*
240 - * returns the firefogg link for your os:
 304+ * Get the URL for installing firefogg on the client OS
241305 */
242 - getOSlink:function(){
 306+ getFirefoggInstallUrl: function() {
243307 var os_link = false;
244 - if(navigator.oscpu){
245 - if(navigator.oscpu.search('Linux') >= 0)
 308+ if ( navigator.oscpu ) {
 309+ if ( navigator.oscpu.search( 'Linux' ) >= 0 )
246310 os_link = firefogg_install_links['linux'];
247 - else if(navigator.oscpu.search('Mac') >= 0)
248 - os_link = firefogg_install_links['macosx'];
249 - else if(navigator.oscpu.search('Win') >= 0)
250 - os_link = firefogg_install_links['win32'];
 311+ else if ( navigator.oscpu.search( 'Mac' ) >= 0 )
 312+ os_link = firefogg_install_links['macosx'];
 313+ else if (navigator.oscpu.search( 'Win' ) >= 0 )
 314+ os_link = firefogg_install_links['win32'];
251315 }
252 - return os_link
 316+ return os_link;
253317 },
254 - firefoggCheck:function(){
255 - if(typeof(Firefogg) != 'undefined' && Firefogg().version >= this.min_firefogg_version){
256 - this.fogg = new Firefogg();
257 - this.fogg_enabled = true;
258 - return true;
259 - }else{
260 - return false;
 318+
 319+ /**
 320+ * Get the Firefogg instance (or false if firefogg is unavailable)
 321+ */
 322+ getFirefogg: function() {
 323+ if ( this.have_firefogg == null ) {
 324+ if ( typeof( Firefogg ) != 'undefined'
 325+ && Firefogg().version >= this.min_firefogg_version )
 326+ {
 327+ this.have_firefogg = true;
 328+ this.fogg = new Firefogg();
 329+ } else {
 330+ this.have_firefogg = false;
 331+ this.fogg = false;
 332+ }
261333 }
 334+ return this.fogg;
262335 },
263 - // Assume input target
264 - setupForm: function(){
265 - js_log('firefogg::setupForm::');
266 - //to parent form setup if we want http updates
267 - if( this.form_rewrite ){
268 - //do parent form setup:
 336+
 337+ /**
 338+ * Set up the upload form
 339+ */
 340+ setupForm: function() {
 341+ js_log( 'firefogg::setupForm::' );
 342+
 343+ // Set up the parent if we are in upload mode
 344+ if ( this.form_type == 'upload' ) {
269345 this.pe_setupForm();
270346 }
271347
272 - // Check if we have firefogg (if not just add a link and stop processing)
273 - if( !this.firefoggCheck() ){
274 - //add some status indicators if not provided:
275 - if(!this.target_please_install){
276 - $j(this.selector).after ( this.getTargetHtml('target_please_install') );
 348+ // If Firefogg is not available, just show a "please install" message
 349+ if ( !this.firefoggCheck() ) {
 350+ if ( !this.target_please_install ) {
 351+ $j( this.selector ).after( this.getControlHtml( 'target_please_install' ) );
277352 this.target_please_install = this.selector + ' ~ .target_please_install';
278353 }
279 - if(!this.target_use_latest_fox){
280 - $j(this.selector).after ( this.getTargetHtml('target_use_latest_fox') );
281 - this.target_use_latest_fox = this.selector + ' ~ .target_use_latest_fox';
 354+ if ( !this.target_use_latest_firefox ) {
 355+ $j( this.selector ).after( this.getControlHtml( 'target_use_latest_firefox' ) );
 356+ this.target_use_latest_firefox = this.selector + ' ~ .target_use_latest_firefox';
282357 }
283 - // Update download link:
284 - this.doControlBindings();
285 - return ;
 358+ // Show download link
 359+ this.bindControls();
 360+ return;
286361 }
287362
288 - // Change the file browser to type text: (can't directly change input from "file" to "text" so longer way:
289 - var inTag = '<input ';
290 - $j.each($j(this.selector).get(0).attributes, function(i, attr){
 363+ // Change the file browser to type text. We can't simply change the attribute so
 364+ // we have to delete and recreate.
 365+ var inputTag = '<input ';
 366+ $j.each( $j( this.selector ).get( 0 ).attributes, function( i, attr ) {
291367 var val = attr.value;
292 - if( attr.name == 'type')
 368+ if ( attr.name == 'type' )
293369 val = 'text';
294 - inTag += attr.name + '="' + val + '" ';
295 - });
296 - if(!$j(this.selector).attr('style'))
297 - inTag += 'style="display:inline" ';
 370+ inputTag += attr.name + '="' + val + '" ';
 371+ } );
 372+ if ( !$j( this.selector ).attr( 'style' ) )
 373+ inputTag += 'style="display:inline" ';
298374
299 - inTag+= '/><span id="' + $j(this.selector).attr('name') + '_fogg-control"></span>';
 375+ var id = $j( this.selector ).attr( 'name' ) + '_firefogg-control';
 376+ inputTag += '/><span id="' + id + '"></span>';
300377
301 - js_log('set input: ' + inTag);
302 - $j(this.selector).replaceWith(inTag);
 378+ js_log( 'set input: ' + inputTag );
 379+ $j( this.selector ).replaceWith( inputTag );
303380
304 - this.target_input_file_name = 'input[name=' + $j(this.selector).attr('name') + ']';
305 -
306 - // Update the selector to the control target:
307 - this.selector = '#' + $j(this.selector).attr('name') + "_fogg-control";
 381+ this.target_input_file_name = 'input[name=' + $j( this.selector ).attr( 'name' ) + ']';
308382
309 - this.doControlHTML();
 383+ // Point the selector at the span we just created
 384+ this.selector = '#' + id;
310385
311 - // Update the bindings:
312 - this.doControlBindings();
 386+ // Create controls for local transcoding
 387+ this.createControls();
 388+ this.bindControls();
313389 },
314 - // Do firefogg specific additions:
315 - dispProgressOverlay:function(){
316 - this.pe_dispProgressOverlay();
317 - // If we are uploading video (not in passthrough mode show preview button)
318 - if( this.fogg_enabled && ! this.encoder_settings['passthrough'] && ! this.http_copy_upload ){
319 - this.doPreviewControl();
 390+
 391+ /**
 392+ * Display an upload progress overlay. Overrides the function in mvBaseUploadInterface.
 393+ */
 394+ displayProgressOverlay: function() {
 395+ this.pe_dispProgressOverlay();
 396+ // If we are uploading video (not in passthrough mode), show preview button
 397+ if( this.getFirefogg() && !this.getEncoderSettings()['passthrough']
 398+ && !this.isCopyUpload() )
 399+ {
 400+ this.createPreviewControls();
320401 }
321402 },
322 - doPreviewControl:function(){
 403+
 404+ /**
 405+ * Create controls for showing a transcode/crop/resize preview
 406+ */
 407+ createPreviewControls: function() {
323408 var _this = this;
324 - // Prepend preview (if fogg)
325 - $j('#upProgressDialog').append(
326 - '<div style="clear:both;height:3em"/>'+
327 - $j.btnHtml(gM('fogg-preview'), 'fogg_preview', 'triangle-1-e') +
328 - '<div style="padding:10px;">' +
 409+ // Add the preview button and canvas
 410+ $j( '#upProgressDialog' ).append(
 411+ '<div style="clear:both;height:3em"/>' +
 412+ $j.btnHtml( gM( 'fogg-preview' ), 'fogg_preview', 'triangle-1-e' ) +
 413+ '<div style="padding:10px;">' +
329414 '<canvas style="margin:auto;" id="fogg_preview_canvas" />' +
330415 '</div>'
331416 );
332 - // Set initial state
333 - if( _this.show_preview == true){
334 - $j('#fogg_preview_canvas').show();
335 - }else{
336 - // Update icon:
337 - $j(this).children('.ui-icon')
338 - .removeClass('ui-icon-triangle-1-s')
339 - .addClass('ui-icon-triangle-1-e');
340 - // Update text:
341 - $j(this).children('.btnText').text( gM('fogg-preview') );
342 - $j('#fogg_preview_canvas').hide();
 417+
 418+ // Set the initial state
 419+ if ( _this.show_preview == true ) {
 420+ $j( '#fogg_preview_canvas' ).show();
 421+ } else {
 422+ // Fix the icon class
 423+ $j( this ).children( '.ui-icon' )
 424+ .removeClass( 'ui-icon-triangle-1-s' )
 425+ .addClass( 'ui-icon-triangle-1-e' );
 426+ // Set the button text
 427+ $j( this ).children( '.btnText' ).text( gM( 'fogg-preview' ) );
 428+ $j( '#fogg_preview_canvas' ).hide();
343429 }
344 - // Apply preview binding:
345 - $j('#upProgressDialog .fogg_preview').btnBind().click( function(){
346 - js_log("click .foog_preview" + $j(this).children('.ui-icon').attr('class') );
347 - // Check state:
348 - if( $j(this).children('.ui-icon').hasClass('ui-icon-triangle-1-e') ){
349 - _this.show_preview = true;
350 - // Update icon:
351 - $j(this).children('.ui-icon')
352 - .removeClass('ui-icon-triangle-1-e')
353 - .addClass('ui-icon-triangle-1-s');
354 - // Update text
355 - $j(this).children('.btnText').text( gM('fogg-hidepreview') );
356 -
357 - // Show preview window
358 - $j('#fogg_preview_canvas').show('fast');
359 - }else{
360 - _this.show_preview = false;
361 - // Update icon:
362 - $j(this).children('.ui-icon')
363 - .removeClass('ui-icon-triangle-1-s')
364 - .addClass('ui-icon-triangle-1-e');
365 - // Update text:
366 - $j(this).children('.btnText').text( gM('fogg-preview') );
367 -
368 - $j('#fogg_preview_canvas').hide('slow');
369 - }
370 - // Don't follow the #
371 - return false;
 430+
 431+ // Bind the preview button
 432+ $j( '#upProgressDialog .fogg_preview' ).btnBind().click( function() {
 433+ return _this.onPreviewClick( this );
372434 });
373 - },
374 - doRenderPreview:function(){
375 - var _this = this;
376 - // Set up the hidden video to pull frames from:
377 - if( $j('#fogg_preview_vid').length == 0 )
378 - $j('body').append('<video id="fogg_preview_vid" style="display:none"></video>');
379 - var v = $j('#fogg_preview_vid').get(0);
380 -
381 - function seekToEnd(){
382 - var v = $j('#fogg_preview_vid').get(0);
383 - v.currentTime = v.duration-0.4;
 435+ },
 436+
 437+ /**
 438+ * onclick handler for the hide/show preview button
 439+ */
 440+ onPreviewClick: function( sourceNode ) {
 441+ var button = $j( sourceNode );
 442+ var icon = button.children( '.ui-icon' );
 443+ js_log( "click .fogg_preview" + icon.attr( 'class' ) );
 444+
 445+ if ( icon.hasClass( 'ui-icon-triangle-1-e' ) ) {
 446+ // Show preview
 447+ // Toggle button class and set button text to "hide".
 448+ this.show_preview = true;
 449+ icon.removeClass( 'ui-icon-triangle-1-e' ).addClass( 'ui-icon-triangle-1-s' );
 450+ button.children( '.btnText' ).text( gM( 'fogg-hidepreview' ) );
 451+ $j( '#fogg_preview_canvas' ).show( 'fast' );
 452+ } else {
 453+ // Hide preview
 454+ // Toggle button class and set button text to "show".
 455+ this.show_preview = false;
 456+ icon.removeClass( 'ui-icon-triangle-1-s' ).addClass( 'ui-icon-triangle-1-e' );
 457+ button.children( '.btnText' ).text( gM( 'fogg-preview' ) );
 458+ $j( '#fogg_preview_canvas' ).hide( 'slow' );
384459 }
385 - function getFrame() {
386 - var v = $j('#fogg_preview_vid').get(0);
387 - var canvas = $j('#fogg_preview_canvas').get(0);
388 - if( canvas ){
 460+ // Don't follow the # link
 461+ return false;
 462+ },
 463+
 464+ /**
 465+ * Render the preview frame (asynchronously)
 466+ */
 467+ renderPreview: function() {
 468+ var _this = this;
 469+ // Set up the hidden video to pull frames from
 470+ if( $j( '#fogg_preview_vid' ).length == 0 )
 471+ $j( 'body' ).append( '<video id="fogg_preview_vid" style="display:none"></video>' );
 472+ var v = $j( '#fogg_preview_vid' ).get( 0 );
 473+
 474+ function seekToEnd() {
 475+ var v = $j( '#fogg_preview_vid' ).get( 0 );
 476+ // TODO: document arbitrary 0.4s constant
 477+ v.currentTime = v.duration - 0.4;
 478+ }
 479+ function renderFrame() {
 480+ var v = $j( '#fogg_preview_vid' ).get( 0 );
 481+ var canvas = $j( '#fogg_preview_canvas' ).get( 0 );
 482+ if ( canvas ) {
389483 canvas.width = 160;
390 - canvas.height = canvas.width * v.videoHeight/v.videoWidth;
391 - var ctx = canvas.getContext("2d");
392 - ctx.drawImage(v, 0, 0, canvas.width, canvas.height);
 484+ canvas.height = canvas.width * v.videoHeight / v.videoWidth;
 485+ var ctx = canvas.getContext( "2d" );
 486+ ctx.drawImage( v, 0, 0, canvas.width, canvas.height );
393487 }
394 - }
395 - var previewI=null;
396 - function preview() {
397 - // Initialize the video if not setup already:
398 - var v = $j('#fogg_preview_vid').get(0);
399 - if( v.src != _this.fogg.previewUrl ){
400 - js_log('init preview with url:' + _this.fogg.previewUrl);
 488+ }
 489+ function preview() {
 490+ // Initialize the video if it is not set up already
 491+ var v = $j( '#fogg_preview_vid' ).get( 0 );
 492+ if ( v.src != _this.fogg.previewUrl ) {
 493+ js_log( 'init preview with url:' + _this.fogg.previewUrl );
401494 v.src = _this.fogg.previewUrl;
402 -
403 - // Set the video to seek to the end of the video
404 - v.removeEventListener("loadedmetadata", seekToEnd, true);
405 - v.addEventListener("loadedmetadata", seekToEnd, true);
406 -
407 - // Render a frame once seek is complete:
408 - v.removeEventListener("seeked", getFrame, true);
409 - v.addEventListener("seeked", getFrame, true);
410 -
411 - // Refresh the video duration/meta:
412 - clearInterval(previewI);
413 - var previewI = setInterval(function(){
414 - if (_this.fogg.status() != "encoding"){
415 - clearInterval(previewI);
 495+
 496+ // Once it's loaded, seek to the end
 497+ v.removeEventListener( "loadedmetadata", seekToEnd, true );
 498+ v.addEventListener( "loadedmetadata", seekToEnd, true );
 499+
 500+ // When the seek is done, render a frame
 501+ v.removeEventListener( "seeked", renderFrame, true );
 502+ v.addEventListener( "seeked", renderFrame, true );
 503+
 504+ // Refresh the video duration and metadata
 505+ var previewTimer = setInterval( function() {
 506+ if ( _this.fogg.status() != "encoding" ) {
 507+ clearInterval( previewTimer );
416508 _this.show_preview == false;
417509 }
418 - if (_this.show_preview == true) {
 510+ if ( _this.show_preview == true ) {
419511 v.load();
420512 }
421 - }, 1000);
422 - }
423 - }
424 - preview();
 513+ }, 1000 );
 514+ }
 515+ }
 516+ preview();
425517 },
426 - getEditForm:function(){
427 - if( this.target_edit_from )
428 - return this.pe_getEditForm();
429 - // Else try to get the parent "from" of the file selector:
430 - return $j(this.selector).parents('form:first').get(0);
 518+
 519+ /**
 520+ * Get the DOMNode of the form element we are rewriting.
 521+ * Returns false if it can't be found.
 522+ * Overrides mvBaseUploadInterface.getForm().
 523+ */
 524+ getForm: function() {
 525+ if ( this.form_selector ) {
 526+ return this.pe_getForm();
 527+ } else {
 528+ // No configured form selector
 529+ // Use the first form descendant of the current container
 530+ return $j( this.selector ).parents( 'form:first' ).get( 0 );
 531+ }
431532 },
432 - selectFogg:function(){
 533+
 534+ /**
 535+ * Show a dialog box allowing the user to select the source file of the
 536+ * encode/upload operation. The filename is stored by Firefogg until the
 537+ * next encode/upload call.
 538+ *
 539+ * After a successful select, the UI is updated accordingly.
 540+ */
 541+ selectSourceFile: function() {
433542 var _this = this;
434 - if(_this.fogg.selectVideo() ){
435 - this.selectFoggActions();
 543+ if( !_this.fogg.selectVideo() ) {
 544+ // User clicked "cancel"
 545+ return;
436546 }
 547+ _this.clearSourceInfoCache();
 548+ _this.updateSourceFileUI();
437549 },
438 - selectFoggActions:function(){
439 - var _this = this;
440 - js_log('videoSelectReady');
441 - // If not already hidden hide select file and show "select new":
442 - $j(_this.target_btn_select_file).hide();
443550
444 - // Show and setup binding for select new file:
445 - $j(_this.target_btn_select_new_file).show().unbind().click(function(){
446 - //create new fogg instance:
447 - _this.fogg = new Firefogg();
448 - _this.selectFogg();
449 - });
 551+ /**
 552+ * Update the UI due to the source file changing
 553+ */
 554+ updateSourceFileUI: function() {
 555+ js_log( 'videoSelectReady' );
450556
451 - // Update if we are in passthrough mode or going to encode
452 - if( _this.fogg.sourceInfo && _this.fogg.sourceFilename ){
453 - //update the source status
454 - try{
455 - _this.sourceFileInfo = JSON.parse( _this.fogg.sourceInfo ) ;
456 - }catch (e){
457 - js_error('error could not parse fogg sourceInfo');
 557+ if ( !_this.fogg.sourceInfo || !_this.fogg.sourceFilename ) {
 558+ // Something wrong with the source file?
 559+ js_log( 'selectSourceFile: sourceInfo/sourceFilename missing' );
 560+ return;
 561+ }
 562+
 563+ // Hide the "select file" button and show "select new"
 564+ $j( _this.target_btn_select_file ).hide();
 565+ $j( _this.target_btn_select_new_file)
 566+ .show()
 567+ .unbind()
 568+ .click( function() {
 569+ _this.fogg = new Firefogg();
 570+ _this.selectSourceFile();
 571+ } );
 572+
 573+ var settings = this.getEncoderSettings();
 574+
 575+ // If we're in passthrough mode, update the interface (if not a form)
 576+ if ( settings['passthrough'] == true && _this.form_type == 'local' ) {
 577+ $j( _this.target_passthrough_mode ).show();
 578+ } else {
 579+ $j( _this.target_passthrough_mode ).hide();
 580+ // Show the "save file" button if this is a local form
 581+ if ( _this.form_type == 'local' ) {
 582+ $j( _this.target_btn_save_local_file ).show();
 583+ } // else the upload will be done on form submit
 584+ }
 585+
 586+ // Update the input file name box and show it
 587+ js_log( " should update: " + _this.target_input_file_name +
 588+ ' to: ' + _this.fogg.sourceFilename );
 589+ $j( _this.target_input_file_name )
 590+ .val( _this.fogg.sourceFilename )
 591+ .show();
 592+
 593+
 594+ // Notify callback new_source_cb
 595+ if ( _this.new_source_cb ) {
 596+ if ( settings['passthrough'] ) {
 597+ var fName = _this.fogg.sourceFilename;
 598+ } else {
 599+ var oggExt = _this.isSourceAudio() ? 'oga' : 'ogg';
 600+ oggExt = _this.isSourceVideo() ? 'ogv' : oggExt;
 601+ oggExt = _this.isUnknown() ? 'ogg' : oggExt;
 602+ oggName = _this.fogg.sourceFilename.substr( 0,
 603+ _this.fogg.sourceFilename.lastIndexOf( '.' ) );
 604+ var fName = oggName + '.' + oggExt;
458605 }
 606+ _this.new_source_cb( _this.fogg.sourceFilename, fName );
 607+ }
 608+ },
459609
460 - // Now setup encoder settings based source type:
461 - _this.autoEncoderSettings();
 610+ /**
 611+ * Get the source file info for the current file selected into this.fogg
 612+ */
 613+ getSourceFileInfo: function() {
 614+ if ( this.sourceFileInfo == null ) {
 615+ if ( !this.fogg.sourceInfo ) {
 616+ js_error( 'No firefogg source info is available' );
 617+ return false;
 618+ }
 619+ try {
 620+ this.sourceFileInfo = JSON.parse( firefogg.sourceInfo );
 621+ } catch ( e ) {
 622+ js_error( 'error could not parse fogg sourceInfo' );
 623+ return false;
 624+ }
 625+ }
 626+ return this.sourceFileInfo;
 627+ },
462628
463 - // If set to passthough update the interface (if not a form)
464 - if(_this.encoder_settings['passthrough'] == true && !_this.form_rewrite){
465 - $j(_this.target_passthrough_mode).show();
466 - }else{
467 - $j(_this.target_passthrough_mode).hide();
468 - // If set to encoder expose the encode button:
469 - if( !_this.form_rewrite ){
470 - $j(_this.target_btn_save_local_file).show();
 629+ /**
 630+ * Clear the cache of the source file info, presumably due to a new file
 631+ * being selected into this.fogg
 632+ */
 633+ clearSourceInfoCache: function() {
 634+ this.sourceFileInfo = null;
 635+ this.current_encoder_settings = null;
 636+ },
 637+
 638+ /**
 639+ * Save the result of the transcode as a local file
 640+ */
 641+ doLocalEncodeAndSave: function() {
 642+ var _this = this;
 643+ if ( !this.fogg ) {
 644+ js_error( 'doLocalEncodeAndSave: no Firefogg object!' );
 645+ return false;
 646+ }
 647+
 648+ // Set up the target location
 649+ // Firefogg shows the "save as" dialog box, and sets the path chosen as
 650+ // the destination for a later encode() call.
 651+ if ( !this.fogg.saveVideoAs() ) {
 652+ // User clicked "cancel"
 653+ return false;
 654+ }
 655+
 656+ // We have a source file, now do the encode
 657+ this.doEncode(
 658+ function /* onProgress */ ( progress ) {
 659+ _this.updateProgress( progress );
 660+ },
 661+ function /* onDone */ () {
 662+ js_log( "done with encoding (no upload) " );
 663+ // Set status to 100% for one second
 664+ // FIXME: this is either a hack or a waste of time, not sure which
 665+ _this.updateProgress( 1 );
 666+ setTimeout( function() {
 667+ _this.onLocalEncodeDone();
471668 }
472669 }
473 - //~otherwise the encoding will be triggered by the form~
 670+ );
 671+ },
474672
475 - // Do source name update callback:
476 - js_log(" should update: " + _this.target_input_file_name + ' to: ' + _this.fogg.sourceFilename );
477 - $j(_this.target_input_file_name).val(_this.fogg.sourceFilename).show();
 673+ /**
 674+ * This is called when a local encode operation has completed. It updates the UI.
 675+ */
 676+ onLocalEncodeDone() {
 677+ var _this = this;
 678+ _this.updateProgressWin( gM( 'fogg-encoding-done' ),
 679+ gM( 'fogg-encoding-done' ) + '<br>' +
 680+ //show the video at full resolution upto 720px wide
 681+ '<video controls="true" style="margin:auto" id="fogg_final_vid" src="' +
 682+ _this.fogg.previewUrl + '"></video>'
 683+ );
 684+ //load the video and set a callback:
 685+ var v = $j( '#fogg_final_vid' ).get( 0 );
 686+ function resizeVid() {
 687+ var v = $j( '#fogg_final_vid' ).get(0);
 688+ if ( v.videoWidth > 720 ) {
 689+ var vW = 720;
 690+ var vH = 720 * v.videoHeight / v.videoWidth;
 691+ } else {
 692+ var vW = v.videoWidth;
 693+ var vH = v.videoHeight;
 694+ }
 695+ //reize the video:
 696+ $j( v ).css({
 697+ 'width': vW,
 698+ 'height': vH
 699+ });
 700+ //if large video resize the dialog box:
 701+ if( vW + 5 > 400 ) {
 702+ //also resize the dialog box
 703+ $j( '#upProgressDialog' ).dialog( 'option', 'width', vW + 20 );
 704+ $j( '#upProgressDialog' ).dialog( 'option', 'height', vH + 120 );
478705
479 - if(_this.new_source_cb){
480 - if(_this.encoder_settings['passthrough']){
481 - var fName = _this.fogg.sourceFilename
482 - }else{
483 - var oggExt = (_this.isSourceAudio())?'oga':'ogg';
484 - oggExt = (_this.isSourceVideo())?'ogv':oggExt;
485 - oggExt = (_this.isUnknown())?'ogg':oggExt;
486 - oggName = _this.fogg.sourceFilename.substr(0,
487 - _this.fogg.sourceFilename.lastIndexOf('.'));
488 - var fName = oggName +'.'+ oggExt
489 - }
490 - _this.new_source_cb( _this.fogg.sourceFilename , fName);
 706+ //also position the dialog container
 707+ $j( '#upProgressDialog') .dialog( 'option', 'position', 'center' );
491708 }
492709 }
 710+ v.removeEventListener( "loadedmetadata", resizeVid, true );
 711+ v.addEventListener( "loadedmetadata", resizeVid, true );
 712+ v.load();
493713 },
494 - saveLocalFogg:function(){
495 - // Request target location:
496 - if(this.fogg){
497 - if(!this.fogg.saveVideoAs() )
498 - return false;
499714
500 - // We have set a target now call the encode:
501 - this.doEncode();
502 - }
503 - },
504 - // Simple auto encoder settings just enable passthough if file is not video or > 480 pixles tall
505 - autoEncoderSettings:function(){
506 - var _this = this;
507 - // Grab the extension:
508 - var sf = _this.fogg.sourceFilename;
509 - var ext = '';
510 - if( sf.lastIndexOf('.') != -1)
511 - ext = sf.substring( sf.lastIndexOf('.')+1 ).toLowerCase();
 715+ /**
 716+ * Get the appropriate encoder settings for the current Firefogg object,
 717+ * into which a video has already been selected.
 718+ */
 719+ getEncoderSettings function() {
 720+ if ( this.current_encoder_settings == null ) {
 721+ // Clone the default settings
 722+ var defaults = function () {};
 723+ var defaults.prototype = this.default_encoder_settings;
 724+ var settings = new defaults();
512725
513 - // Set to passthrough to true by default (images, arbitrary files that we want to send with http chunks)
514 - this.encoder_settings['passthrough'] = true;
 726+ // Grab the extension
 727+ var sf = this.fogg.sourceFilename;
 728+ if ( !sf ) {
 729+ js_error( 'getEncoderSettings(): No Firefogg source filename is available!' );
 730+ return false;
 731+ }
 732+ var ext = '';
 733+ if ( sf.lastIndexOf('.') != -1 )
 734+ ext = sf.substring( sf.lastIndexOf( '.' ) + 1 ).toLowerCase();
515735
516 - // See if we have video or audio:
517 - if( _this.isSourceAudio() || _this.isSourceVideo() )
518 - _this.encoder_settings['passthrough'] = false;
 736+ // Determine passthrough mode
 737+ if ( this.isOggFormat() ) {
 738+ // Already Ogg, no need to encode
 739+ settings['passthrough'] = true;
 740+ } else if ( this.isSourceAudio() || this.isSourceVideo() ) {
 741+ // OK to encode
 742+ settings['passthrough'] = false;
 743+ } else {
 744+ // Not audio or video, can't encode
 745+ settings['passthrough'] = true;
 746+ }
519747
520 - // Special case see if we already have ogg video:
521 - if( _this.isOggFormat() )
522 - _this.encoder_settings['passthrough'] = true;
523 -
524 - js_log('base autoEncoderSettings::' + _this.sourceFileInfo.contentType + ' passthrough:' + _this.encoder_settings['passthrough']);
 748+ js_log( 'base setupAutoEncoder::' + this.getSourceFileInfo().contentType +
 749+ ' passthrough:' + settings['passthrough'] );
 750+ this.current_encoder_settings = settings;
 751+ }
 752+ return this.current_encoder_settings;
525753 },
526 - isUnknown:function(){
527 - return (this.sourceFileInfo.contentType.indexOf("unknown") != -1);
 754+
 755+ isUnknown: function() {
 756+ return ( this.getSourceFileInfo().contentType.indexOf("unknown") != -1 );
528757 },
529 - isSourceAudio:function(){
530 - return (this.sourceFileInfo.contentType.indexOf("audio/") != -1);
 758+
 759+ isSourceAudio: function() {
 760+ return ( this.getSourceFileInfo().contentType.indexOf("audio/") != -1 );
531761 },
532 - isSourceVideo:function(){
533 - return (this.sourceFileInfo.contentType.indexOf("video/") != -1);
 762+
 763+ isSourceVideo: function() {
 764+ return ( this.getSourceFileInfo().contentType.indexOf("video/") != -1 );
534765 },
535 - isOggFormat:function(){
536 - return ( this.sourceFileInfo.contentType.indexOf("video/ogg") != -1 ||
537 - this.sourceFileInfo.contentType.indexOf("application/ogg") != -1 );
 766+
 767+ isOggFormat: function() {
 768+ var contentType = this.getSourceFileInfo().contentType;
 769+ return ( contentType.indexOf("video/ogg") != -1
 770+ || contentType.indexOf("application/ogg") != -1 );
538771 },
539 - getProgressTitle:function(){
540 - js_log("fogg:getProgressTitle f:" + this.fogg_enabled + ' rw:' + this.form_rewrite);
541 - // Return the parent if we don't have fogg turned on:
542 - if(! this.fogg_enabled || !this.firefogg_form_action )
 772+
 773+ /**
 774+ * Get the default title of the progress window
 775+ */
 776+ getProgressTitle: function() {
 777+ js_log( "fogg:getProgressTitle f:" + ( this.getFirefogg() ? 'on' : 'off' ) +
 778+ ' mode:' + this.form_type );
 779+ // Return the parent's title if we don't have Firefogg turned on
 780+ if ( !this.getFirefogg() || !this.firefogg_form_action ) {
543781 return this.pe_getProgressTitle();
544 - if( !this.form_rewrite )
545 - return gM('fogg-transcoding');
546 - // Else return our upload+transcode msg:
547 - return gM('mwe-upload-transcode-in-progress');
 782+ } else if ( this.form_type == 'local' ) {
 783+ return gM( 'fogg-transcoding' );
 784+ } else {
 785+ return gM( 'mwe-upload-transcode-in-progress' );
 786+ }
548787 },
549 - doUploadSwitch:function(){
550 - var _this = this;
551 - js_log("firefogg: doUploadSwitch:: " + this.fogg_enabled + ' up mode:' + _this.upload_mode);
552 - // Make sure firefogg is enabled otherwise do parent UploadSwich:
553 - if( !this.fogg_enabled || !this.firefogg_form_action )
554 - return _this.pe_doUploadSwitch();
555788
556 - // Check what mode to use firefogg in:
557 - if( _this.upload_mode == 'post' ){
558 - _this.doEncode();
559 - }else if( _this.upload_mode == 'api' ){ //if api mode and chunks supported do chunkUpload
 789+ /**
 790+ * Do an upload, with the mode given by this.upload_mode
 791+ */
 792+ doUpload: function() {
 793+ var _this = this;
 794+ js_log( "firefogg: doUpload:: " +
 795+ ( this.getFirefogg() ? 'on' : 'off' ) +
 796+ ' up mode:' + _this.upload_mode );
 797+
 798+ // If Firefogg is disabled, just invoke the parent method
 799+ if( !this.getFirefogg() || !this.firefogg_form_action ) {
 800+ _this.pe_doUpload();
 801+ return;
 802+ }
 803+
 804+ if ( _this.upload_mode == 'post' ) {
 805+ // Encode and then do a post upload
 806+ _this.doEncode(
 807+ function /* onProgress */ ( progress ) {
 808+ _this.updateProgress( progress );
 809+ },
 810+ function /* onDone */ () {
 811+ js_log( 'done with encoding do POST upload:' + _this.editForm.action );
 812+ // ignore warnings & set source type
 813+ //_this.formData[ 'wpIgnoreWarning' ]='true';
 814+ _this.formData['wpSourceType'] = 'upload';
 815+ _this.formData['action'] = 'submit';
 816+ // wpUploadFile is set by firefogg
 817+ delete _this.formData['file'];
 818+
 819+ _this.fogg.post( _this.editForm.action, 'wpUploadFile',
 820+ JSON.stringify( _this.formData ) );
 821+ _this.doUploadStatus();
 822+ }
 823+ );
 824+ } else if ( _this.upload_mode == 'api' ) {
 825+ // We have the API so we can do a chunk upload
560826 _this.doChunkUpload();
561 - }else{
 827+ } else {
562828 js_error( 'Error: unrecongized upload mode: ' + _this.upload_mode );
563829 }
564830 },
 831+
565832 /**
566 - * doChunkUpload
567 - * does both uploading and encoding at the same time and uploads one meg chunks
568 - */
569 - doChunkUpload : function(){
570 - js_log('firefogg::doChunkUpload');
 833+ * Do both uploading and encoding at the same time. Uploads 1MB chunks as
 834+ * they become ready.
 835+ */
 836+ doChunkUpload : function() {
 837+ js_log( 'firefogg::doChunkUpload' );
571838 var _this = this;
572839 _this.action_done = false;
573 -
574 - // File extension should already be ogg but since its user editable,
575 - // (should not be needed for passthrough mode)
576 - var sf = _this.formData['filename'];
577 - var ext = '';
578 - if( sf.lastIndexOf('.') != -1){
579 - ext = sf.substring( sf.lastIndexOf('.') ).toLowerCase();
 840+
 841+ if ( !_this.getEncoderSettings()['passthrough'] ) {
 842+ // We are transcoding to Ogg. Fix the destination extension, it
 843+ // must be ogg/ogv/oga.
 844+ var fileName = _this.formData['filename'];
 845+ var ext = '';
 846+ var dotPos = fileName.lastIndexOf( '.' );
 847+ if ( dotPos != -1 ) {
 848+ ext = fileName.substring( dotPos ).toLowerCase();
 849+ }
 850+ if ( $j.inArray( ext.substr( 1 ), _this.ogg_extensions ) == -1 ) {
 851+ _this.formData['filename'] = fileName.substr(
 852+ 0,
 853+
 854+
 855+ var extreg = new RegExp( ext + '$', 'i' );
 856+ _this.formData['filename'] = fileName.replace( extreg, '.ogg' );
 857+ }
580858 }
581 - if( !_this.encoder_settings['passthrough'] && $j.inArray(ext.substr(1), _this.ogg_extensions) == -1 ){
582 - var extreg = new RegExp(ext + '$', 'i');
583 - _this.formData['filename'] = sf.replace(extreg, '.ogg');
 859+
 860+ // Get the edit token from formData if it's not set already
 861+ if ( !_this.editToken && _this.formData['token'] ) {
 862+ _this.editToken = _this.formData['token'];
584863 }
585 - // Add chunk response hook to build the resultURL when uploading chunks
586864
587 - // Check for editToken:
588 - if(!this.etoken){
589 - js_log('missing token try ' + _this.formData['token']);
590 - if( _this.formData['token']){
591 - _this.etoken = _this.formData['token'];
592 - _this.doChunkWithFormData();
593 - }else{
594 - get_mw_token(
595 - 'File:'+ _this.formData['filename'],
596 - _this.api_url,
597 - function( eToken ){
598 - if( !eToken || eToken == '+\\' ){
599 - _this.updateProgressWin( gM('fogg-badtoken'), gM('fogg-badtoken') );
600 - return false;
601 - }
602 - _this.etoken = eToken;
603 - _this.doChunkWithFormData();
604 - }
605 - );
 865+ if( _this.editToken ) {
 866+ js_log( 'we already have an edit token: ' + _this.editToken );
 867+ _this.doChunkUploadWithFormData();
 868+ return;
 869+ }
 870+
 871+ // No edit token. Fetch it asynchronously and then do the upload.
 872+ get_mw_token(
 873+ 'File:'+ _this.formData['filename'],
 874+ _this.api_url,
 875+ function( editToken ) {
 876+ if( !editToken || editToken == '+\\' ) {
 877+ _this.updateProgressWin( gM( 'fogg-badtoken' ), gM( 'fogg-badtoken' ) );
 878+ return false;
 879+ }
 880+ _this.editToken = editToken;
 881+ _this.doChunkUploadWithFormData();
606882 }
607 - }else{
608 - js_log('we already have token: ' + this.etoken);
609 - _this.doChunkWithFormData();
610 - }
 883+ );
611884 },
612 - doChunkWithFormData:function(){
 885+
 886+ /**
 887+ * Internal function called from doChunkUpload() when the edit token is available
 888+ */
 889+ doChunkUploadWithFormData: function() {
613890 var _this = this;
614 - js_log("firefogg::doChunkWithFormData" + _this.etoken);
615 - // Build the api url:
616 - var aReq ={
 891+ js_log( "firefogg::doChunkUploadWithFormData" + _this.editToken );
 892+ // Build the API URL
 893+ var aReq = {
617894 'action': 'upload',
618895 'format': 'json',
619896 'filename': _this.formData['filename'],
@@ -620,223 +897,187 @@
621898 'enablechunks': 'true'
622899 };
623900
624 - if( _this.etoken )
625 - aReq['token'] = this.etoken;
 901+ if ( _this.editToken )
 902+ aReq['token'] = this.editToken;
626903
627 - if( _this.formData['watch'] )
628 - aReq['watch'] = _this.formData['watch'];
 904+ if ( _this.formData['watch'] )
 905+ aReq['watch'] = _this.formData['watch'];
629906
630 - if( _this.formData['ignorewarnings'] )
 907+ if ( _this.formData['ignorewarnings'] )
631908 aReq['ignorewarnings'] = _this.formData['ignorewarnings'];
632909
633 - js_log('do fogg upload/encode call: '+ _this.api_url + ' :: ' + JSON.stringify( aReq ) );
634 - js_log('foggEncode: '+ JSON.stringify( _this.encoder_settings ) );
635 - _this.fogg.upload( JSON.stringify( _this.encoder_settings ), _this.api_url , JSON.stringify( aReq ) );
 910+ var encoderSettings = this.getEncoderSettings();
 911+ js_log( 'do fogg upload/encode call: ' + _this.api_url + ' :: ' + JSON.stringify( aReq ) );
 912+ js_log( 'foggEncode: ' + JSON.stringify( encoderSettings ) );
 913+ _this.fogg.upload( JSON.stringify( encoderSettings ), _this.api_url,
 914+ JSON.stringify( aReq ) );
636915
637 - // Update upload status:
 916+ // Start polling the upload status
638917 _this.doUploadStatus();
639918 },
640 - // doEncode and monitor progress:
641 - doEncode : function(){
 919+
 920+ /**
 921+ * Encode the video and monitor progress.
 922+ *
 923+ * Calls progressCallback() regularly with a number between 0 and 1 indicating progress.
 924+ * Calls doneCallback() when the encode is finished.
 925+ *
 926+ * Asynchronous, returns immediately.
 927+ */
 928+ doEncode : function( progressCallback, doneCallback ) {
642929 var _this = this;
643930 _this.action_done = false;
644 - _this.dispProgressOverlay();
645 - js_log('doEncode: with: ' + JSON.stringify( _this.encoder_settings ) );
646 - _this.fogg.encode( JSON.stringify( _this.encoder_settings ) );
 931+ _this.displayProgressOverlay();
 932+ var encoderSettings = this.getEncoderSettings();
 933+ js_log( 'doEncode: with: ' + JSON.stringify( encoderSettings ) );
 934+ _this.fogg.encode( JSON.stringify( encoderSettings ) );
647935
648 - // Show transcode status:
649 - $j('#up-status-state').html( gM('mwe-upload-transcoded-status') );
 936+ //show transcode status:
 937+ $j( '#up-status-state' ).html( gM( 'mwe-upload-transcoded-status' ) );
650938
651 - // Setup a local function for timed callback:
 939+ //setup a local function for timed callback:
652940 var encodingStatus = function() {
653941 var status = _this.fogg.status();
654942
655 - if( _this.show_preview == true && _this.fogg.state == 'encoding'){
656 - _this.doRenderPreview();
 943+ if ( _this.show_preview == true && _this.fogg.state == 'encoding' ) {
 944+ _this.renderPreview();
657945 }
658946
659 - // Update progress bar
660 - _this.updateProgress( _this.fogg.progress() );
 947+ // Update progress
 948+ progressCallback( _this.fogg.progress() );
661949
662 - // Loop to get new status if still encoding
663 - if( _this.fogg.state == 'encoding' ) {
664 - setTimeout(encodingStatus, 500);
665 - }else if ( _this.fogg.state == 'encoding done' ) { //encoding done, state can also be 'encoding failed
666 - _this.encodeDone();
667 - }else if(_this.fogg.state == 'encoding fail'){
 950+ //loop to get new status if still encoding
 951+ if ( _this.fogg.state == 'encoding' ) {
 952+ setTimeout( encodingStatus, 500 );
 953+ } else if ( _this.fogg.state == 'encoding done' ) {
 954+ _this.action_done = true;
 955+ progressCallback( 1 );
 956+ doneCallback();
 957+ } else if ( _this.fogg.state == 'encoding fail' ) {
668958 //@@todo error handling:
669 - js_error('encoding failed');
 959+ js_error( 'encoding failed' );
670960 }
671961 }
672962 encodingStatus();
673963 },
674 - encodeDone:function(){
675 - var _this = this;
676 - js_log('::encodeDone::');
677 - _this.action_done = true;
678 -
679 - // Send to the post url:
680 - if( _this.form_rewrite && _this.upload_mode == 'post' ){
681 - js_log('done with encoding do POST upload:' + _this.editForm.action);
682 - // ignore warnings & set source type
683 - //_this.formData[ 'wpIgnoreWarning' ]='true';
684 - _this.formData[ 'wpSourceType' ] = 'upload';
685 - _this.formData[ 'action' ] = 'submit';
686 - //wpUploadFile is set by firefogg
687 - delete _this.formData[ 'file' ];
688964
689 - _this.fogg.post( _this.editForm.action, 'wpUploadFile', JSON.stringify( _this.formData ) );
690 - // Update upload status:
691 - _this.doUploadStatus();
692 - }else{
693 - js_log("done with encoding (no upload) ");
694 - // Set status to 100% for one second:
695 - _this.updateProgress( 1 );
696 - setTimeout(function(){
697 - _this.updateProgressWin(gM('fogg-encoding-done'),
698 - gM('fogg-encoding-done') + '<br>' +
699 - // Show the video at full resolution up-to 720px wide
700 - '<video controls="true" style="margin:auto" id="fogg_final_vid" src="' +
701 - _this.fogg.previewUrl + '"></video>'
702 - );
703 - //load the video and set a callback:
704 - var v = $j('#fogg_final_vid').get(0);
705 - function resizeVid(){
706 - var v = $j('#fogg_final_vid').get(0);
707 - if( v.videoWidth > 720 ){
708 - var vW = 720;
709 - var vH = 720 * (v.videoHeight/v.videoWidth)
710 - }else{
711 - var vW = v.videoWidth;
712 - var vH = v.videoHeight;
713 - }
714 - // Resize the video:
715 - $j(v).css({
716 - 'width' : vW,
717 - 'height': vH
718 - });
719 - // If large video resize the dialog box:
720 - if( vW + 5 > 400){
721 - //also resize the dialog box
722 - $j('#upProgressDialog').dialog('option', 'width', vW + 20);
723 - $j('#upProgressDialog').dialog('option', 'height', vH + 120);
724 -
725 - //also position the dialog container
726 - $j('#upProgressDialog').dialog('option', 'position', 'center');
727 - }
728 - }
729 - v.removeEventListener("loadedmetadata", resizeVid, true);
730 - v.addEventListener("loadedmetadata", resizeVid, true);
731 - v.load();
732 - }, 1000);
733 - }
734 - },
735 - doUploadStatus:function() {
 965+ /**
 966+ * Poll the upload progress and update the UI regularly until the upload is complete.
 967+ *
 968+ * Asynchronous, returns immediately.
 969+ */
 970+ doUploadStatus: function() {
736971 var _this = this;
737 - $j( '#up-status-state' ).html( gM('mwe-uploaded-status') );
 972+ $j( '#up-status-state' ).html( gM( 'mwe-uploaded-status' ) );
738973
739974 _this.oldResponseText = '';
740 - // Setup a local function for timed callback:
741 - var uploadStatus = function(){
742 - // Get the response text:
743 - var response_text = _this.fogg.responseText;
744 - if(!response_text){
745 - try{
746 - var pstatus = JSON.parse( _this.fogg.uploadstatus() );
747 - response_text = pstatus["responseText"];
748 - }catch(e){
749 - js_log("could not parse uploadstatus / could not get responseText");
750 - }
 975+
 976+ // Create a local function for timed callback
 977+ var uploadStatus = function() {
 978+ var response_text = _this.fogg.responseText;
 979+ if ( !response_text ) {
 980+ try {
 981+ var pstatus = JSON.parse( _this.fogg.uploadstatus() );
 982+ response_text = pstatus["responseText"];
 983+ } catch( e ) {
 984+ js_log( "could not parse uploadstatus / could not get responseText" );
 985+ }
751986 }
752987
753 - if( _this.oldResponseText != response_text){
754 - js_log('new result text:' + response_text + ' state:' + _this.fogg.state);
 988+ if ( _this.oldResponseText != response_text ) {
 989+ js_log( 'new result text:' + response_text + ' state:' + _this.fogg.state );
755990 _this.oldResponseText = response_text;
756 - // Try and parse the response text and check for errors
757 - try{
 991+ // Parse the response text and check for errors
 992+ try {
758993 var apiResult = JSON.parse( response_text );
759 - }catch(e){
760 - js_log("could not parse response_text::" + response_text + ' ...for now try with eval...');
761 - try{
 994+ } catch( e ) {
 995+ js_log( "could not parse response_text::" + response_text +
 996+ ' ...for now try with eval...' );
 997+ try {
762998 var apiResult = eval( response_text );
763 - }catch(e){
 999+ } catch( e ) {
7641000 var apiResult = null;
765 - }
 1001+ }
7661002 }
767 - if(apiResult && _this.apiUpdateErrorCheck( apiResult ) === false){
768 - // Stop status update we have an error
 1003+ if ( apiResult && !_this.isApiSuccess( apiResult ) ) {
 1004+ // Show the error and stop the upload
 1005+ _this.showApiError( apiResult );
7691006 _this.action_done = true;
7701007 _this.fogg.cancel();
7711008 return false;
7721009 }
7731010 }
774 - if( _this.show_preview == true ){
775 - if( _this.fogg.state == 'encoding' ){
776 - _this.doRenderPreview();
 1011+ if ( _this.show_preview == true ) {
 1012+ if ( _this.fogg.state == 'encoding' ) {
 1013+ _this.renderPreview();
7771014 }
7781015 }
779 -
780 - // Update progress bar
 1016+
 1017+ // Update the progress bar
7811018 _this.updateProgress( _this.fogg.progress() );
7821019
783 - // Loop to get new status if still uploading (could also be encoding if we are in chunk upload mode)
784 - if( _this.fogg.state == 'encoding' || _this.fogg.state == 'uploading') {
785 - setTimeout(uploadStatus, 100);
786 - }// Check upload state
787 - else if( _this.fogg.state == 'upload done' ||
788 - _this.fogg.state == 'done' ||
789 - _this.fogg.state == 'encoding done' ) {
790 - // If in "post" upload mode read the html response (should be deprecated):
791 - if( _this.upload_mode == 'api' ){
792 - if( apiResult && apiResult.resultUrl ){
793 - var buttons ={};
794 - buttons[gM('mwe-go-to-resource')] = function(){
795 - window.location = apiResult.resultUrl;
796 - }
797 - var go_to_url_txt = gM('mwe-go-to-resource');
798 - if( typeof _this.done_upload_cb == 'function' ){
799 - // If done action return 'true'
800 - if( _this.done_upload_cb( _this.formData ) ){
801 - // Update status
802 - _this.updateProgressWin( gM('mwe-successfulupload'), gM( 'mwe-upload_done', apiResult.resultUrl),buttons);
803 - }else{
804 - // If done action returns 'false' //close progress window
805 - this.action_done = true;
806 - $j('#upProgressDialog').empty().dialog('close');
807 - }
808 - }else{
809 - // Update status (without done_upload_cb)
810 - _this.updateProgressWin( gM('mwe-successfulupload'), gM( 'mwe-upload_done', apiResult.resultUrl),buttons);
811 - }
812 - }else{
813 - // Done state with error? ..not really possible given how firefogg works
814 - js_log(" Upload done in chunks mode, but no resultUrl!");
815 - }
816 - }else{
817 - js_log("Error:: not supported upload mode" + _this.upload_mode);
818 - }
819 - }else{
820 - // Upload error:
821 - js_log('Error:firefogg upload error: ' + _this.fogg.state );
822 - }
823 - }
824 - uploadStatus();
 1020+ // If we're still uploading or encoding, continue to poll the status
 1021+ if ( _this.fogg.state == 'encoding' || _this.fogg.state == 'uploading' ) {
 1022+ setTimeout( uploadStatus, 100 );
 1023+ return;
 1024+ }
 1025+
 1026+ // Upload done?
 1027+ if ( -1 == $j.inArray( _this.fogg.state, [ 'upload done', 'done', 'encoding done' ] ) ) {
 1028+ js_log( 'Error:firefogg upload error: ' + _this.fogg.state );
 1029+ return;
 1030+ }
 1031+
 1032+ if ( _this.upload_mode == 'api' ) {
 1033+ if ( apiResult && apiResult.resultUrl ) {
 1034+ var buttons = {};
 1035+ buttons[ gM( 'mwe-go-to-resource' ) ] = function() {
 1036+ window.location = apiResult.resultUrl;
 1037+ }
 1038+ var go_to_url_txt = gM( 'mwe-go-to-resource' );
 1039+ var showMessage = true;
 1040+ if ( typeof _this.done_upload_cb == 'function' ) {
 1041+ // Call the callback
 1042+ // It will return false if it doesn't want us to show our own "done" message
 1043+ showMessage = _this.done_upload_cb( _this.formData );
 1044+ }
 1045+ if ( showMessage ) {
 1046+ _this.updateProgressWin( gM( 'mwe-successfulupload' ),
 1047+ gM( 'mwe-upload_done', apiResult.resultUrl ), buttons );
 1048+ } else {
 1049+ this.action_done = true;
 1050+ $j( '#upProgressDialog' ).empty().dialog( 'close' );
 1051+ }
 1052+ } else {
 1053+ // Done state with error? Not really possible given how firefogg works...
 1054+ js_log( " Upload done in chunks mode, but no resultUrl!" );
 1055+ }
 1056+ } else {
 1057+ js_log( "Error:: not supported upload mode" + _this.upload_mode );
 1058+ }
 1059+ }
 1060+ uploadStatus();
8251061 },
826 - cancel_action:function( dlElm ){
827 - if(!this.fogg_enabled){
 1062+
 1063+ /**
 1064+ * This is the cancel button handler, referenced by getCancelButton() in the parent.
 1065+ */
 1066+ onCancel: function( dlElm ) {
 1067+ if ( !this.have_firefogg ) {
8281068 return this.pe_cancel_action();
8291069 }
830 - js_log('firefogg:cancel')
831 - if( confirm( gM('mwe-cancel-confim') )){
832 - if(navigator.oscpu && navigator.oscpu.search('Win') >= 0){
833 - alert( 'sorry we do not yet support cancel on windows' );
834 - }else{
835 - this.action_done = true;
836 - this.fogg.cancel();
837 - $j(dlElm).empty().dialog('close');
838 - }
839 - }
840 - // Dont' follow the link:
841 - return false;
 1070+ js_log( 'firefogg:cancel' )
 1071+ if ( confirm( gM( 'mwe-cancel-confim' ) ) ) {
 1072+ // FIXME: sillyness
 1073+ if ( navigator.oscpu && navigator.oscpu.search( 'Win' ) >= 0 ) {
 1074+ alert( 'sorry we do not yet support cancel on windows' );
 1075+ } else {
 1076+ this.action_done = true;
 1077+ this.fogg.cancel();
 1078+ $j( dlElm ).empty().dialog( 'close' );
 1079+ }
 1080+ }
 1081+ // Don't follow the # link:
 1082+ return false;
8421083 }
8431084 };

Follow-up revisions

RevisionCommit summaryAuthorDate
r59439Fixes for remoteSearchDriver.js and related. Untested, probably doesn't work....tstarling03:10, 26 November 2009
r59811* some more fixes for r59278 breakagedale00:12, 8 December 2009

Comments

#Comment by Mdale (talk | contribs)   20:59, 25 November 2009

Fixed the associated regressions in r59433 & r59431 & 59435

Status & tagging log