r63157 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r63156‎ | r63157 | r63158 >
Date:23:57, 1 March 2010
Author:dale
Status:deferred
Tags:
Comment:
working upload iframe api proxy
fixed overlay display size
Modified paths:
  • /branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/mw.Firefogg.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/mw.UploadHandler.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/mw.UploadInterface.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/ApiProxy/mw.ApiProxy.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/mw.EmbedPlayer.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/skins/kskin/kskinConfig.js (modified) (history)

Diff [purge]

Index: branches/js2-work/phase3/js/mwEmbed/skins/kskin/kskinConfig.js
@@ -78,6 +78,7 @@
7979 $menuOverlay.css( {
8080 'top' : topPos + 'px',
8181 'bottom' : null,
 82+ 'width' : ctrlObj.getOverlayWidth(),
8283 'height' : ctrlObj.getOverlayHeight() + 'px'
8384 });
8485
Index: branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/mw.UploadHandler.js
@@ -7,11 +7,8 @@
88 * This base upload class is optionally extended by Firefogg
99 *
1010 */
11 -mw.addMessages({
12 - "mwe-upload-in-progress" : "Upload in progress (do not close this window)",
 11+mw.addMessages({
1312 "mwe-upload-transcoded-status" : "Transcoded",
14 - "mwe-uploaded-time-remaining" : "Time remaining: $1",
15 - "mwe-uploaded-status" : "Uploaded",
1613 "mwe-upload-stats-fileprogress" : "$1 of $2",
1714 "mwe-upload_completed" : "Your upload is complete",
1815 "mwe-upload_done" : "<a href=\"$1\">Your upload <i>should be<\/i> accessible<\/a>.",
@@ -34,7 +31,8 @@
3532
3633 "license-header" : "Licensing",
3734 "filedesc" : "Summary",
38 - "filesource" : "Source:"
 35+ "filesource" : "Source:",
 36+ "filestatus" : "Copyright status:"
3937 });
4038
4139 var default_bui_options = {
@@ -82,19 +80,24 @@
8381 if ( myUpload ) {
8482 myUpload.setupForm( );
8583 }
 84+
 85+ // Update the selecto to include pointer to upload handler
 86+ var selectorElement = $j( this.selector ).get( 0 );
 87+ selectorElement[ 'uploadHandler' ] = myUpload;
8688 }
8789 } )( jQuery );
8890
8991 mw.UploadHandler = function( options ) {
9092 return this.init( options );
9193 }
 94+
9295 mw.UploadHandler.prototype = {
9396
9497 // The form data to be submitted
9598 formData: {},
9699
97100 // Upload warning session key, for continued uploads
98 - warnings_sessionkey: null,
 101+ warnings_sessionkey: false,
99102
100103 // If chunks uploading is supported
101104 chunks_supported: true,
@@ -115,10 +118,6 @@
116119
117120 // The DOM node for the upload form
118121 form: false,
119 -
120 - // The following are really state of the upload, not the interface.
121 - // we are currently only managing one, so this is okay... for now.
122 - uploadBeginTime: null,
123122
124123 /**
125124 * Object initialization
@@ -134,15 +133,21 @@
135134 this.api_url = mw.getLocalApiUrl();
136135 }
137136
138 - // Setup the UploadInterface handler
139 - if( ! options.ui ){
140 - this.ui = mw.DialogInterface( );
141 - } else {
 137+ // We can't pass around actual function refrences since sometimes the interface
 138+ // is seperated via iframe #hash messege communication.
 139+ if( options.ui ){
142140 this.ui = options.ui;
143 - }
144 -
 141+ } else {
 142+ // Setup the default DialogInterface UI
 143+ this.ui = new mw.DialogInterface();
 144+ }
 145+
 146+ // Setup ui uploadHandler pointer
 147+ this.ui.uploadHandler = this;
 148+
145149 mw.log( "init mvUploadHandler:: " + this.api_url + ' interface: ' + this.ui );
146150 },
 151+
147152 /**
148153 * Set up the upload form, register onsubmit handler.
149154 * May remap it to use the API field names.
@@ -181,6 +186,7 @@
182187 onSubmit: function() {
183188 var _this = this;
184189 mw.log( 'Base::onSubmit:' );
 190+
185191 // Run the original onsubmit (if not run yet set flag to avoid excessive chaining)
186192 if ( typeof( this.orig_onsubmit ) == 'function' ) {
187193 if ( ! this.orig_onsubmit() ) {
@@ -202,17 +208,21 @@
203209 mw.log( 'form_post_override is true, do ordinary form submit' );
204210 return true;
205211 }
206 -
207 - // Put into a try catch so we are sure to return false:
 212+ mw.log(" about to run try / catch " );
 213+ // Put into a try catch so we are sure to return false:
208214 try {
209215 // Startup interface dispatch dialog
210 - _this.ui.setup( {'title': gM('mwe-upload-in-progress') } );
 216+ _this.ui.setup( { 'title' : gM( 'mwe-upload-in-progress' ) } );
211217
 218+ mw.log('ui.setup done ' );
 219+
212220 // Drop down the #p-search z-index so its not ontop
213221 $j( '#p-search' ).css( 'z-index', 1 );
214222
215223 var _this = this;
 224+
216225 _this.detectUploadMode( function( mode ) {
 226+ mw.log("detectUploadMode callback" );
217227 _this.upload_mode = mode;
218228 _this.doUpload();
219229 } );
@@ -293,8 +303,7 @@
294304 * Do an upload, with the mode given by this.upload_mode
295305 */
296306 doUpload: function() {
297 - // Note "api" should be called "http_copy_upload" and /post/ should be "form_upload"
298 - this.uploadBeginTime = (new Date()).getTime();
 307+ // Note "api" should be called "http_copy_upload" and /post/ should be "form_upload"
299308 if ( this.upload_mode == 'api' ) {
300309 this.doApiCopyUpload();
301310 } else if ( this.upload_mode == 'post' ) {
@@ -329,7 +338,7 @@
330339 try {
331340 $form.attr('action', _this.api_url);
332341 } catch( e ) {
333 - mw.log("IE for some reason error's out when you change the action")
 342+ mw.log( "IE sometimes errors out when you change the action" );
334343 }
335344
336345 // Add API action
@@ -365,220 +374,8 @@
366375 $form.find( "[name='wpWatchthis']" ).attr( 'name', 'watch' );
367376
368377 //mw.log( 'comment: ' + $form.find( "[name='comment']" ).val() );
369 - },
370 -
371 - /**
372 - * Given the result of an action=upload API request, display the error message
373 - * to the user.
374 - *
375 - * @param {Object} apiRes The result object
376 - */
377 - showApiError: function( apiRes ) {
378 - var _this = this;
379 - if ( apiRes.error || ( apiRes.upload && apiRes.upload.result == "Failure" ) ) {
380 - // Generate the error button
381 -
382 - var buttons = {};
383 - buttons[ gM( 'mwe-return-to-form' ) ] = function() {
384 - _this.form_post_override = false;
385 - $j( this ).dialog( 'close' );
386 - };
 378+ },
387379
388 - // Check a few places for the error code
389 - var error_code = 0;
390 - var errorReplaceArg = '';
391 - if ( apiRes.error && apiRes.error.code ) {
392 - error_code = apiRes.error.code;
393 - } else if ( apiRes.upload.code ) {
394 - if ( typeof apiRes.upload.code == 'object' ) {
395 - if ( apiRes.upload.code[0] ) {
396 - error_code = apiRes.upload.code[0];
397 - }
398 - if ( apiRes.upload.code['status'] ) {
399 - error_code = apiRes.upload.code['status'];
400 - if ( apiRes.upload.code['filtered'] )
401 - errorReplaceArg = apiRes.upload.code['filtered'];
402 - }
403 - } else {
404 - apiRes.upload.code;
405 - }
406 - }
407 -
408 - var error_msg = '';
409 - if ( typeof apiRes.error == 'string' )
410 - error_msg = apiRes.error;
411 -
412 - // There are many possible error messages here, so we don't load all
413 - // message text in advance, instead we use mw.getRemoteMsg() for some.
414 - //
415 - // This code is similar to the error handling code formerly in
416 - // SpecialUpload::processUpload()
417 - var error_msg_key = {
418 - '2' : 'largefileserver',
419 - '3' : 'emptyfile',
420 - '4' : 'minlength1',
421 - '5' : 'illegalfilename'
422 - };
423 -
424 - // NOTE:: handle these error types
425 - var error_onlykey = {
426 - '1': 'BEFORE_PROCESSING',
427 - '6': 'PROTECTED_PAGE',
428 - '7': 'OVERWRITE_EXISTING_FILE',
429 - '8': 'FILETYPE_MISSING',
430 - '9': 'FILETYPE_BADTYPE',
431 - '10': 'VERIFICATION_ERROR',
432 - '11': 'UPLOAD_VERIFICATION_ERROR',
433 - '12': 'UPLOAD_WARNING',
434 - '13': 'INTERNAL_ERROR',
435 - '14': 'MIN_LENGTH_PARTNAME'
436 - }
437 -
438 - if ( !error_code || error_code == 'unknown-error' ) {
439 - if ( typeof JSON != 'undefined' ) {
440 - mw.log( 'Error: apiRes: ' + JSON.stringify( apiRes ) );
441 - }
442 - if ( apiRes.upload.error == 'internal-error' ) {
443 - // Do a remote message load
444 - errorKey = apiRes.upload.details[0];
445 - mw.getRemoteMsg( errorKey, function() {
446 - _this.ui.setPrompt( gM( 'mwe-uploaderror' ), gM( errorKey ), buttons );
447 -
448 - });
449 - return false;
450 - }
451 -
452 - _this.ui.setPrompt(
453 - gM('mwe-uploaderror'),
454 - gM('mwe-unknown-error') + '<br>' + error_msg,
455 - buttons );
456 - return false;
457 - }
458 -
459 - if ( apiRes.error && apiRes.error.info ) {
460 - _this.ui.setPrompt( gM( 'mwe-uploaderror' ), apiRes.error.info, buttons );
461 - return false;
462 - }
463 -
464 - if ( typeof error_code == 'number'
465 - && typeof error_msg_key[error_code] == 'undefined' )
466 - {
467 - if ( apiRes.upload.code.finalExt ) {
468 - _this.ui.setPrompt(
469 - gM( 'mwe-uploaderror' ),
470 - gM( 'mwe-wgfogg_warning_bad_extension', apiRes.upload.code.finalExt ),
471 - buttons );
472 - } else {
473 - _this.ui.setPrompt(
474 - gM( 'mwe-uploaderror' ),
475 - gM( 'mwe-unknown-error' ) + ' : ' + error_code,
476 - buttons );
477 - }
478 - return false;
479 - }
480 -
481 - mw.log( 'get key: ' + error_msg_key[ error_code ] )
482 - mw.getRemoteMsg( error_msg_key[ error_code ], function() {
483 - _this.ui.setPrompt(
484 - gM( 'mwe-uploaderror' ),
485 - gM( error_msg_key[ error_code ], errorReplaceArg ),
486 - buttons );
487 - });
488 - mw.log( "api.error" );
489 - return false;
490 - }
491 -
492 - // Check upload.error
493 - if ( apiRes.upload && apiRes.upload.error ) {
494 - mw.log( ' apiRes.upload.error: ' + apiRes.upload.error );
495 - _this.ui.setPrompt(
496 - gM( 'mwe-uploaderror' ),
497 - gM( 'mwe-unknown-error' ) + '<br>',
498 - buttons );
499 - return false;
500 - }
501 -
502 - // Check for warnings:
503 - if ( apiRes.upload && apiRes.upload.warnings ) {
504 - var wmsg = '<ul>';
505 - for ( var wtype in apiRes.upload.warnings ) {
506 - var winfo = apiRes.upload.warnings[wtype]
507 - wmsg += '<li>';
508 - switch ( wtype ) {
509 - case 'duplicate':
510 - case 'exists':
511 - if ( winfo[1] && winfo[1].title && winfo[1].title.mTextform ) {
512 - wmsg += gM( 'mwe-file-exists-duplicate' ) + ' ' +
513 - '<b>' + winfo[1].title.mTextform + '</b>';
514 - } else {
515 - //misc error (weird that winfo[1] not present
516 - wmsg += gM( 'mwe-upload-misc-error' ) + ' ' + wtype;
517 - }
518 - break;
519 - case 'file-thumbnail-no':
520 - wmsg += gM( 'mwe-file-thumbnail-no', winfo );
521 - break;
522 - default:
523 - wmsg += gM( 'mwe-upload-misc-error' ) + ' ' + wtype;
524 - break;
525 - }
526 - wmsg += '</li>';
527 - }
528 - wmsg += '</ul>';
529 - if ( apiRes.upload.sessionkey )
530 - _this.warnings_sessionkey = apiRes.upload.sessionkey;
531 -
532 - // Create the "ignore warning" button
533 - var buttons = {};
534 - buttons[ gM( 'mwe-ignorewarning' ) ] = function() {
535 - // Check if we have a stashed key:
536 - if ( _this.warnings_sessionkey ) {
537 - //set to "loading"
538 - $j( '#upProgressDialog' ).html( mw.loading_spinner() );
539 - //setup request:
540 - var request = {
541 - 'action': 'upload',
542 - 'sessionkey': _this.warnings_sessionkey,
543 - 'ignorewarnings': 1,
544 - 'filename': $j( '#wpDestFile' ).val(),
545 - 'token' : _this.editToken,
546 - 'comment' : _this.getUploadDescription()
547 - };
548 - //run the upload from stash request
549 - mw.getJSON(_this.api_url, request, function( data ) {
550 - _this.processApiResult( data );
551 - } );
552 - } else {
553 - mw.log( 'No session key re-sending upload' )
554 - //do a stashed upload
555 - $j( '#wpIgnoreWarning' ).attr( 'checked', true );
556 - $j( _this.editForm ).submit();
557 - }
558 - };
559 - // Create the "return to form" button
560 - buttons[ gM( 'mwe-return-to-form' ) ] = function() {
561 - $j( this ).dialog( 'close' );
562 - _this.form_post_override = false;
563 - }
564 - // Show warning
565 - _this.ui.setPrompt(
566 - gM( 'mwe-uploadwarning' ),
567 - $j('<div />')
568 - .append(
569 - $j( '<h3 />' )
570 - .text( gM( 'mwe-uploadwarning' ) ),
571 -
572 - $j('<span />')
573 - .html( wmsg )
574 - ),
575 - buttons );
576 - return false;
577 - }
578 - // No error!
579 - return true;
580 - },
581 -
582 -
583380 /**
584381 * Returns true if the current form has copy upload selected, false otherwise.
585382 */
@@ -600,17 +397,17 @@
601398 var _this = this;
602399 var $form = $j( _this.form );
603400 mw.log( 'mvBaseUploadHandler.doPostUpload' );
 401+
604402 // Issue a normal post request
605403 // Get the token from the page
606404 _this.editToken = $j( "#wpEditToken" ).val();
607405
608 - // TODO check for sendAsBinary to support Firefox/HTML5 progress on upload
609 -
 406+ // TODO check for sendAsBinary to support Firefox/HTML5 progress on upload
610407 this.ui.setLoading();
611408
612409 // Add the iframe
613410 _this.iframeId = 'f_' + ( $j( 'iframe' ).length + 1 );
614 - //IE only works if you "create element with the name" (not jquery style
 411+ //IE only works if you "create element with the name" ( not jquery style buildout )
615412 var iframe;
616413 try {
617414 iframe = document.createElement( '<iframe name="' + _this.iframeId + '">' );
@@ -705,10 +502,14 @@
706503 if ( license != '' ) {
707504 licensetxt = '== ' + gM( 'license-header' ) + " ==\n" + '{{' + license + '}}' + "\n";
708505 }
709 - pageText = '== ' + gM( 'filedesc' ) + " ==\n" + comment + "\n" +
710 - '== ' + gM( 'filestatus' ) + " ==\n" + copyStatus + "\n" +
711 - licensetxt +
712 - '== ' + gM( 'filesource' ) + " ==\n" . source ;
 506+ pageText = '== ' + gM( 'filedesc' ) + " ==\n" + comment + "\n";
 507+ if( copyStatus ){
 508+ pageText += '== ' + gM( 'filestatus' ) + " ==\n" + copyStatus + "\n" +
 509+ licensetxt;
 510+ }
 511+ if( source ){
 512+ pageText += '== ' + gM( 'filesource' ) + " ==\n" . source ;
 513+ }
713514 return pageText;
714515 },
715516
@@ -851,47 +652,23 @@
852653 return ;
853654 }
854655
855 - // Else update status:
 656+ // Update status:
856657 if ( data.upload['content_length'] && data.upload['loaded'] ) {
857658 // We have content length we can show percentage done:
858659 var fraction = data.upload['loaded'] / data.upload['content_length'];
859660 // Update the status:
860 - _this.ui.updateProgress( fraction );
861 - //special case update the file progress where we have data size:
862 - $j( '#up-status-container' ).html(
863 - gM( 'mwe-upload-stats-fileprogress',
864 - [
865 - mw.lang.formatSize( data.upload['loaded'] ),
866 - mw.lang.formatSize( data.upload['content_length'] )
867 - ]
868 - )
869 - );
870 - } else if( data.upload['loaded'] ) {
871 - _this.ui.updateProgress( 1 );
872 - mw.log( 'just have loaded (no cotent length: ' + data.upload['loaded'] );
873 - //for lack of content-length requests:
874 - $j( '#up-status-container' ).html(
875 - gM( 'mwe-upload-stats-fileprogress',
876 - [
877 - mw.lang.formatSize( data.upload['loaded'] ),
878 - gM( 'mwe-upload-unknown-size' )
879 - ]
880 - )
881 - );
 661+ _this.ui.updateProgress( fraction, data.upload['loaded'], data.upload['content_length'] );
 662+ } else if ( data.upload['loaded'] ) {
 663+ _this.ui.updateProgress( 1, data.upload['loaded'] );
 664+ mw.log( 'just have loaded ( no content length: ' + data.upload['loaded'] );
882665 }
883 - if ( _this.api_url == 'proxy' ) {
884 - // Do the updates a bit less often: every 4.2 seconds
885 - var timeout = 4200;
886 - } else {
887 - // We got a result: set timeout to 100ms + your server update
888 - // interval (in our case 2s)
889 - var timeout = 2100;
890 - }
891 - setTimeout(
892 - function() {
893 - _this.onAjaxUploadStatusTimer();
894 - },
895 - timeout );
 666+
 667+ // We got a result: set timeout to 100ms + your server update
 668+ // interval (in our case 2s)
 669+ var timeout = 2100;
 670+ setTimeout( function() {
 671+ _this.onAjaxUploadStatusTimer();
 672+ }, timeout );
896673 },
897674
898675 /**
@@ -922,25 +699,31 @@
923700 */
924701 processApiResult: function( apiRes ) {
925702 var _this = this;
926 - mw.log( 'processApiResult::' );
 703+ mw.log( 'processApiResult::' + JSON.stringify( apiRes ) );
927704
928705 if ( !_this.isApiSuccess( apiRes ) ) {
 706+
 707+ // Set the local warnings_sessionkey for warnings
 708+ if ( apiRes.upload && apiRes.upload.sessionkey ) {
 709+ _this.warnings_sessionkey = apiRes.upload.sessionkey;
 710+ }
 711+
929712 // Error detected, show it to the user
930 - _this.showApiError( apiRes );
 713+ _this.ui.showApiError( apiRes );
 714+
931715 return false;
932716 }
 717+
 718+ // See if we have a session key without warning
933719 if ( apiRes.upload && apiRes.upload.upload_session_key ) {
934720 // Async upload, do AJAX status polling
935721 _this.upload_session_key = apiRes.upload.upload_session_key;
936722 _this.doAjaxUploadStatus();
937723 mw.log( "set upload_session_key: " + _this.upload_session_key );
938 - return;
 724+ return true;
939725 }
940726
941 - if ( apiRes.upload && apiRes.upload.imageinfo && apiRes.upload.imageinfo.descriptionurl ) {
942 - var url = apiRes.upload.imageinfo.descriptionurl;
943 -
944 - // Upload complete.
 727+ if ( apiRes.upload && apiRes.upload.imageinfo && apiRes.upload.imageinfo.descriptionurl ) {
945728 // Call the completion callback if available.
946729 if ( _this.done_upload_cb && typeof _this.done_upload_cb == 'function' ) {
947730 mw.log( "call done_upload_cb" );
@@ -949,30 +732,68 @@
950733 // dialog immediately.
951734 _this.ui.close();
952735 _this.done_upload_cb( apiRes.upload );
953 - return false;
 736+ return true;
954737 }
955 -
956 - var buttons = {};
957 - // "Return" button
958 - buttons[ gM( 'mwe-return-to-form' ) ] = function() {
959 - $j( this ).dialog( 'destroy' ).remove();
960 - _this.form_post_override = false;
961 - }
962 - // "Go to resource" button
963 - buttons[ gM('mwe-go-to-resource') ] = function() {
964 - window.location = url;
965 - };
966 - _this.action_done = true;
967 - _this.ui.setPrompt(
968 - gM( 'mwe-successfulupload' ),
969 - gM( 'mwe-upload_done', url),
970 - buttons );
971 - mw.log( 'apiRes.upload.imageinfo::' + url );
 738+
 739+ // Else pass off the api Success to interface:
 740+ _this.ui.showApiSuccess( apiRes );
972741 return true;
973742 }
974743 },
975744
976745 /**
 746+ * Receives upload interface "action" requests from the "ui"
 747+ *
 748+ * For example ignorewarning
 749+ */
 750+ uploadHandlerAction : function( action ){
 751+ mw.log( "UploadHandler :: action:: " + action + ' sw: ' + this.warnings_sessionkey );
 752+ switch( action ){
 753+ case 'ignoreWarnings':
 754+ this.ignoreWarningsSubmit();
 755+ break;
 756+ case 'disableFormPostOverride':
 757+ this.form_post_override = false;
 758+ break;
 759+ default:
 760+ mw.log( "Error reciveUploadAction:: unkown action: " + action );
 761+ break;
 762+ }
 763+ },
 764+
 765+ /**
 766+ * Do ignore warnings submit.
 767+ *
 768+ * Must have set warnings_sessionkey
 769+ */
 770+ ignoreWarningsSubmit: function( ) {
 771+ var _this = this;
 772+ // Check if we have a stashed key:
 773+ if ( _this.warnings_sessionkey !== false ) {
 774+ //set to "loading"
 775+ $j( '#upProgressDialog' ).html( mw.loading_spinner() );
 776+ //setup request:
 777+ var request = {
 778+ 'action': 'upload',
 779+ 'sessionkey': _this.warnings_sessionkey,
 780+ 'ignorewarnings': 1,
 781+ 'filename': $j( '#wpDestFile' ).val(),
 782+ 'token' : _this.editToken,
 783+ 'comment' : _this.getUploadDescription()
 784+ };
 785+ //run the upload from stash request
 786+ mw.getJSON(_this.api_url, request, function( data ) {
 787+ _this.processApiResult( data );
 788+ } );
 789+ } else {
 790+ mw.log( 'No session key re-sending upload' )
 791+ //do a stashed upload
 792+ $j( '#wpIgnoreWarning' ).attr( 'checked', true );
 793+ $j( _this.editForm ).submit();
 794+ }
 795+ },
 796+
 797+ /**
977798 * Get the default title of the progress window
978799 */
979800 getProgressTitle: function() {
@@ -998,6 +819,7 @@
999820 // jQuery plugins
1000821
1001822 ( function( $ ) {
 823+
1002824 /**
1003825 * Check the upload destination filename for conflicts and show a conflict
1004826 * error message if there is one
Index: branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/mw.UploadInterface.js
@@ -13,7 +13,11 @@
1414 * Dispatches updates to an iframe target for upload proxy
1515 *
1616 */
17 -
 17+mw.addMessages({
 18+ "mwe-upload-in-progress" : "Upload in progress (do not close this window)",
 19+ "mwe-uploaded-status" : "Uploaded",
 20+ "mwe-uploaded-time-remaining" : "Time remaining: $1",
 21+});
1822 /**
1923 * Base UploadInterface object
2024 */
@@ -23,7 +27,11 @@
2428 /**
2529 * Dialog Interface
2630 */
27 -mw.DialogInterface = function( ) {
 31+mw.DialogInterface = function( uploadHandler ) {
 32+ // Set a reference the uploadHandler if provided
 33+ if( uploadHandler ) {
 34+ this.uploadHandler = uploadHandler;
 35+ }
2836 return this;
2937 }
3038 mw.DialogInterface.prototype = {
@@ -126,8 +134,10 @@
127135 * Update the progress bar to a given completion fraction (between 0 and 1)
128136 * NOTE: This progress bar is used for encoding AND for upload with no clear Distinction (might want to fix)
129137 * @param {Float} progress Progress float
 138+ * @param {Number} [loaded] Bytes loaded
 139+ * @param {Number} [contentLength] Length of content
130140 */
131 - updateProgress: function( fraction ) {
 141+ updateProgress: function( fraction, loaded, contentLength ) {
132142 var _this = this;
133143
134144 $j( '#up-progressbar' ).progressbar( 'value', parseInt( fraction * 100 ) );
@@ -141,6 +151,25 @@
142152 $j( '#up-etr' ).html( gM( 'mwe-uploaded-time-remaining', mw.seconds2npt( remainingSeconds ) ) );
143153 }
144154 }
 155+ if( loaded && contentLength ){
 156+ $j( '#up-status-container' ).text(
 157+ gM( 'mwe-upload-stats-fileprogress',
 158+ [
 159+ mw.lang.formatSize( data.upload['loaded'] ),
 160+ mw.lang.formatSize( data.upload['content_length'] )
 161+ ]
 162+ )
 163+ );
 164+ } else if ( loaded ){
 165+ $j( '#up-status-container' ).text(
 166+ gM( 'mwe-upload-stats-fileprogress',
 167+ [
 168+ mw.lang.formatSize( data.upload['loaded'] ),
 169+ gM( 'mwe-upload-unknown-size' )
 170+ ]
 171+ )
 172+ );
 173+ }
145174
146175 },
147176
@@ -161,7 +190,7 @@
162191 * Set the dialog to loading
163192 * @param optional loadingText text to set dialog to.
164193 */
165 - setLoading: function( loadingText ) {
 194+ setLoading: function( ) {
166195 this.action_done = false;
167196 //Update the progress dialog (no bar without XHR request)
168197 $j( '#upProgressDialog' ).loadingSpinner();
@@ -191,12 +220,226 @@
192221 $j( this ).dialog( 'close' ).remove();
193222 };
194223 }
 224+
195225 $j( '#upProgressDialog' ).dialog( 'option', 'title', title_txt );
196226 $j( '#upProgressDialog' ).html( msg );
197227 $j( '#upProgressDialog' ).dialog( 'option', 'buttons', buttons );
198228 },
199229
 230+
200231 /**
 232+ * Given the result of an action=upload API request, display the error message
 233+ * to the user.
 234+ *
 235+ * @param {Object} apiRes The result object
 236+ */
 237+ showApiError: function( apiRes ) {
 238+ var _this = this;
 239+ // NOTE: this could be simplified and cleaned up
 240+ // by simplified the error output provided by the upload api
 241+
 242+ // Generate the error button
 243+ var buttons = {};
 244+ buttons[ gM( 'mwe-return-to-form' ) ] = function() {
 245+ _this.form_post_override = false;
 246+ $j( this ).dialog( 'close' );
 247+ };
 248+
 249+
 250+ if ( apiRes.error || ( apiRes.upload && apiRes.upload.result == "Failure" ) ) {
 251+
 252+ // Check a few places for the error code
 253+ var error_code = 0;
 254+ var errorReplaceArg = '';
 255+ if ( apiRes.error && apiRes.error.code ) {
 256+ error_code = apiRes.error.code;
 257+ } else if ( apiRes.upload.code && typeof apiRes.upload.code == 'object' ) {
 258+ if ( apiRes.upload.code[0] ) {
 259+ error_code = apiRes.upload.code[0];
 260+ }
 261+ if ( apiRes.upload.code['status'] ) {
 262+ error_code = apiRes.upload.code['status'];
 263+ if ( apiRes.upload.code['filtered'] ){
 264+ errorReplaceArg = apiRes.upload.code['filtered'];
 265+ }
 266+ }
 267+ }
 268+
 269+ var error_msg = '';
 270+ if ( typeof apiRes.error == 'string' ){
 271+ error_msg = apiRes.error;
 272+ }
 273+ // There are many possible error messages here, so we don't load all
 274+ // message text in advance, instead we use mw.getRemoteMsg() for some.
 275+ //
 276+ // This code is similar to the error handling code formerly in
 277+ // SpecialUpload::processUpload()
 278+ var error_msg_key = {
 279+ '2' : 'largefileserver',
 280+ '3' : 'emptyfile',
 281+ '4' : 'minlength1',
 282+ '5' : 'illegalfilename'
 283+ };
 284+
 285+ if ( typeof error_code == 'number'
 286+ && typeof error_msg_key[ error_code ] == 'undefined' )
 287+ {
 288+ if ( apiRes.upload.code.finalExt ) {
 289+ _this.setPrompt(
 290+ gM( 'mwe-uploaderror' ),
 291+ gM( 'mwe-wgfogg_warning_bad_extension', apiRes.upload.code.finalExt ),
 292+ buttons );
 293+ } else {
 294+ _this.setPrompt(
 295+ gM( 'mwe-uploaderror' ),
 296+ gM( 'mwe-unknown-error' ) + ' : ' + error_code,
 297+ buttons );
 298+ }
 299+ return false;
 300+ }
 301+
 302+ // If no "error_code" was provided or it is an unknown-error
 303+ // try to use the errorKey in apiRes.upload.details
 304+ if ( !error_code || error_code == 'unknown-error' ) {
 305+ if ( apiRes.upload.error == 'internal-error' ) {
 306+ // Do a remote message load
 307+ errorKey = apiRes.upload.details[0];
 308+ mw.getRemoteMsg( errorKey, function() {
 309+ _this.setPrompt( gM( 'mwe-uploaderror' ), gM( errorKey ), buttons );
 310+ });
 311+ return false;
 312+ }
 313+ _this.setPrompt(
 314+ gM('mwe-uploaderror'),
 315+ gM('mwe-unknown-error') + '<br>' + error_msg,
 316+ buttons
 317+ );
 318+ return false;
 319+ }
 320+
 321+ // This is the ideal error handling,
 322+ // if apiRes consistently provided error.info
 323+ if ( apiRes.error && apiRes.error.info ) {
 324+ _this.setPrompt( gM( 'mwe-uploaderror' ), apiRes.error.info, buttons );
 325+ return false;
 326+ }
 327+
 328+ mw.log( 'get remote error key: ' + error_msg_key[ error_code ] )
 329+ mw.getRemoteMsg( error_msg_key[ error_code ], function() {
 330+ _this.setPrompt(
 331+ gM( 'mwe-uploaderror' ),
 332+ gM( error_msg_key[ error_code ], errorReplaceArg ),
 333+ buttons );
 334+ });
 335+ mw.log( "api.error" );
 336+ return false;
 337+ }
 338+
 339+ // If nothing above was able to set the error
 340+ // set simple unknown-error
 341+ if ( apiRes.upload && apiRes.upload.error ) {
 342+ mw.log( ' apiRes.upload.error: ' + apiRes.upload.error );
 343+ _this.setPrompt(
 344+ gM( 'mwe-uploaderror' ),
 345+ gM( 'mwe-unknown-error' ) + '<br>',
 346+ buttons );
 347+ return false;
 348+ }
 349+
 350+ // Check for warnings:
 351+ if ( apiRes.upload && apiRes.upload.warnings ) {
 352+ var wmsg = '<ul>';
 353+ for ( var wtype in apiRes.upload.warnings ) {
 354+ var winfo = apiRes.upload.warnings[wtype]
 355+ wmsg += '<li>';
 356+ switch ( wtype ) {
 357+ case 'duplicate':
 358+ case 'exists':
 359+ if ( winfo[1] && winfo[1].title && winfo[1].title.mTextform ) {
 360+ wmsg += gM( 'mwe-file-exists-duplicate' ) + ' ' +
 361+ '<b>' + winfo[1].title.mTextform + '</b>';
 362+ } else {
 363+ //misc error (weird that winfo[1] not present
 364+ wmsg += gM( 'mwe-upload-misc-error' ) + ' ' + wtype;
 365+ }
 366+ break;
 367+ case 'file-thumbnail-no':
 368+ wmsg += gM( 'mwe-file-thumbnail-no', winfo );
 369+ break;
 370+ default:
 371+ wmsg += gM( 'mwe-upload-misc-error' ) + ' ' + wtype;
 372+ break;
 373+ }
 374+ wmsg += '</li>';
 375+ }
 376+ wmsg += '</ul>';
 377+
 378+
 379+ // Create the "ignore warning" button
 380+ var buttons = {};
 381+ buttons[ gM( 'mwe-ignorewarning' ) ] = function() {
 382+ // call the upload object ignore warnings:
 383+ _this.sendUploadAction( 'ignoreWarnings' );
 384+ };
 385+ // Create the "return to form" button
 386+ buttons[ gM( 'mwe-return-to-form' ) ] = function() {
 387+ $j( this ).dialog( 'close' );
 388+ _this.sendUploadAction( 'disableFormPostOverride' );
 389+ }
 390+ // Show warning
 391+ _this.setPrompt(
 392+ gM( 'mwe-uploadwarning' ),
 393+ $j('<div />')
 394+ .append(
 395+ $j( '<h3 />' )
 396+ .text( gM( 'mwe-uploadwarning' ) ),
 397+
 398+ $j('<span />')
 399+ .html( wmsg )
 400+ ),
 401+ buttons );
 402+ return false;
 403+ }
 404+ // No error!
 405+ return true;
 406+ },
 407+
 408+ /**
 409+ * Send an upload action to the upload handler.
 410+ * @param {Object} action
 411+ */
 412+ sendUploadAction: function( action ) {
 413+ this.uploadHandler.uploadHandlerAction( action );
 414+ },
 415+
 416+ /**
 417+ * Shows api success from a apiResult
 418+ */
 419+ showApiSuccess: function( apiRes ){
 420+ mw.log( " UI:: showApiSuccess: " );
 421+ // set the target resource url:
 422+ var url = apiRes.upload.imageinfo.descriptionurl;
 423+ var _this = this;
 424+ var buttons = {};
 425+ // "Return" button
 426+ buttons[ gM( 'mwe-return-to-form' ) ] = function() {
 427+ $j( this ).dialog( 'destroy' ).remove();
 428+ _this.sendUploadAction( 'disableFormPostOverride' );
 429+ }
 430+ // "Go to resource" button
 431+ buttons[ gM('mwe-go-to-resource') ] = function() {
 432+ window.location = url;
 433+ };
 434+ _this.action_done = true;
 435+ _this.setPrompt(
 436+ gM( 'mwe-successfulupload' ),
 437+ gM( 'mwe-upload_done', url),
 438+ buttons
 439+ );
 440+ mw.log( 'apiRes.upload.imageinfo::' + url );
 441+ },
 442+
 443+ /**
201444 * Set the dialog to "done"
202445 */
203446 close: function() {
@@ -241,19 +484,25 @@
242485 this.callbackProxy( 'setup', options );
243486 },
244487
245 - // Don't call update progress more than once every 4 seconds
 488+ // Don't call update progress more than once every 3 seconds
246489 // Since it involves loading a cached iframe. Once we support html5
247490 // cross domain "sendMsg" then we can pass all updates
248491 updateProgress: function( fraction ) {
249 - if( ( new Date() ).getTime() - this.lastProgressTime > 4000 ){
250 - this.lastProgressTime = ( new Date() ).getTime()
251 - mw.log('do update progress' );
 492+ if( ( new Date() ).getTime() - this.lastProgressTime > 3000 ){
 493+ this.lastProgressTime = ( new Date() ).getTime()
252494 this.callbackProxy( 'updateProgress', fraction );
253495 }
254496 },
255 -
256 - setPrompt: function( title_txt, msg, buttons ) {
257 - // @@todo fix button isssue:
258 - this.callbackProxy( 'setPrompt', title_txt, msg, buttons );
259 - }
 497+ // Pass on the show api errror:
 498+ showApiError: function ( apiRes ){
 499+ this.callbackProxy( 'showApiError', apiRes );
 500+ },
 501+ // Pass on the show api success:
 502+ showApiSuccess: function ( apiRes ) {
 503+ this.callbackProxy( 'showApiSuccess', apiRes );
 504+ },
 505+ // Pass on api action
 506+ sendUploadAction: function( action ) {
 507+ this.callbackProxy( 'sendUploadAction', action );
 508+ }
260509 };
Index: branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/mw.Firefogg.js
@@ -107,8 +107,8 @@
108108
109109 if ( myFogg ) {
110110 myFogg.doRewrite( );
111 - var selectorElement = $j( options.selector ).get( 0 );
112 - selectorElement[ 'firefogg' ] = myFogg;
 111+ var selectorElement = $j( this.selector ).get( 0 );
 112+ selectorElement[ 'uploadHandler' ] = myFogg;
113113 }
114114 }
115115 } )( jQuery );
@@ -171,13 +171,17 @@
172172
173173 // Prefix conflicting members with parent_
174174 for ( var i in myBUI ) {
175 - if ( this[i] ) {
 175+ if ( this[ i ] ) {
176176 this[ 'parent_'+ i ] = myBUI[i];
177177 } else {
178 - this[i] = myBUI[i];
 178+ this[ i ] = myBUI[i];
179179 }
180180 }
181181 }
 182+
 183+ // Setup ui uploadHandler pointer
 184+ this.ui.uploadHandler = this;
 185+
182186 if ( !this.selector ) {
183187 mw.log('firefogg: missing selector ');
184188 }
@@ -1140,7 +1144,13 @@
11411145 }
11421146 }
11431147
1144 - //Check for success:
 1148+ // Process the api result ( if not a chunk )
 1149+ if( ! apiResult.resultUrl ){
 1150+ _this.processApiResult ( apiResult );
 1151+ return true;
 1152+ }
 1153+
 1154+ /*
11451155 if( apiResult && _this.isApiSuccess( apiResult ) ) {
11461156 if( _this.processApiResult ( apiResult ) ) {
11471157 return true;
@@ -1149,11 +1159,12 @@
11501160
11511161 if ( apiResult && !_this.isApiSuccess( apiResult ) ) {
11521162 // Show the error and stop the upload
1153 - _this.showApiError( apiResult );
 1163+ _this.ui.showApiError( apiResult );
11541164 _this.action_done = true;
11551165 _this.fogg.cancel();
11561166 return false;
11571167 }
 1168+ */
11581169
11591170 }
11601171 // Show the video preview if encoding and show_preview is enabled.
@@ -1178,7 +1189,7 @@
11791190 }
11801191 // Chunk upload mode:
11811192 if ( apiResult && apiResult.resultUrl ) {
1182 - var buttons = {};
 1193+ var buttons = { };
11831194 buttons[ gM( 'mwe-go-to-resource' ) ] = function() {
11841195 window.location = apiResult.resultUrl;
11851196 }
Index: branches/js2-work/phase3/js/mwEmbed/modules/EmbedPlayer/mw.EmbedPlayer.js
@@ -1522,7 +1522,7 @@
15231523 var missingType = '';
15241524 var or = '';
15251525 for ( var i = 0; i < this.mediaElement.sources.length; i++ ) {
1526 - missing_type += or + this.mediaElement.sources[i].mime_type;
 1526+ missingType += or + this.mediaElement.sources[i].mime_type;
15271527 or = ' or ';
15281528 }
15291529 // Get from parent playlist if set:
Index: branches/js2-work/phase3/js/mwEmbed/modules/ApiProxy/mw.ApiProxy.js
@@ -57,7 +57,7 @@
5858 var currentApiReq = { };
5959
6060 // The url for the last api request target.
61 - var currentApiUrl = null;
 61+ var currentServerApiUrl = null;
6262
6363 // Time we should wait for proxy page callback
6464 // ( note this time starts form when the page is "done"
@@ -92,7 +92,7 @@
9393 // ( presently the api proxy only support sequential requests
9494 // for multiple simultaneous requests we will need to do some minor refactoring )
9595 currentApiReq = requestQuery;
96 - currentApiUrl = apiUrl;
 96+ currentServerApiUrl = apiUrl;
9797
9898 // Setup the callback:
9999 proxyCallback = callback;
@@ -157,7 +157,7 @@
158158 }
159159
160160 // Update the current apiUrl:
161 - currentApiUrl = options.api_url;
 161+ currentServerApiUrl = options.api_url;
162162
163163 if( ! options.width ) {
164164 options.width = 270;
@@ -179,7 +179,7 @@
180180 // Empty the target ( so that the iframe can be put there )
181181 $j( options.target ).empty();
182182
183 - // Append the iframe to the target:
 183+ // Append the browseFile iframe to the target:
184184 appendIframe( {
185185 'persist' : true,
186186 'style' : frameStyle,
@@ -190,7 +190,7 @@
191191 }, function( ) {
192192 // Add a 10 second timeout for setting up the nested child callback (after iframe load)
193193 setTimeout( function() {
194 - if ( !frameProxyOk ) {
 194+ if ( ! frameProxyOk ) {
195195 // we timmed out no api proxy (should make sure the user is "logged in")
196196 mw.log( "Error:: api proxy timeout are we logged in? mwEmbed is on?" );
197197 proxyNotReadyDialog();
@@ -202,11 +202,24 @@
203203 $j('<div />').loadingSpinner()
204204 );
205205
206 - var uploadDialogInterface = new mw.DialogInterface();
 206+ var uploadDialogInterface = new mw.DialogInterface({
 207+ 'uploadHandlerAction' : function( action ){
 208+ mw.log( 'apiProxy uploadActionHandler:: ' + action );
 209+ // Send action to remote frame
 210+ mw.ApiProxy.sendServerMsg( {
 211+ 'api_url' : options.api_url,
 212+ 'frameName' : iFrameName,
 213+ 'frameMsg' : {
 214+ 'action' : 'uploadHandlerAction',
 215+ 'uiAction' : action
 216+ }
 217+ } );
 218+ }
 219+ });
207220
208221 // Setup the proxy scope callback to display the upload unhide the iframe upload form
209222 proxyCallback = function( iframeData ) {
210 - // proccess fileBrowse callbacks::
 223+ // Process fileBrowse callbacks ::
211224
212225 // check for basic status "ok"
213226 if( iframeData['status'] == 'ok' ) {
@@ -293,7 +306,10 @@
294307 switch( frameMsg.action ){
295308 case 'fileSubmit':
296309 serverSubmitFile( frameMsg.formData );
297 - break;
 310+ break;
 311+ case 'uploadHandlerAction':
 312+ serverSendUploadHandlerAction( frameMsg.uiAction );
 313+ break;
298314 }
299315 }
300316
@@ -342,9 +358,9 @@
343359 //var gadgetWithJS = '?withJS=MediaWiki:Gadget-mwEmbed.js';
344360 var gadgetWithJS = '';
345361 function getServerFrame( apiUrl ) {
346 - // Set to local scope currentApiUrl if unset by argument
 362+ // Set to local scope currentServerApiUrl if unset by argument
347363 if( !apiUrl) {
348 - apiUrl = currentApiUrl;
 364+ apiUrl = currentServerApiUrl;
349365 }
350366 var parsedUrl = mw.parseUri( apiUrl );
351367
@@ -607,7 +623,7 @@
608624 mw.load( 'AddMedia.UploadHandler', function() {
609625 var uploadConfig = getUploadFileConfig();
610626
611 - $j( 'mw-upload-form' ).uploadHandler( uploadConfig );
 627+ $j( '#mw-upload-form' ).uploadHandler( uploadConfig );
612628
613629 // Update status
614630 sendClientMsg( {'status':'ok'} );
@@ -653,7 +669,7 @@
654670 }
655671
656672 /**
657 - * Browse file upload config gennerator
 673+ * Browse file upload config generator
658674 */
659675 function getUploadFileConfig(){
660676 var uploadIframeUI = new mw.UploadIframeUI( function( method ){
@@ -682,6 +698,21 @@
683699 }
684700 return uploadConfig;
685701 }
 702+
 703+ /**
 704+ * Server send interface action
 705+ */
 706+ function serverSendUploadHandlerAction( action ) {
 707+ // Get a refrence to the uploadHandler:
 708+ // NOTE: this should not be hard-coded
 709+ var selector = ( wgEnableFirefogg ) ? '#wpUploadFile' : '#mw-upload-form';
 710+ var uploadHandler = $j( selector ).get(0).uploadHandler;
 711+ if( uploadHandler ){
 712+ uploadHandler.uploadHandlerAction( action );
 713+ } else {
 714+ mw.log( "Error: could not find upload handler" );
 715+ }
 716+ }
686717
687718 /**
688719 * Server submit file
@@ -695,6 +726,7 @@
696727 $form.append(
697728 $j( '<input />' )
698729 .attr( {
 730+ 'id' : 'wpDestFile',
699731 'name' : 'filename',
700732 'type' : 'hidden'
701733 } )
@@ -704,7 +736,8 @@
705737 $form.append(
706738 $j( '<input />' )
707739 .attr( {
708 - 'name' : 'description',
 740+ 'id' : 'wpUploadDescription',
 741+ 'name' : 'comment',
709742 'type' : 'hidden'
710743 } )
711744 );
@@ -721,6 +754,7 @@
722755 // Do submit the form
723756 $form.submit();
724757 };
 758+
725759 /**
726760 * Outputs the result object to the client domain
727761 *

Status & tagging log