'allowed' => $wgFileExtensions
) );
break;
- case UploadBase::MIN_LENGHT_PARTNAME:
+ case UploadBase::MIN_LENGTH_PARTNAME:
$this->dieUsage( 'The filename is too short', 'filename-tooshort' );
break;
case UploadBase::ILLEGAL_FILENAME:
const VERIFICATION_ERROR = 10;
const UPLOAD_VERIFICATION_ERROR = 11;
const HOOK_ABORTED = 11;
- const MIN_LENGHT_PARTNAME = 14;
const SESSION_VERSION = 2;
/*
- * Adds advanced firefogg support (let you control and structure advanced controls over many aspects of video encoding)
+ * Advanced Firefogg support. Lets you control many aspects of video encoding.
*/
//@@todo put all msg text into loadGM json
"fogg-cg-advAudio" : "Advanced audio encoding controls",
"fogg-preset-custom" : "Custom settings",
"fogg-webvideo-desc" : "Web video Theora, Vorbis 400 kbit\/s and 400px maximum width",
- "fogg-savebandwith-desc" : "Low bandwith Theora, Vorbis 164 kbit\/s and 200px maximum width",
+ "fogg-savebandwidth-desc" : "Low bandwidth Theora, Vorbis 164 kbit\/s and 200px maximum width",
"fogg-highquality-desc" : "High quality Theora, Vorbis 1080px maximum width",
"fogg-videoQuality-title" : "Video quality",
"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).",
"fogg-framerate-title" : "Frame rate",
"fogg-framerate-help" : "The video frame rate. More about <a target=\"_new\" href=\"http:\/\/en.wikipedia.org\/wiki\/Frame_rate\">frame rate<\/a>.",
"fogg-aspect-title" : "Aspect ratio",
- "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>.",
+ "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>.",
"fogg-keyframeInterval-title" : "Key frame interval",
"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>.",
"fogg-denoise-title" : "Denoise filter",
"fogg-novideo-help" : "disable video in the output",
"fogg-audioBitrate-title" : "Audio bitrate",
"fogg-samplerate-title" : "Audio sampling rate",
- "fogg-samplerate-help" : "set output samplerate (in Hz).",
+ "fogg-samplerate-help" : "set output sample rate (in Hz).",
"fogg-noaudio-title" : "No audio",
"fogg-noaudio-help" : "disable audio in the output",
"fogg-title-title" : "Title",
"fogg-contact-help" : "Contact link"
});
-var mvAdvFirefogg = function( iObj ){
+var mvAdvFirefogg = function( iObj ) {
return this.init( iObj );
}
var default_mvAdvFirefogg_config = {
- // Which config groups to include
- 'config_groups' : ['preset', 'range', 'quality', 'meta', 'advVideo', 'advAudio'],
+ // Config groups to include
+ 'config_groups': [ 'preset', 'range', 'quality', 'meta', 'advVideo', 'advAudio' ],
// If you want to load any custom presets must follow the mvAdvFirefogg.presetConf json outline below
- 'custom_presets' : {},
+ 'custom_presets': {},
- // Any firefog config properties that may need to be excluded from options
- 'exclude_settings' : [],
+ // Any Firefog config properties that may need to be excluded from options
+ 'exclude_settings': [],
- // The control container (where we put all the controls)
- 'target_control_container':false
+ // The control container
+ 'target_control_container': false
}
mvAdvFirefogg.prototype = {
- //the global groupings and titles for for configuration options :
- config_groups : [ 'preset', 'range', 'quality', 'meta', 'advVideo', 'advAudio'],
- //list of pre-sets:
-
- //local instance encoder config:
- default_local_settings:{
- 'd' : 'webvideo',
- 'type' : 'select',
+ // The configuration group names
+ config_groups: [ 'preset', 'range', 'quality', 'meta', 'advVideo', 'advAudio' ],
+
+ // Default configuration for this class
+ default_local_settings: {
+ 'default': 'webvideo',
+ 'type': 'select',
'selectVal': ['webvideo'],
- 'group' : "preset",
- 'pSet' : {
- 'custom':{
+ 'group': "preset",
+ 'presets': {
+ 'custom': {
'descKey': 'fogg-preset-custom',
'conf': {}
},
'webvideo': {
- 'desc': gM('fogg-webvideo-desc'),
+ 'desc': gM( 'fogg-webvideo-desc' ),
'conf': {
'maxSize' : 400,
'videoBitrate' : 544,
'noUpscaling' : true,
}
},
- 'savebandwith': {
- 'desc': gM('fogg-savebandwith-desc'),
+ 'savebandwidth': {
+ 'desc': gM( 'fogg-savebandwidth-desc' ),
'conf': {
'maxSize' : 200,
'videoBitrate' : 164,
'noUpscaling' : true
}
},
- 'hqstream':{
- 'desc': gM('fogg-highquality-desc'),
+ 'hqstream': {
+ 'desc': gM( 'fogg-highquality-desc' ),
'conf': {
'maxSize' : 1080,
'videoQuality' : 6,
},
}
},
- local_settings: {},
- //core firefogg default encoder configuration
- //see encoder options here: http://www.firefogg.org/dev/index.html
+ // Customised configuration hashtable
+ local_settings: {},
-
- default_encoder_config : {
- //base quality settings:
+ // Core Firefogg default encoder configuration
+ // See encoder options here: http://www.firefogg.org/dev/index.html
+ default_encoder_config: {
+ // Base quality settings
'videoQuality': {
- 'd' : 5,
- 'range' : {'min':0,'max':10},
- 'type' : 'slider',
- 'group' : 'quality'
+ 'default' : 5,
+ 'range' : { 'min': 0,'max': 10 },
+ 'type' : 'slider',
+ 'group' : 'quality'
},
- 'starttime':{
- 'type' : "float",
- 'group' : "range"
+ 'starttime': {
+ 'type' : "float",
+ 'group' : "range"
},
- 'endtime':{
- 'type' : "float",
- 'group' : "range"
+ 'endtime': {
+ 'type' : "float",
+ 'group' : "range"
},
'audioQuality': {
- 'd' : 1,
- 'range' : {'min':-1,'max':10},
- 'type' : 'slider',
- 'group' : 'quality',
+ 'default' : 1,
+ 'range' : { 'min': -1, 'max': 10 },
+ 'type' : 'slider',
+ 'group' : 'quality',
},
- 'videoCodec':{
- 'd' : "theora",
- 'selectVal' : ['theora'],
- 'type' : "select",
- 'group' : "quality"
+ 'videoCodec': {
+ 'default' : "theora",
+ 'selectVal' : [ 'theora' ],
+ 'type' : "select",
+ 'group' : "quality"
},
- 'audioCodec':{
- 'd' : "vorbis",
- 'selectVal' : ['vorbis'],
- 'type' : "select",
- 'group' : "quality"
+ 'audioCodec': {
+ 'default' : "vorbis",
+ 'selectVal' : [ 'vorbis' ],
+ 'type' : "select",
+ 'group' : "quality"
},
'width': {
- 'range' : {'min':0,'max':1080},
- 'step' : 4,
- 'type' : 'slider',
- 'group' : "quality"
+ 'range' : { 'min': 0, 'max': 1080 },
+ 'step' : 4,
+ 'type' : 'slider',
+ 'group' : "quality"
},
'height': {
- 'range' : {'min':0,'max':1080},
- 'step' : 4,
- 'type' : "slider",
- 'group' : "quality"
+ 'range' : { 'min': 0, 'max' : 1080 },
+ 'step' : 4,
+ 'type' : "slider",
+ 'group' : "quality"
},
- //advanced Video control configs:
- 'videoBitrate':{
- 'range' : {'min':1, 'max':16778},
- 'type' : "slider",
- 'group' : "advVideo",
+
+ // Advanced video control
+ 'videoBitrate': {
+ 'range' : { 'min' : 1, 'max' : 16778 },
+ 'type' : "slider",
+ 'group' : "advVideo",
} ,
- 'twopass':{
- 'type' : "boolean",
- 'group' : "advVideo"
+ 'twopass': {
+ 'type' : "boolean",
+ 'group' : "advVideo"
},
- 'framerate':{
- 'd' : '24',
- 'selectVal' : ['12', '16', {'24000:1001':'23.97'}, '24', '25', {'30000:1001':'29.97'}, '30'],
- 'type' : "select",
- 'group' : "advVideo"
+ 'framerate': {
+ 'default' : '24',
+ 'selectVal' : [ '12', '16', { '24000:1001' : '23.97' }, '24', '25',
+ { '30000:1001' : '29.97' }, '30' ],
+ 'type' : "select",
+ 'group' : "advVideo"
},
- 'aspect':{
- 'd' : '4:3',
- 'type' : "select",
- 'selectVal' : ['4:3', '16:9'],
- 'group' : "advVideo"
+ 'aspect': {
+ 'default' : '4:3',
+ 'type' : "select",
+ 'selectVal' : [ '4:3', '16:9' ],
+ 'group' : "advVideo"
},
- 'keyframeInterval':{
- 'd' : '64',
- 'range' : {'min':0,'max':65536},
+ 'keyframeInterval': {
+ 'default' : '64',
+ 'range' : { 'min': 0, 'max': 65536 },
'numberType': 'force keyframe every $1 frames',
- 'type' : 'int',
- 'group' : 'advVideo'
+ 'type' : 'int',
+ 'group' : 'advVideo'
},
- 'denoise':{
- 'type' : "boolean",
- 'group' : 'advVideo'
+ 'denoise': {
+ 'type' : "boolean",
+ 'group' : 'advVideo'
},
- 'novideo':{
- 'type' : "boolean",
- 'group' : 'advVideo'
+ 'novideo': {
+ 'type' : "boolean",
+ 'group' : 'advVideo'
},
- //advanced Audio control Config:
- 'audioBitrate':{
- 'range' : {'min':32,'max':500},
+ // Advanced audio control
+ 'audioBitrate': {
+ 'range' : { 'min': 32, 'max': 500 },
'numberType': '$1 kbs',
- 'type' : 'slider'
+ 'type' : 'slider'
},
- 'samplerate':{
- 'type' : 'select',
- 'selectVal' : [{'22050':'22 kHz'}, {'44100':'44 khz'}, {'48000':'48 khz'}],
- 'formatSelect' : function(val){
- return (Math.round(val/100)*10) + ' Hz';
+ 'samplerate': {
+ 'type' : 'select',
+ 'selectVal' : [ { '22050': '22 kHz' }, { '44100': '44 khz' }, { '48000': '48 khz' } ],
+ 'formatSelect' : function( val ) {
+ return ( Math.round( val / 100 ) * 10 ) + ' Hz';
}
},
- 'noaudio':{
- 'type' : 'boolean',
- 'group' : 'advAudio'
+ 'noaudio': {
+ 'type' : 'boolean',
+ 'group' : 'advAudio'
},
- //meta tags:
- 'title':{
- 'type' : 'string',
- 'group' : 'meta'
+ // Meta tags
+ 'title': {
+ 'type' : 'string',
+ 'group' : 'meta'
},
- 'artist':{
- 'type' : 'string',
- 'group' : 'meta'
+ 'artist': {
+ 'type' : 'string',
+ 'group' : 'meta'
},
- 'date':{
- 'group' : 'meta',
- 'type' : 'date'
+ 'date': {
+ 'group' : 'meta',
+ 'type' : 'date'
},
- 'location':{
- 'type' : 'string',
- 'group' : 'meta'
+ 'location': {
+ 'type' : 'string',
+ 'group' : 'meta'
},
- 'organization':{
- 'type' : 'string',
- 'group' : 'meta'
+ 'organization': {
+ 'type' : 'string',
+ 'group' : 'meta'
},
- 'copyright':{
- 'type' : 'string',
- 'group' : 'meta'
+ 'copyright': {
+ 'type' : 'string',
+ 'group' : 'meta'
},
- 'license':{
- 'type' : 'string',
+ 'license': {
+ 'type' : 'string',
},
- 'contact':{
- 'type' : 'string',
- 'group' : 'meta'
+ 'contact': {
+ 'type' : 'string',
+ 'group' : 'meta'
}
},
- init:function( iObj ){
- //setup a "supported" iObj:
- for(var i in iObj){
- if( typeof default_mvAdvFirefogg_config [i] != 'undefined' ){
- this[i] = iObj[i];
+
+ /**
+ * Initialise this object
+ */
+ init: function( options ) {
+ // Set up a supported object:
+ for ( var key in options ) {
+ if ( typeof default_mvAdvFirefogg_config[key] != 'undefined' ) {
+ this[key] = options[key];
}
}
- //inherit the base mvFirefogg class:
- var myFogg = new mvFirefogg( iObj );
- for(var i in myFogg){
- if( typeof this[i] != 'undefined'){
- this[ 'basefogg_' + i ] = myFogg[i];
- }else{
- this[ i ] = myFogg[i];
+ // Inherit the base mvFirefogg class:
+ var baseFirefogg = new mvFirefogg( options );
+ for ( var key in baseFirefogg ) {
+ if ( typeof this[key] != 'undefined' ) {
+ this[ 'basefogg_' + key ] = baseFirefogg[ key ];
+ } else {
+ this[ key ] = baseFirefogg[ key ];
}
}
},
- setupForm:function(){
- //call base firefogg form setup
- basefogg_setupForm();
-
- //gennerate the control html
- this.doControlHTML();
-
- //setup control bindings:
- this.doControlBindings();
+ setupForm: function() {
+ basefogg_setupForm();
+ this.createControls();
+ this.bindControls();
},
- doControlHTML: function(){
- js_log("adv doControlHTML");
+
+ createControls: function() {
+ js_log( "adv createControls" );
var _this = this;
- //load presets from cookie:
+ // Load presets from the cookie
this.loadEncSettings();
- //add base control buttons:
- this.basefogg_doControlHTML();
-
- //build the config group outpouts
- var gdout ='';
- $j.each(this.config_groups, function(inx, group_key){
- gdout+= '<div> '+
- '<h3><a href="#" class="gd_'+group_key+'" >' + gM('fogg-cg-'+group_key) + '</a></h3>'+
- '<div>';
- //output that group control options:
- gdout+='<table width="' + ($j(_this.selector).width()-60) + '" ><tr><td width="35%"></td><td width="65%"></td></tr>';
- //output the special prset output
- if(group_key=='preset'){
- gdout += _this.proccessPresetControl();
+ // Add the base control buttons
+ this.basefogg_createControls();
+
+ // Build the config group output
+ var gdout = '';
+ $j.each( this.config_groups, function( inx, group_key ) {
+ gdout += '<div> ' +
+ '<h3><a href="#" class="gd_' + group_key + '" >' +
+ gM( 'fogg-cg-' + group_key ) + '</a></h3>' +
+ '<div>';
+ // Output this group's control options:
+ gdout += '<table width="' + ( $j( _this.selector ).width() - 60 ) + '" >' +
+ '<tr><td width="35%"></td><td width="65%"></td></tr>';
+ // If this is the preset group, output the preset control
+ if ( group_key == 'preset' ) {
+ gdout += _this.getPresetControlHtml();
}
- for(var cK in _this.default_encoder_config){
- var cConf = _this.default_encoder_config[cK];
- if(cConf.group == group_key){
- gdout+= _this.proccessCkControlHTML( cK );
+ // Output the encoder config controls
+ for ( var configKey in _this.default_encoder_config ) {
+ var confEntry = _this.default_encoder_config[ configKey ];
+ if( confEntry.group == group_key ) {
+ gdout += _this.getConfigControlHtml( configKey );
}
}
- gdout+='</table>';
- gdout+= '</div>' +
- '</div>';
-
+ gdout += '</table></div></div>';
});
- //add the control container:
- if(!this.target_control_container){
+ // Add the control container
+ if( !this.target_control_container ) {
this.target_control_container = this.selector + ' .control_container';
- //set the target contorl container to height
- $j(this.selector).append( '<p><div class="control_container"></div>' );
+ $j( this.selector ).append( '<p><div class="control_container"></div>' );
}
- //hide the container and add the output
- $j(this.target_control_container).hide();
- $j(this.target_control_container).html( gdout );
-
+ // Hide the container and add the output
+ $j( this.target_control_container ).hide();
+ $j( this.target_control_container ).html( gdout );
},
- //custom advanced target rewrites:
- getTargetHtml:function(target){
- if( target=='target_btn_select_file' ||
- target=='target_btn_select_new_file'||
- target=='target_btn_save_local_file'){
- var icon = (target=='target_btn_save_local_file')?'ui-icon-video':'ui-icon-folder-open';
- return '<a class="ui-state-default ui-corner-all ui-icon_link '+
- target +'" href="#"><span class="ui-icon ' + icon + '"/>' +
- gM( 'fogg-' + target.substring(11) ) +
- '</a>';
- }else if( target=='target_btn_select_url'){
- //return the btnHtml:
- return $j.btnHtml( gM( 'fogg-' + target.substring(11) ), target, 'link');
-
- }else if( target=='target_use_latest_fox' ||
- target=='target_please_install' ||
- target == 'target_passthrough_mode'){
- return '<div style="margin-top:1em;padding: 0pt 0.7em;" class="ui-state-error ui-corner-all ' +
- target + '">' +
- '<p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-alert"/>'+
- gM( 'fogg-' + target.substring(7)) +'</p>'+
- '</div>';
- }else if( target == 'target_input_file_name'){
- return '<br><br><input style="" class="text ui-widget-content ui-corner-all ' + target + '" '+
- 'type="text" value="' + gM( 'fogg-' + target.substring(11)) + '" size="60" /> ';
- }else{
- js_log('call : basefogg_getTargetHtml');
- return this.basefogg_getTargetHtml(target);
+
+ // Custom advanced target rewrites
+ getControlHtml: function( target ) {
+ switch ( target ) {
+ case 'target_btn_select_file':
+ case 'target_btn_select_new_file':
+ case 'target_btn_save_local_file':
+ var icon;
+ if ( target == 'target_btn_save_local_file' ) {
+ icon = 'ui-icon-video'
+ } else {
+ icon = 'ui-icon-folder-open';
+ }
+ var linkText = gM( target.replace( /^target_btn_/, 'fogg-' ) );
+ return '<a class="ui-state-default ui-corner-all ui-icon_link ' +
+ target + '" href="#"><span class="ui-icon ' + icon + '"/>' +
+ linkText +
+ '</a>';
+ case 'target_btn_select_url':
+ return $j.btnHtml( gM( 'fogg-select_url' ), target, 'link' );
+ case 'target_use_latest_firefox':
+ case 'target_please_install':
+ case 'target_passthrough_mode':
+ var text = gM( target.replace( '/^target_', 'fogg-' ) );
+ return
+ '<div ' +
+ 'style="margin-top:1em;padding: 0pt 0.7em;" ' +
+ 'class="ui-state-error ui-corner-all ' +
+ target + '">' +
+ '<p>' +
+ '<span style="float: left; margin-right: 0.3em;" ' +
+ 'class="ui-icon ui-icon-alert"/>' +
+ text +
+ '</p>' +
+ '</div>';
+ case 'target_input_file_name':
+ var text = gM( 'fogg-input_file_name' );
+ return '<br><br><input style="" ' +
+ 'class="text ui-widget-content ui-corner-all ' + target + '" ' +
+ 'type="text" value="' + text + '" size="60" /> ';
+ default:
+ js_log( 'call : basefogg_getTargetHtml' );
+ return this.basefogg_getTargetHtml( target );
}
},
- proccessPresetControl:function(){
- var out='';
+
+ getPresetControlHtml: function() {
+ var out = '';
var _this = this;
- js_log('proccessPresetControl::');
- if(typeof this.local_settings.pSet!= 'undefined' ){
- out+= '<select class="_preset_select">';
- $j.each(this.local_settings.pSet, function(pKey, pSet){
- var pDesc = (pSet.descKey) ? gM(pSet.descKey) : pSet.desc;
- var sel = (_this.local_settings.d == pKey)?' selected':'';
- out+='<option value="'+pKey+'" '+sel+'>'+ pDesc+'</option>';
+ js_log( 'getPresetControlHtml::' );
+ if ( typeof this.local_settings.presets != 'undefined' ) {
+ out += '<select class="_preset_select">';
+ $j.each( this.local_settings.presets, function( presetKey, preset ) {
+ var presetDesc = preset.descKey ? gM( preset.descKey ) : preset.desc;
+ var sel = ( _this.local_settings['default'] == presetKey ) ? ' selected' : '';
+ out += '<option value="' + presetKey + '" ' + sel + '>' + presetDesc + '</option>';
});
- out+='</select>';
- }
+ out += '</select>';
+ }
return out;
},
- proccessCkControlHTML:function( cK ){
- var cConf = this.default_encoder_config[cK];
- var out ='';
- out+='<tr><td valign="top">'+
- '<label for="_' + cK + '">' +
- gM( 'fogg-' + cK + '-title') + ':' +
- '<span title="' + gM('fogg-help-sticky') + '" class="help_'+ cK + ' ui-icon ui-icon-info" style="float:left"></span>'+
- '</label></td><td valign="top">';
- //if we don't value for this:
- var dv = ( this.default_encoder_config[cK].d ) ? this.default_encoder_config[cK].d : '';
- //switch on the config type
- switch( cConf.type ){
+
+ getConfigControlHtml : function( configKey ) {
+ var configEntry = this.default_encoder_config[configKey];
+ var out = '';
+ out += '<tr><td valign="top">' +
+ '<label for="_' + configKey + '">' +
+ gM( 'fogg-' + configKey + '-title' ) + ':' +
+ '<span title="' + gM( 'fogg-help-sticky' ) + '" ' +
+ 'class="help_' + configKey + ' ui-icon ui-icon-info" style="float:left">' +
+ '</span>' +
+ '</label></td><td valign="top">';
+ // Get the default value (or an empty string if there is no default)
+
+ var defaultValue = this.default_encoder_config[configKey]['default'];
+ if ( !defaultValue ) {
+ defaultValue = '';
+ }
+ var type = configEntry.type; // shortcut
+
+ // Switch on the config type
+ switch( type ) {
case 'string':
case 'date':
case 'int':
case 'float':
- var size = ( cConf.type =='string' ||cConf.type == 'date' )?'14':'4';
- out+= '<input size="' + size + '" type="text" class="_' + cK + ' text ui-widget-content ui-corner-all" value="' + dv + '" >' ;
- break;
+ var size = ( type == 'string' || type == 'date' ) ? '14' : '4';
+ out += '<input ' +
+ 'size="' + size + '" ' +
+ 'type="text" ' +
+ 'class="_' + configKey + ' text ui-widget-content ui-corner-all" ' +
+ 'value="' + defaultValue + '" >';
+ break;
case 'boolean':
- var checked_attr = (dv===true)?' checked="true"':'';
- out+='<input type="checkbox" class="_'+cK+ ' ui-widget-content ui-corner-all" ' + checked_attr + '>';
- break;
+ var checked_attr = ( defaultValue === true ) ? ' checked="true"' : '';
+ out += '<input ' +
+ 'type="checkbox" ' +
+ 'class="_' + configKey + ' ui-widget-content ui-corner-all" ' +
+ checked_attr + '>';
+ break;
case 'slider':
- var strMax = this.default_encoder_config[ cK ].range.max + '';
- maxdigits = strMax.length +1;
- out+= '<input type="text" maxlength="'+maxdigits+'" size="' +maxdigits + '" '+
- 'class="_'+cK+ ' text ui-widget-content ui-corner-all" style="display:inline;border:0; color:#f6931f; font-weight:bold;" ' +
- 'value="' + dv + '" >' +
- '<div class="slider_' + cK + '"></div>';
- break;
+ var strMax = this.default_encoder_config[ configKey ].range.max + '';
+ maxDigits = strMax.length + 1;
+ out += '<input ' +
+ 'type="text" ' +
+ 'maxlength="' + maxDigits + '" ' +
+ 'size="' + maxDigits + '" ' +
+ 'class="_' + configKey + ' text ui-widget-content ui-corner-all" ' +
+ 'style="display:inline;border:0; color:#f6931f; font-weight:bold;" ' +
+ 'value="' + defaultValue + '" >' +
+ '<div class="slider_' + configKey + '"></div>';
+ break;
case 'select':
- out+= '<select class="_' + cK + '">'+
+ out += '<select class="_' + configKey + '">' +
'<option value=""> </option>';
- for(var i in cConf.selectVal){
- var val = cConf.selectVal[i];
- if(typeof val == 'string'){
- var sel = ( cConf.selectVal[i] == val)?' selected':'';
- out+= '<option value="'+val+'"'+sel+'>'+val+'</option>';
- }else if(typeof val == 'object'){
- for(var key in val){
+ for ( var i in configEntry.selectVal ) {
+ var val = configEntry.selectVal[i];
+ if ( typeof val == 'string' ) {
+ var sel = ( configEntry.selectVal[i] == val ) ? ' selected' : '';
+ out += '<option value="' + val + '"'+sel+'>' + val + '</option>';
+ } else if ( typeof val == 'object' ) {
+ for ( var key in val ) {
hr_val = val[key];
}
- var sel = ( cConf.selectVal[i] == key )?' selected':'';
+ var sel = ( configEntry.selectVal[i] == key ) ? ' selected' : '';
- out+= '<option value="'+key+'"'+sel+'>'+hr_val+'</option>';
+ out += '<option value="' + key + '"' + sel + '>' + hr_val + '</option>';
}
}
- out+='</select>';
- break;
+ out += '</select>';
+ break;
}
- //output the help row:
- out+='<div class="helpRow_' + cK + '">'+
- '<span class="helpClose_' + cK + ' ui-icon ui-icon-circle-close" '+
- 'title="Close Help"'+
- 'style="float:left"/>'+
- gM('fogg-'+ cK + '-help') +
- '</div>';
- out+='</td></tr><tr><td colspan="2" height="10"></td></tr>';
+ // output the help row:
+ out += '<div class="helpRow_' + configKey + '">' +
+ '<span class="helpClose_' + configKey + ' ui-icon ui-icon-circle-close" ' +
+ 'title="Close Help"' +
+ 'style="float:left"/>' +
+ gM( 'fogg-'+ configKey + '-help' ) +
+ '</div>';
+ out += '</td></tr><tr><td colspan="2" height="10"></td></tr>';
return out;
},
- selectByUrl:function(){
- var urlValue = prompt("Please enter the source media url you would like to transcode from.","http://");
- if( urlValue ){
- //update the mode:
- this.sourceMode = 'url';
- this.sourceUrl = urlValue;
- this.selectFoggActions();
- this.autoEncoderSettings();
- //update the input target
- $j(this.target_input_file_name).unbind().val( urlValue ).removeAttr('readonly');
+
+ /**
+ * Show a dialog box asking the user to select a source URL.
+ * FIXME: half-written, doesn't work at all.
+ */
+ selectSourceUrl: function() {
+ // FIXME: i18n
+ var url = prompt( "Please enter the source media url you would like " +
+ "to transcode from.", "http://" );
+ if ( !url ) {
+ return;
}
+
+ // update the mode:
+ this.sourceMode = 'url';
+ this.sourceUrl = url;
+ this.clearSourceInfoCache();
+ this.updateSourceFileUI();
+ // update the input target
+ $j( this.target_input_file_name )
+ .unbind()
+ .val( url )
+ .removeAttr( 'readonly' );
},
- doControlBindings:function(){
+
+ bindControls: function() {
var _this = this;
- _this.basefogg_doControlBindings();
- //show the select by url if present:
- /*$j( this.target_btn_select_url ).unbind(
- ).attr('disabled', false
- ).css({'display':'inline'}
- ).click(function(){
- _this.selectByUrl();
- });
+ _this.basefogg_bindControls();
+
+ // Show the select by URL if present
+ /*$j( this.target_btn_select_url ).unbind()
+ .attr( 'disabled', false )
+ .css( { 'display': 'inline' } )
+ .click( function() {
+ _this.selectSourceUrl();
+ });
*/
-
- //hide the base advanced controls untill a file is selected:
- $j(this.target_control_container).hide();
+ // Hide the base advanced controls until a file is selected:
+ $j( this.target_control_container ).hide();
var helpState = {};
- //do some display tweeks:
- js_log('tw:' + $j(this.selector).width() +
- 'ssf:' + $j(this.target_btn_select_new_file).width() +
- 'sf:' + $j(this.target_btn_save_local_file).width() );
+ // Do some display tweaks
+ js_log( 'tw:' + $j( this.selector ).width() +
+ ' ssf:' + $j( this.target_btn_select_new_file ).width() +
+ ' sf:' + $j( this.target_btn_save_local_file ).width() );
- //set width to 250
- $j(this.target_input_file_name).width( 250 );
+ // Set width to 250
+ $j( this.target_input_file_name ).width( 250 );
- //special preset action:
- $j(this.selector + ' ._preset_select').change(function(){
- _this.updatePresetSelection( $j(this).val() );
+ // Special preset action
+ $j( this.selector + ' ._preset_select' ).change( function() {
+ _this.updatePresetSelection( $j( this ).val() );
});
- //bind control actions
- for(var cK in this.default_encoder_config){
- var cConf = this.default_encoder_config[cK];
-
- //initial state is hidden:
- $j( this.selector + ' .helpRow_' + cK).hide();
- $j(this.selector + ' .help_' + cK).click(function(){
- //get the ckId (assume its the last class)
- var cK = _this.getClassId(this, 'help_');
-
- if(helpState[cK]){
- $j(_this.selector + ' .helpRow_' + cK).hide('slow');
- helpState[cK] = false;
- }else{
- $j(_this.selector + ' .helpRow_' + cK).show('slow');
- helpState[cK] = true;
- }
- return false;
- }).hover(
- function(){
- //get the ckId (assume its the last class)
- var cK = _this.getClassId(this, 'help_');
- $j( _this.selector + ' .helpRow_' + cK).show('slow');
- },function(){
- var cK = _this.getClassId(this, 'help_');
- if(!helpState[cK])
- $j( _this.selector + ' .helpRow_' + cK).hide('slow')
- }
- );
- $j( _this.selector + ' .helpClose_' + cK).click(function(){
- js_log("close help: " +cK);
- //get the ckId (assume its the last class)
- var cK = _this.getClassId(this, 'helpClose_');
- $j(_this.selector + ' .helpRow_' + cK).hide('slow');
- helpState[cK] = false;
- return false;
- }).css('cursor', 'pointer');
-
- //setup bindings for change values: (validate input)
-
- switch( cConf.type ){
+ // Bind control actions
+ for ( var configKey in this.default_encoder_config ) {
+ var confEntry = this.default_encoder_config[configKey];
+
+ // Initial state is hidden
+ $j( this.selector + ' .helpRow_' + configKey ).hide();
+
+ $j( this.selector + ' .help_' + configKey )
+ .click(
+ function() {
+ // Get the config key (assume it's the last class)
+ var configKey = _this.getClassId( this, 'help_' );
+
+ if ( helpState[configKey] ) {
+ $j( _this.selector + ' .helpRow_' + configKey ).hide( 'slow' );
+ helpState[configKey] = false;
+ } else {
+ $j( _this.selector + ' .helpRow_' + configKey ).show( 'slow' );
+ helpState[configKey] = true;
+ }
+ return false;
+ }
+ )
+ .hover(
+ function() {
+ // get the config key (assume it's the last class)
+ var configKey = _this.getClassId( this, 'help_' );
+ $j( _this.selector + ' .helpRow_' + configKey ).show( 'slow' );
+ },
+ function() {
+ var configKey = _this.getClassId( this, 'help_' );
+ if( !helpState[configKey] )
+ $j( _this.selector + ' .helpRow_' + configKey ).hide( 'slow' )
+ }
+ );
+
+ $j( this.selector + ' .helpClose_' + configKey )
+ .click(
+ function() {
+ js_log( "close help: " + configKey );
+ // get the config key (assume it's the last class)
+ var configKey = _this.getClassId( this, 'helpClose_' );
+ $j( _this.selector + ' .helpRow_' + configKey ).hide( 'slow' );
+ helpState[configKey] = false;
+ return false;
+ }
+ )
+ .css( 'cursor', 'pointer' );
+
+ // Set up bindings for the change events (validate input)
+
+ switch ( confEntry.type ) {
case 'boolean':
- $j(_this.selector + ' ._'+cK).click(function(){
- _this.updateLocalValue( _this.getClassId(this), $j(this).is(":checked") );
- _this.updatePresetSelection('custom');
- })
- break;
+ $j( this.selector + ' ._' + configKey)
+ .click( function() {
+ _this.updateLocalValue( _this.getClassId( this ),
+ $j( this ).is( ":checked" ) );
+ _this.updatePresetSelection( 'custom' );
+ });
+ break;
case 'select':
case 'string':
case 'int':
case 'float':
//@@check if we have a validate function on the string
- $j(_this.selector + ' ._'+cK).change(function(){
- $j(this).val( _this.updateLocalValue(
- _this.getClassId(this),
- $j(this).val() ));
- _this.updatePresetSelection('custom');
+ $j( this.selector + ' ._' + configKey ).change( function() {
+ $j( this ).val( _this.updateLocalValue(
+ _this.getClassId( this ),
+ $j( this ).val() ) );
+ _this.updatePresetSelection( 'custom' );
})
- break;
+ break;
case 'date':
- $j(_this.selector + ' ._'+cK).datepicker({
+ $j( this.selector + ' ._' + configKey ).datepicker({
changeMonth: true,
changeYear: true,
dateFormat: 'd MM, yy',
- onSelect: function(dateText) {
- _this.updateInterfaceValue(_this.getClassId(this), dateText);
+ onSelect: function( dateText ) {
+ _this.updateInterfaceValue( _this.getClassId( this ), dateText );
}
});
- break;
+ break;
case 'slider':
- $j(this.selector + ' .slider_' + cK ).slider({
+ var sliderId = _this.getClassId( this, 'slider_' );
+ $j( this.selector + ' .slider_' + configKey ).slider({
range: "min",
animate: true,
- step: (cConf.step)?cConf.step:1,
- value: $j( this.selector +' ._' + cK ).val(),
- min: this.default_encoder_config[ cK ].range.min,
- max: this.default_encoder_config[ cK ].range.max,
- slide: function(event, ui) {
- $j( _this.selector + ' ._' + _this.getClassId(this, 'slider_') ).val( ui.value );
-
- //maintain source video aspect ratio:
- if(_this.getClassId(this, 'slider_') == 'width'){
- var hv = parseInt((_this.sourceFileInfo.video[0]['height']/_this.sourceFileInfo.video[0]['width'])* ui.value );
- //update the height value: the new height value is > that original the slider:
- if(hv > _this.updateInterfaceValue('height', hv))
+ step: confEntry.step ? confEntry.step : 1,
+ value: $j( this.selector + ' ._' + configKey ).val(),
+ min: this.default_encoder_config[ configKey ].range.min,
+ max: this.default_encoder_config[ configKey ].range.max,
+ slide: function( event, ui ) {
+ $j( _this.selector + ' ._' + sliderId ).val( ui.value );
+
+ // Maintain source video aspect ratio
+ if ( sliderId == 'width' ) {
+ var sourceHeight = _this.sourceFileInfo.video[0]['height'];
+ var sourceWidth = _this.sourceFileInfo.video[0]['width'];
+ var newHeight = parseInt( sourceHeight / sourceWidth * ui.value );
+ // Reject the update if the new height is above the maximum
+ if ( newHeight > _this.updateInterfaceValue( 'height', newHeight ) )
return false;
}
- if(_this.getClassId(this, 'slider_') == 'height'){
- var wv = parseInt((_this.sourceFileInfo.video[0]['width']/_this.sourceFileInfo.video[0]['height'])* ui.value );
- //update the height value: the new height value is > that original the slider:
- if(wv > _this.updateInterfaceValue('width', wv))
+ if ( sliderId == 'height' ) {
+ var sourceHeight = _this.sourceFileInfo.video[0]['height'];
+ var sourceWidth = _this.sourceFileInfo.video[0]['width'];
+ var newWidth = parseInt( sourceWidth / sourceHeight * ui.value );
+ // Reject the update if the new width is above the maximum
+ if ( newWidth > _this.updateInterfaceValue( 'width', wv ) )
return false;
}
},
- change: function(event, ui){
- //update the local settings
- _this.updateLocalValue( _this.getClassId(this, 'slider_'), ui.value);
- _this.updatePresetSelection('custom');
+ change: function( event, ui ) {
+ _this.updateLocalValue( sliderId, ui.value );
+ _this.updatePresetSelection( 'custom' );
}
- })
- $j( this.selector +' ._' + cK).change(function(){
- var scid = _this.getClassId(this);
- var valdVal = _this.updateLocalValue(scid.substr(1),$j(this).val() );
- _this.updatePresetSelection('custom');
- //(validate user form input)
- $j(this).val(valdVal);
- //update the slider
- js_log("update: " + _this.selector + ' .slider' + scid);
- $j(_this.selector + ' .slider'+ scid).slider('option', 'value', valdVal );
});
- break
+
+ $j( this.selector + ' ._' + configKey ).change( function() {
+ var classId = _this.getClassId( this );
+ var validValue = _this.updateLocalValue( classId.substr( 1 ),
+ $j( this ).val() );
+ _this.updatePresetSelection( 'custom' );
+ // Change it to the validated value
+ $j( this ).val( validValue );
+ // update the slider
+ js_log( "update: " + _this.selector + ' .slider' + classId );
+ $j( _this.selector + ' .slider' + classId )
+ .slider( 'option', 'value', validValue );
+ });
+ break;
}
}
-
- $j(this.target_control_container).accordion({
+
+ $j( this.target_control_container ).accordion({
header: "h3",
collapsible: true,
active: false,
fillSpace: true
});
- //do config value updates if any
+ // Do the config value updates if there are any
this.updateValuesInHtml();
},
- updatePresetSelection:function( pKey ){
- //update the local key:
- this.local_settings.d = pKey;
- //js_log('update preset desc: '+ pKey);
- var pset_desc = '';
- if(this.local_settings.pSet[ pKey ].desc){
- pset_desc = this.local_settings.pSet[ pKey ].desc;
- }else{
- pset_desc = gM('fogg-preset-'+ pKey);
+
+ /**
+ * Update the UI due to a change in preset
+ */
+ updatePresetSelection: function( presetKey ) {
+ // Update the local configuration
+ this.local_settings['default'] = presetKey;
+ // js_log( 'update preset desc: ' + presetKey );
+ var presetDesc = '';
+ if ( this.local_settings.presets[presetKey].desc ) {
+ presetDesc = this.local_settings.presets[presetKey].desc;
+ } else {
+ presetDesc = gM( 'fogg-preset-' + presetKey );
}
- //update the preset title:
- $j( this.selector + ' .gd_preset' ).html(
- gM('fogg-cg-preset', pset_desc)
- );
- //update the selector
- $j(this.selector + ' ._preset_select').val(pKey);
+ // Update the preset title
+ $j( this.selector + ' .gd_preset' )
+ .html( gM( 'fogg-cg-preset', presetDesc ) );
+ // update the selector
+ $j( this.selector + ' ._preset_select' ).val( presetKey );
},
+
/*
- * updates the interface
+ * Update the interface due to a change in a particular config key
*/
- updateInterfaceValue:function(confKey, val){
+ updateInterfaceValue: function( confKey, val ) {
var _this = this;
- if(!val){
- return ;
+ if ( !val ) {
+ return;
}
- //js_log('updateInterfaceValue:: ' + confKey + ' v:' + val + ' cv:'+ _this.selector + '._'+ confKey+' len:' + $j(_this.selector + ' ._'+confKey).length );
- //lookup the type
- if(typeof this.default_encoder_config[confKey] == 'undefined'){
- js_error('error: missing default key: '+ confKey);
+ // Look up the type
+ if ( typeof this.default_encoder_config[confKey] == 'undefined' ) {
+ js_error( 'error: missing default key: ' + confKey );
return false;
}
- //update the local value (if not already up-to-date
- if( this.local_settings.pSet['custom']['conf'][confKey] != val ){
- val = this.updateLocalValue(confKey, val);
+ // Update the local value (if it's not already up-to-date)
+ if ( this.local_settings.presets['custom']['conf'][confKey] != val ) {
+ val = this.updateLocalValue( confKey, val );
}
- //update the text filed:
- $j(_this.selector + ' ._'+confKey).val( val );
- //update the interaface widget:
- switch(this.default_encoder_config[confKey].type){
+ // Update the text field
+ $j( _this.selector + ' ._' + confKey ).val( val );
+ // Update the interface widget
+ switch ( this.default_encoder_config[confKey].type ) {
case 'slider':
- $j(_this.selector + ' .slider_' + confKey).slider('option',
- 'value', $j(_this.selector + ' ._'+ confKey).val() );
- break;
+ $j( _this.selector + ' .slider_' + confKey )
+ .slider( 'option', 'value', $j( _this.selector + ' ._' + confKey ).val() );
+ break;
}
return val;
},
- updateLocalValue:function(confKey, value){
- //update the local value (return the value we acutally set)
- if(typeof this.default_encoder_config[confKey] == 'undefined'){
- js_log("Error:could not update conf key:" + confKey)
- return value;
+
+ /**
+ * Validate the new config setting, fixing its type and bounding it within a
+ * range if required. Update the configuration with the validated value and
+ * return it.
+ */
+ updateLocalValue: function( confKey, value ) {
+ if ( typeof this.default_encoder_config[confKey] == 'undefined' ) {
+ js_log( "Error: could not update conf key: " + confKey )
+ return value;
}
- dec = this.default_encoder_config[confKey];
- if(dec.range){
- value = parseInt(value);
- var min = ( dec.range.local_min) ? dec.range.local_min :dec.range.min;
- if(value < min)
+ var confEntry = this.default_encoder_config[confKey];
+ var range = confEntry.range;
+ if ( range ) {
+ value = parseInt( value );
+ var min = ( range.local_min ) ? range.local_min : range.min;
+ if ( value < min )
value = min;
- var max = ( dec.range.local_max) ? dec.range.local_max : dec.range.max
- if(value > max)
+ var max = ( range.local_max ) ? range.local_max : range.max;
+ if (value > max )
value = max;
}
- if(dec.type=='int')
- value = parseInt(value);
+ if ( confEntry.type == 'int' )
+ value = parseInt( value );
- //step value:
- /*if(dec.step){
- if((value % dec.step)!=0){
- value = value - (value % dec.step);
+ // step value:
+ /* if( confEntry.step ) {
+ if ( ( value % confEntry.step ) != 0 ) {
+ value = value - (value % confEntry.step);
}
}*/
- js_log('update:local_settings:custom:conf:'+ confKey + ' = ' + value);
- this.local_settings.pSet['custom']['conf'][confKey] = value;
+ js_log( 'update:local_settings:custom:conf:' + confKey + ' = ' + value );
+ this.local_settings.presets['custom']['conf'][confKey] = value;
return value;
},
- getLocalValue:function(confKey){
- return this.local_settings.pSet['custom']['conf'][confKey];
+
+ /**
+ * Get a local config value from the custom preset
+ */
+ getLocalValue: function( confKey ) {
+ return this.local_settings.presets['custom']['conf'][confKey];
},
- getClassId:function(elm, rmstr){
- var elmclass = $j(elm).attr("class").split(' ').slice(0,1).toString();
- if(rmstr){
- return elmclass.replace( rmstr, '' );
- }else{
- //strip leading underscore:
- return (elmclass[0]=='_')?elmclass.substr(1):elmclass;
+
+ /**
+ * Given an element or selector, get its primary class, and strip a given
+ * prefix from it.
+ *
+ * If no prefix is given, "_" is assumed.
+ */
+ getClassId: function( element, prefix ) {
+ var eltClass = $j( element ).attr( "class" ).split( ' ' ).slice( 0, 1 ).toString();
+
+ if ( !prefix ) {
+ prefix = '_';
+ }
+ if ( eltClass.substr( 0, prefix.length ) == prefix ) {
+ eltClass = eltClass.substr( prefix.length );
}
+ return eltClass;
},
- /*
- * sets up the autoEncoder settings
+
+ /**
+ * Get the appropriate encoder settings for the current Firefogg object,
+ * into which a video has already been selected. Overrides the base method.
*/
- autoEncoderSettings:function(){
- var _this = this;
- //do the base encoder settings setup:
- this.basefogg_autoEncoderSettings();
-
- //special case see if we already have ogg video in adv encoder expose encode settings anyway:
- if( _this.isOggFormat() ){
- _this.encoder_settings['passthrough'] = false;
+ getEncoderSettings: function() {
+ if ( this.current_encoder_settings != null ) {
+ return this.current_encoder_settings;
}
-
- //make sure we are "encoding" if not display not a video file eror:
- if( this.encoder_settings['passthrough'] ){
- js_log("in passthrough mode (hide control)");
- //hide all controls
- //display not encodable video
- $j(this.target_control_container).hide('slow');
- $j(this.target_passthrough_mode).show('slow');
- return ;
+
+ // Call the base function
+ // Note that settings will be a reference and can be modified
+ var settings = this.basefogg_getEncoderSettings();
+
+ // Allow re-encoding of files that are already ogg (unlike in the base class)
+ if ( this.isOggFormat() ) {
+ settings['passthrough'] = false;
}
- //restore display:
- $j(this.target_control_container).show('slow');
- $j(this.target_passthrough_mode).hide('slow');
-
- //do setup settings based on local_settings /default_encoder_config with sourceFileInfo
- //see: http://firefogg.org/dev/sourceInfo_example.html
- var setValues = function(k, val, maxVal) {
- if( k !== false){
- //update the value if unset:
- _this.updateLocalValue(k, val);
+ },
+
+ /**
+ * Do the necessary UI updates due to the source file changing.
+ * Overrides the parent method.
+ */
+ updateSourceFileUI: function() {
+ var _this = this;
+
+ // Call the parent
+ _this.basefogg_updateSourceFileUI();
+
+ var settings = this.getEncoderSettings();
+ var fileInfo = this.getSourceFileInfo();
+
+ // In passthrough mode, hide encoder controls
+ if ( settings['passthrough'] ) {
+ js_log( "in passthrough mode (hide control)" );
+ $j( this.target_control_container ).hide( 'slow' );
+ $j( this.target_passthrough_mode ).show( 'slow' );
+ return;
+ }
+
+ // Show encoder controls
+ $j( this.target_control_container ).show( 'slow' );
+ $j( this.target_passthrough_mode ).hide( 'slow' );
+
+ // do set up settings based on local_settings /default_encoder_config with sourceFileInfo
+ // see: http://firefogg.org/dev/sourceInfo_example.html
+ var setValues = function( k, val, maxVal ) {
+ if ( k !== false ) {
+ // update the value if unset:
+ _this.updateLocalValue( k, val );
}
- if( maxVal ){
- //update the local range:
- if(_this.default_encoder_config[k].range){
+ if ( maxVal ) {
+ // update the local range:
+ if ( _this.default_encoder_config[k].range ) {
_this.default_encoder_config[k].range.local_max = maxVal;
}
}
}
- //container level settings
- for(var i in this.sourceFileInfo){
- var val = this.sourceFileInfo[i];
+ // container level settings
+ for ( var i in fileInfo ) {
+ var val = fileInfo[i];
var k = false;
- var maxVal= false;
- switch(i){
- //do nothing with these:
+ var maxVal = false;
+ switch ( i ) {
+ // do nothing with these:
case 'bitrate':
k = 'videoBitrate';
- maxVal = (val*2 > this.default_encoder_config[k])?this.default_encoder_config[k]:val*2;
- break;
+ if ( val * 2 > this.default_encoder_config[k] ) {
+ maxVal = this.default_encoder_config[k];
+ } else {
+ maxVal = val * 2;
+ }
+ break;
}
- setValues(k, val, maxVal);
+ setValues( k, val, maxVal );
}
- //video stream settings
- for(var i in this.sourceFileInfo.video[0]){
- var val = this.sourceFileInfo.video[0][i];
+ // video stream settings
+ for ( var i in fileInfo.video[0] ) {
+ var val = fileInfo.video[0][i];
var k = false;
var maxVal= false;
- switch(i){
+ switch( i ) {
case 'width':
case 'height':
k = i;
maxVal = val;
- break;
+ break;
}
- setValues(k, val, maxVal);
+ setValues( k, val, maxVal );
}
- //audio stream settings, assumes for now there is only one stream
- for(var i in this.sourceFileInfo.audio[0]){
- var val = this.sourceFileInfo.audio[0][i];
+ // audio stream settings, assumes for now thare is only one stream
+ for ( var i in fileInfo.audio[0] ) {
+ var val = fileInfo.audio[0][i];
var k = false;
- var maxVal= false;
- switch(i){
+ var maxVal = false;
+ switch ( i ) {
case 'bitrate':
k = 'audioBitrate';
- maxVal = (val*2 > this.default_encoder_config[k])?this.default_encoder_config[k]:val*2;
- break;
+ if ( val * 2 > this.default_encoder_config[k] ) {
+ maxVal = this.default_encoder_config[k];
+ } else {
+ maxVal = val * 2;
+ }
+ break;
}
- setValues(k, val, maxVal);
+ setValues( k, val, maxVal );
}
- //set all values to new default ranges & update slider:
- $j.each(this.default_encoder_config, function(inx, val){
- if($j(_this.selector + ' ._'+inx).length!=0){
- if(typeof val.range != 'undefined'){
- //udate slider range
- var new_max = (val.range.local_max)?val.range.local_max: val.range.max
- $j( _this.selector + ' .slider_'+inx).slider('option', 'max', new_max);
-
- //update slider/input value:
- _this.updateInterfaceValue(inx, _this.local_settings.pSet['custom']['conf'][inx]);
+ // set all values to new default ranges & update slider:
+ $j.each( this.default_encoder_config, function( inx, val ) {
+ if ( $j( _this.selector + ' ._' + inx ).length != 0 ) {
+ if ( typeof val.range != 'undefined' ) {
+ // update slider range
+ var new_max = (val.range.local_max) ? val.range.local_max : val.range.max
+ $j( _this.selector + ' .slider_' + inx ).slider( 'option', 'max', new_max );
+
+ // update slider/input value:
+ _this.updateInterfaceValue( inx,
+ _this.local_settings.presets['custom']['conf'][inx] );
}
}
});
- //update values
+ // update values
this.updateValuesInHtml();
},
- doEncode:function(){
- //update the encoder settings (from local settings)
- pKey = this.local_settings.d;
- this.encoder_settings = this.local_settings.pSet[ pKey ].conf;
+
+ doEncode: function() {
+ // update the encoder settings (from local settings)
+ pKey = this.local_settings['default'];
+ this.encoder_settings = this.local_settings.presets[ pKey ].conf;
this.basefogg_doEncode();
},
- updateValuesInHtml:function(){
- js_log('updateValuesInHtml::');
+
+ /**
+ * Set the HTML control values to whatever is currently present in this.local_settings
+ */
+ updateValuesInHtml: function() {
+ js_log( 'updateValuesInHtml::' );
var _this = this;
- var pKey = this.local_settings.d;
+ var pKey = this.local_settings['default'];
this.updatePresetSelection( pKey );
- //set the actual HTML & widgets based on any local settings values:
- $j.each(_this.local_settings.pSet['custom']['conf'], function(inx, val){
- if($j(_this.selector + ' ._'+inx).length !=0){
- $j(_this.selector + ' ._'+inx).val( val );
+ // set the actual HTML & widgets based on any local settings values:
+ $j.each( _this.local_settings.presets['custom']['conf'], function( inx, val ) {
+ if ( $j( _this.selector + ' ._' + inx ).length != 0 ) {
+ $j( _this.selector + ' ._' + inx ).val( val );
}
});
},
- //restors settings from a cookie if you have them)
- loadEncSettings:function( force ){
- if($j.cookie('fogg_encoder_config')){
- js_log("load:fogg_encoder_config from cookie ");
- this.local_settings = JSON.parse( $j.cookie('fogg_settings') );
+
+ /**
+ * Restore settings from a cookie (if available)
+ */
+ loadEncSettings: function( force ) {
+ if ( $j.cookie( 'fogg_encoder_config' ) ) {
+ js_log( "load:fogg_encoder_config from cookie " );
+ this.local_settings = JSON.parse( $j.cookie( 'fogg_settings' ) );
}
- //set to default if not loaded yet:
- if( this.local_settings && this.local_settings.pSet && this.local_settings.pSet['custom']['conf']){
- js_log('local settings already populated');
- }else{
- this.local_settings = this.default_local_settings;
+ // set to default if not loaded yet:
+ if ( this.local_settings && this.local_settings.presets
+ && this.local_settings.presets['custom']['conf'] )
+ {
+ js_log( 'local settings already populated' );
+ } else {
+ this.local_settings = this.default_local_settings;
}
-
},
- //clear preset settings:
- clearSettings:function(force){
+ /**
+ * Clear preset settings
+ * FIXME: not called, does nothing
+ */
+ clearSettings: function( force ) {
},
- //save settings to the cookie
- saveEncSettings:function(){
- $j.cookie('fogg_settings', JSON.stringify( this.local_settings ) );
+
+ /**
+ * Save the current encoder settings to a cookie.
+ */
+ saveEncSettings: function() {
+ $j.cookie( 'fogg_settings', JSON.stringify( this.local_settings ) );
}
};
/**
- * The base Upload Interface for uploading.
+ * The base upload interface.
*
* This base upload class is optionally extended by Firefogg
*
"mwe-upload-in-progress" : "Upload in progress (do not close this window)",
"mwe-upload-transcoded-status" : "Transcoded",
"mwe-uploaded-status" : "Uploaded",
- "mwe-upload-stats-fileprogres" : "$1 of $2",
+ "mwe-upload-stats-fileprogress" : "$1 of $2",
"mwe-upload_completed" : "Your upload is complete",
"mwe-upload_done" : "<a href=\"$1\">Your upload <i>should be<\/i> accessible<\/a>.",
"mwe-upload-unknown-size" : "Unknown size",
});
var default_bui_options = {
- 'api_url':null,
- 'parent_uploader':null,
- 'edit_from':null,
+ 'api_url': null,
+ 'parent_uploader': null,
+ 'form': null,
'done_upload_cb': null,
- 'target_edit_from':null,
+ 'form_selector': null,
// Default upload mode is 'api'
'upload_mode': 'api'
}
-var mvBaseUploadInterface = function( iObj ){
- return this.init( iObj );
+var mvBaseUploadInterface = function( options ) {
+ return this.init( options );
}
+
mvBaseUploadInterface.prototype = {
- parent_uploader:false,
- formData:{}, // The form data to be submitted
- warnings_sessionkey:null,
- chunks_supported:true,
- form_post_override:false,
- http_copy_upload : false,
- action_done:false,
- // The edit token:
- etoken:false,
- init: function( iObj ){
- if(!iObj)
- iObj = {};
- // Inherit iObj properties:
- $j.extend( this, default_bui_options, iObj);
- js_log( "init mvBaseUploadInterface:: " + this.api_url);
+ parent_uploader: false,
+ formData: {}, // The form data to be submitted
+ warnings_sessionkey: null,
+ chunks_supported: true,
+ form_post_override: false,
+ http_copy_upload : null,
+ action_done: false,
+ editToken: false,
+
+ // The DOM node for the upload form
+ form: false,
+
+ /**
+ * Object initialisation
+ */
+ init: function( options ) {
+ if ( !options )
+ options = {};
+ $j.extend( this, default_bui_options, options );
+ js_log( "init mvBaseUploadInterface:: " + this.api_url );
},
- setupForm:function(){
- js_log("Base::setupForm::");
+
+ /**
+ * Set up the upload form, register onsubmit handler.
+ * May remap it to use the API field names.
+ */
+ setupForm: function() {
+ js_log( "Base::setupForm::" );
var _this = this;
// Set up the local pointer to the edit form:
- _this.editForm = _this.getEditForm();
- if( _this.editForm ){
-
- // If in api re-map the upload form to api: (we have to do this BEFORE the users selects a file)
- if( _this.upload_mode == 'api'){
- _this.doRemapFormToApi();
- }
-
- // Set up the org_onsubmit if not set:
- if( typeof( _this.org_onsubmit ) == 'undefined' && _this.editForm.onsubmit )
- _this.org_onsubmit = _this.editForm.onsubmit;
-
-
- // Set up the submit action:
- $j( _this.editForm ).submit( function(){
- js_log('setupForm.onSubmit:');
-
- // Set the upload mode:
- _this.setWgUploadSelect();
-
- // Run the original onsubmit (if not run yet set flag to avoid excessive chaining )
- if( typeof( _this.org_onsubmit ) == 'function' ){
- if( ! _this.org_onsubmit() ){
- //error in org submit return false;
- return false;
- }
- }
- // Check for post action override:
- if( _this.form_post_override ){
- js_log('form_post_override is true do form proccesing:');
- return true;
- }
- // Get the input form data in flat json:
- js_log('update formData::');
- var tmpAryData = $j( _this.editForm ).serializeArray();
- for(var i=0; i < tmpAryData.length; i++){
- if( tmpAryData[i]['name'] )
- _this.formData[ tmpAryData[i]['name'] ] = tmpAryData[i]['value'];
- }
- // Put into a try catch so we are sure to return false:
- try{
- debugger;
- // Get a clean loader:
- _this.dispProgressOverlay();
-
- // For some unknown reason we have to drop down the #p-search z-index:
- $j('#p-search').css('z-index', 1);
-
- // Select upload mode:
- _this.detectUploadMode();
- }catch(e){
- js_log('::error in dispProgressOverlay or detectUploadMode');
- }
-
- // Don't submit the form we will do the post in ajax
- return false;
- });
- }
- $j('#testcat').click(function(){
- $j( _this.editForm ).submit();
- });
+ this.form = this.getForm();
+ if ( !this.form ) {
+ js_log( "Upload form not found!" );
+ return;
+ }
+
+ // If we're in API mode, re-map the upload form to API.
+ if ( this.upload_mode == 'api' ) {
+ this.remapFormToApi();
+ }
+
+ // Set up the orig_onsubmit if not set:
+ if ( typeof( this.orig_onsubmit ) == 'undefined' && this.form.onsubmit ) {
+ this.orig_onsubmit = this.form.onsubmit;
+ }
+
+ // Set up the submit action:
+ $j( this.form ).submit( function() {
+ _this.onSubmit();
+ } );
},
- detectUploadMode:function( callback ){
+
+ /**
+ * onsubmit handler for the upload form
+ */
+ onSubmit: function() {
+ js_log( 'Base::onSubmit:' );
+
+ // Run the original onsubmit (if not run yet set flag to avoid excessive chaining)
+ if ( typeof( this.orig_onsubmit ) == 'function' ) {
+ if ( ! this.orig_onsubmit() ) {
+ //error in orig submit return false;
+ return false;
+ }
+ }
+ // Check for post action override
+ if ( this.form_post_override ) {
+ js_log( 'form_post_override is true, do ordinary form submit' );
+ return true;
+ }
+
+ // Get the input form data into an array
+ js_log( 'update formData::' );
+ var data = $j( this.form ).serializeArray();
+ this.formData = {};
+ for ( var i = 0; i < data.length; i++ ) {
+ if ( data[i]['name'] )
+ this.formData[ data[i]['name'] ] = data[i]['value'];
+ }
+ // Put into a try catch so we are sure to return false:
+ try {
+ // Get a clean loader:
+ // FIXME: this function does not exist in this class
+ this.displayProgressOverlay();
+
+ // For some unknown reason we have to drop down the #p-search z-index:
+ $j( '#p-search' ).css( 'z-index', 1 );
+
+ var _this = this;
+ this.detectUploadMode( function( mode ) {
+ _this.doUpload();
+ } );
+ } catch( e ) {
+ js_log( '::error in displayProgressOverlay or doUpload' );
+ }
+
+ // Don't submit the form we will do the post in ajax
+ return false;
+ }
+
+ /**
+ * Determine the correct upload mode.
+ *
+ * If this.upload_mode is autodetect, this runs an API call to find out if MW
+ * supports uploading. It then sets the upload mode when this call returns.
+ *
+ * When done detecting, or if detecting is unnecessary, it calls the callback
+ * with the upload mode as the first parameter.
+ */
+ detectUploadMode: function( callback ) {
var _this = this;
- js_log('detectUploadMode::' + _this.upload_mode);
- // Check the upload mode:
- if( _this.upload_mode == 'autodetect' ){
- js_log('detectUploadMode::' + _this.upload_mode + ' api:' + _this.api_url);
- if( ! _this.api_url )
- return js_error( 'Error: can\'t autodetect mode without api url' );
- do_api_req( {
- 'data': { 'action' : 'paraminfo', 'modules' : 'upload' },
- 'url' : _this.api_url
- }, function(data){
- if( typeof data.paraminfo == 'undefined' || typeof data.paraminfo.modules == 'undefined' )
- return js_error( 'Error: bad api results' );
- if( typeof data.paraminfo.modules[0].classname == 'undefined'){
- js_log( 'Autodetect Upload Mode: \'post\' ');
- _this.upload_mode = 'post';
- }else{
- js_log( 'Autodetect Upload Mode: api ' );
- _this.upload_mode = 'api';
- //check to see if chunks are supported:
- for( var i in data.paraminfo.modules[0].parameters ){
- var pname = data.paraminfo.modules[0].parameters[i].name;
- if( pname == 'enablechunks' ){
- js_log( 'this.chunks_supported = true' );
- _this.chunks_supported = true;
- break;
+ js_log( 'detectUploadMode::' + _this.upload_mode );
+ // Check the upload mode
+ if ( _this.upload_mode == 'detect_in_progress' ) {
+ // Don't send another request, wait for the pending one.
+ } else if ( !_this.isCopyUpload() ) {
+ callback( 'post' );
+ } else if ( _this.upload_mode == 'autodetect' ) {
+ js_log( 'detectUploadMode::' + _this.upload_mode + ' api:' + _this.api_url );
+ if( !_this.api_url ) {
+ js_error( 'Error: can\'t autodetect mode without api url' );
+ return;
+ }
+
+ // Don't send multiple requests
+ _this.upload_mode = 'detect_in_progress';
+
+ // FIXME: move this to configuration and avoid this API request
+ do_api_req(
+ {
+ 'data': { 'action' : 'paraminfo', 'modules' : 'upload' },
+ 'url' : _this.api_url
+ },
+ function( data ) {
+ if ( typeof data.paraminfo == 'undefined'
+ || typeof data.paraminfo.modules == 'undefined' )
+ {
+ return js_error( 'Error: bad api results' );
+ }
+ if ( typeof data.paraminfo.modules[0].classname == 'undefined' ) {
+ js_log( 'Autodetect Upload Mode: \'post\' ' );
+ _this.upload_mode = 'post';
+ callback( 'post' );
+ } else {
+ js_log( 'Autodetect Upload Mode: api ' );
+ _this.upload_mode = 'api';
+ // Check to see if chunks are supported
+ for ( var i in data.paraminfo.modules[0].parameters ) {
+ var pname = data.paraminfo.modules[0].parameters[i].name;
+ if( pname == 'enablechunks' ) {
+ js_log( 'this.chunks_supported = true' );
+ _this.chunks_supported = true;
+ break;
+ }
}
+ callback( 'api' );
}
}
- js_log("do call: doUploadSwitch");
- _this.doUploadSwitch();
- });
- }else{
- _this.doUploadSwitch();
+ );
+ } else if ( _this.upload_mode == 'api' ) {
+ callback( 'api' );
+ } else if ( _this.upload_mode == 'post' ) {
+ callback( 'post' );
+ } else {
+ js_error( 'Error: unrecongized upload mode: ' + _this.upload_mode );
}
},
- //@@NOTE this could probably be deprecated in favor of automated input
- doRemapFormToApi:function(){
- var _this = this;
- if( !_this.api_url )
+
+ /**
+ * Do an upload, with the mode given by this.upload_mode
+ */
+ doUpload: function() {
+ if ( this.upload_mode == 'api' ) {
+ _this.doApiCopyUpload();
+ } else if ( this.upload_mode == 'post' ) {
+ _this.doPostUpload();
+ } else {
+ js_error( 'Error: unrecongized upload mode: ' + this.upload_mode );
+ }
+ }
+
+ /**
+ * Change the upload form so that when submitted, it sends a request to
+ * the MW API.
+ *
+ * This is rather ugly, but solutions are constrained by the fact that
+ * file inputs can't be moved around or recreated after the user has
+ * selected a file in them, which they may well do before DOM ready.
+ */
+ remapFormToApi: function() {
+ if ( !this.api_url )
return false;
-
- //add the action api
- //$j(_this.editForm).attr('action', _this.api_url);
-
- //add api url
- //add api action:
- if( $j(_this.editForm).find("[name='action']").length == 0)
- $j(_this.editForm).append('<input type="hidden" name="action" value="upload">');
-
- //add json format
- if( $j(_this.editForm).find("[name='format']").length == 0)
- $j(_this.editForm).append('<input type="hidden" name="format" value="jsonfm">');
-
- //map a new hidden form
- $j(_this.editForm).find("[name='wpUploadFile']").attr('name', 'file');
- $j(_this.editForm).find("[name='wpDestFile']").attr('name', 'filename');
- $j(_this.editForm).find("[name='wpUploadDescription']").attr('name', 'comment');
- $j(_this.editForm).find("[name='wpEditToken']").attr('name', 'token');
- $j(_this.editForm).find("[name='wpIgnoreWarning']").attr('name', 'ignorewarnings');
- $j(_this.editForm).find("[name='wpWatchthis']").attr('name', 'watch');
-
+
+ var form = $j( this.form );
+
+ // Set the form action
+ form.attr('action', _this.api_url);
+
+ // Add API action
+ if ( form.find( "[name='action']" ).length == 0 )
+ form.append( '<input type="hidden" name="action" value="upload">' );
+
+ // Add JSON format
+ if ( form.find( "[name='format']" ).length == 0 )
+ form.append( '<input type="hidden" name="format" value="jsonfm">' );
+
+ // Map a new hidden form
+ form.find( "[name='wpUploadFile']" ).attr( 'name', 'file' );
+ form.find( "[name='wpDestFile']" ).attr( 'name', 'filename' );
+ form.find( "[name='wpUploadDescription']" ).attr( 'name', 'comment' );
+ form.find( "[name='wpEditToken']" ).attr( 'name', 'token' );
+ form.find( "[name='wpIgnoreWarning']" ).attr( 'name', 'ignorewarnings' );
+ form.find( "[name='wpWatchthis']" ).attr( 'name', 'watch' );
},
- setWgUploadSelect: function(){
- if( $j('#wpSourceTypeFile').length == 0 || $j('#wpSourceTypeFile').get(0).checked ){
- this.http_copy_upload = false;
- }else if( $j('#wpSourceTypeUrl').get(0).checked ){
- this.http_copy_upload = true;
+
+ /**
+ * Returns true if the current form has copy upload selected, false otherwise.
+ */
+ isCopyUpload: function() {
+ if ( this.http_copy_upload == null ) {
+ if ( $j( '#wpSourceTypeFile' ).length == 0
+ || $j( '#wpSourceTypeFile' ).get( 0 ).checked )
+ {
+ this.http_copy_upload = false;
+ } else if ( $j('#wpSourceTypeURL').get( 0 ).checked ) {
+ this.http_copy_upload = true;
+ }
}
+ return this.http_copy_upload;
},
- doUploadSwitch:function(){
+
+ /**
+ * Do an upload by submitting the form
+ */
+ doPostUpload: function() {
var _this = this;
- js_log('mvUPload:doUploadSwitch():' + _this.upload_mode);
- //issue a normal post request
- if( _this.upload_mode == 'api' && ! _this.http_copy_upload ){
- //get the token from the page:
- _this.etoken = $j("#wpEditToken").val();
-
- //@@TODO check for sendAsBinnary to support firefox/html5 progress on upload
-
- //set the form target to iframe target:
- _this.iframeId = 'f_' + ($j('iframe').length + 1);
-
- //add the iframe
- $j("body").append('<iframe src="javascript:false;" id="' + _this.iframeId + '" ' +
- 'name="' + _this.iframeId + '" style="display:none;" ></iframe>');
- $j(_this.editForm).attr('target', _this.iframeId);
-
- //set up the done binding
- $j('#' + _this.iframeId).load(function(){
- _this.proccessIframeResult( $j(this).get(0) );
- });
- //set the action to the api url:
- $j(_this.editForm).attr('action', _this.api_url );
-
- js_log('do iframe form submit to: ' + $j(_this.editForm).attr('target') );
- js_log(' destName:' + $j(_this.editForm).find("[name='filename']").val() );
-
-
- //do post override
- _this.form_post_override = true;
- //reset the done with action flag:
- _this.action_done = false;
-
- /*js_log('run editForm submit()');
- var tmpAryData = $j(_this.editForm).serializeArray();
- for(var i=0; i < tmpAryData.length; i++){
- if( tmpAryData[i]['name'] )
- js_log('name: ' + tmpAryData[i]['name'] + ' = ' + tmpAryData[i]['value']);
- }*/
- $j( _this.editForm ).submit();
+ var form = $j( _this.form );
+ js_log( 'mvBaseUploadInterface.doPostUpload' );
- return false;
- }else if( _this.upload_mode == 'api' ){
- js_log('doHttpUpload (no form submit) ');
- //if the api is supported.. && source type is http do upload with http status updates
- var httpUpConf ={
- 'url' : $j('#wpUploadFileURL').val(),
- 'filename' : $j('#wpDestFile').val(),
- 'comment' : $j('#wpUploadDescription').val(),
- 'watch' : ($j('#wpWatchthis').is(':checked'))?'true':'false',
- 'ignorewarnings': ($j('#wpIgnoreWarning').is(':checked'))?'true':'false'
- }
- //check for editToken
- _this.etoken = $j("#wpEditToken").val();
- _this.doHttpUpload( httpUpConf );
- }else{
- js_error( 'Error: unrecongized upload mode: ' + _this.upload_mode );
+ // Issue a normal post request
+ // Get the token from the page
+ _this.editToken = $j( "#wpEditToken" ).val();
+
+ //@@TODO check for sendAsBinary to support Firefox/HTML5 progress on upload
+
+
+ // Add the iframe
+ _this.iframeId = 'f_' + ( $j( 'iframe' ).length + 1 );
+ $j( "body" ).append( '<iframe src="javascript:false;" id="' + _this.iframeId + '" ' +
+ 'name="' + _this.iframeId + '" style="display:none;" ></iframe>' );
+
+ // Set the form target to the iframe
+ form.attr( 'target', _this.iframeId );
+
+ // Set up the completion callback
+ $j( '#' + _this.iframeId ).load( function() {
+ _this.processIframeResult( $j( this ).get( 0 ) );
+ });
+
+ // Set the action to the API URL:
+ form.attr( 'action', _this.api_url );
+
+ js_log( 'Do iframe form submit to: ' + form.attr( 'target' ) );
+ js_log( ' destName:' + form.find( "[name='filename']" ).val() );
+
+ // Do post override
+ _this.form_post_override = true;
+ // Reset the done with action flag
+ _this.action_done = false;
+
+ form.submit();
+ },
+
+ /**
+ * Do an upload by submitting an API request
+ */
+ doApiCopyUpload: function() {
+ js_log( 'mvBaseUploadInterface.doApiCopyUpload' );
+ js_log( 'doHttpUpload (no form submit) ' );
+ var httpUpConf = {
+ 'url' : $j( '#wpUploadFileURL' ).val(),
+ 'filename' : $j( '#wpDestFile' ).val(),
+ 'comment' : $j( '#wpUploadDescription' ).val(),
+ 'watch' : ( $j( '#wpWatchthis' ).is( ':checked' ) ) ? 'true' : 'false',
+ 'ignorewarnings': ($j('#wpIgnoreWarning' ).is( ':checked' ) ) ? 'true' : 'false'
}
- return false;
+ //check for editToken
+ this.editToken = $j( "#wpEditToken" ).val();
+ this.doHttpUpload( httpUpConf );
},
- proccessIframeResult:function(iframe){
+
+ /**
+ * Process the result of the form submission, returned to an iframe.
+ * This is the iframe's onload event.
+ */
+ processIframeResult: function( iframe ) {
var _this = this;
var doc = iframe.contentDocument ? iframe.contentDocument : frames[iframe.id].document;
- // fixing Opera 9.26
- if (doc.readyState && doc.readyState != 'complete'){
+ // Fix for Opera 9.26
+ if ( doc.readyState && doc.readyState != 'complete' ) {
return;
}
- // fixing Opera 9.64
- if (doc.body && doc.body.innerHTML == "false"){
+ // Fix for Opera 9.64
+ if ( doc.body && doc.body.innerHTML == "false" ) {
return;
}
var response;
- if (doc.XMLDocument){
- // response is a xml document IE property
+ if ( doc.XMLDocument ) {
+ // The response is a document property in IE
response = doc.XMLDocument;
- } else if (doc.body){
- // get the json str:
- json_str = $j(doc.body).find('pre').html();
- js_log('iframe:json::' + json_str + "\nbody:" + $j(doc.body).html() );
- //htmlentties
- if (json_str) {
- response = window["eval"]("(" +json_str + ")");
+ } else if ( doc.body ) {
+ // Get the json string
+ json = $j( doc.body ).find( 'pre' ).text();
+ js_log( 'iframe:json::' + json_str + "\nbody:" + $j( doc.body ).html() );
+ if ( json ) {
+ response = window["eval"]( "(" + json + ")" );
} else {
response = {};
}
} else {
// response is a xml document
- var response = doc;
+ response = doc;
}
- //do proccess the api result
- _this.processApiResult( response );
+ // Process the API result
+ _this.processApiResult( response );
},
- doHttpUpload:function( opt ){
+
+ /**
+ * Do a generic action=upload API request and monitor its progress
+ */
+ doHttpUpload: function( params ) {
var _this = this;
- //make sure to display the progress win:
- _this.dispProgressOverlay();
-
- //set the http box to loading (in case we don't get an update for some time)
- $j('#dlbox-centered').html( '<h5>' + _this.getProgressTitle() + '</h5>' +
- mv_get_loading_img( 'left:40%;top:20%')
- );
- //setup request:
- var req = {
- 'action' : 'upload',
- 'asyncdownload' : true //do async download
+ // Display the progress overlay (again)
+ _this.displayProgressOverlay();
+
+ // Set the HTTP box to "loading", in case we don't get an update for some time
+ $j( '#dlbox-centered' ).html( '<h5>' + _this.getProgressTitle() + '</h5>' +
+ mv_get_loading_img( 'left:40%;top:20%' )
+ );
+
+ // Set up the request
+ var request = {
+ 'action' : 'upload',
+ 'asyncdownload' : true // Do async download
};
- //set config from options:
- $j.extend(req, opt);
- //else try and get a token:
- if(!_this.etoken && _this.api_url){
- js_log('Error:doHttpUpload: missing token');
- }else{
- req['token'] =_this.etoken;
+ // Add any parameters specified by the caller
+ for ( key in params ) {
+ if ( !request[key] ) {
+ request[key] = params[key];
+ }
}
- //reset the done with action flag:
+
+ // Add the edit token (if available)
+ if( !_this.editToken && _this.api_url ) {
+ js_log( 'Error:doHttpUpload: missing token' );
+ } else {
+ request['token'] =_this.editToken;
+ }
+
+ // Reset the done with action flag
_this.action_done = false;
- //do the api req
+
+ //do the api request
do_api_req({
- 'data': req,
+ 'data': request,
'url' : _this.api_url
- }, function( data ){
+ }, function( data ) {
_this.processApiResult( data );
});
},
- doAjaxUploadStatus:function() {
- var _this = this;
-
+
+ /**
+ * Start periodic checks of the upload status using XHR
+ */
+ doAjaxUploadStatus: function() {
+ var _this = this;
+
//set up the progress display for status updates:
- _this.dispProgressOverlay();
- var req = {
- 'action' : 'upload',
+ this.displayProgressOverlay();
+ this.upload_status_request = {
+ 'action' : 'upload',
'httpstatus' : 'true',
'sessionkey' : _this.upload_session_key
};
- //add token if present:
- if(this.etoken)
- req['token'] = this.etoken;
-
- var uploadStatus = function(){
- //do the api request:
- do_api_req({
- 'data':req,
- 'url' : _this.api_url
- }, function( data ){
- //@@check if we are done
- if( data.upload['apiUploadResult'] ){
- //update status to 100%
- _this.updateProgress( 1 );
- //see if we need JSON
- mvJsLoader.doLoad( [
- 'JSON'
- ],function(){
- var apiResult = {};
- try{
- apiResult = JSON.parse ( data.upload['apiUploadResult'] ) ;
- }catch (e){
- //could not parse api result
- js_log('errro: could not parse apiUploadResult ')
- }
- _this.processApiResult( apiResult );
- });
- return ;
- }
+ // Add token if present
+ if ( this.editToken )
+ this.upload_status_request['token'] = this.editToken;
- //@@ else update status:
- if( data.upload['content_length'] && data.upload['loaded'] ){
- //we have content length we can show percentage done:
- var perc = data.upload['loaded'] / data.upload['content_length'];
- //update the status:
- _this.updateProgress( perc );
- //special case update the file progress where we have data size:
- $j('#up-status-container').html(
- gM('mwe-upload-stats-fileprogres', [
- $mw.lang.formatSize( data.upload['loaded'] ),
- $mw.lang.formatSize( data.upload['content_length'] )
- ]
- )
- );
- }else if( data.upload['loaded'] ){
- _this.updateProgress( 1 );
- js_log('just have loaded (no cotent length: ' + data.upload['loaded']);
- //for lack of content-length requests:
- $j('#up-status-container').html(
- gM('mwe-upload-stats-fileprogres', [
- $mw.lang.formatSize( data.upload['loaded'] ),
- gM('mwe-upload-unknown-size')
- ]
- )
- );
- }
- if( _this.api_url == 'proxy'){
- //do the updates a bit more sporadically every 4.2 seconds
- setTimeout(uploadStatus, 4200);
- }else{
- //(we got a result) set it to 100ms + your server update interval (in our case 2s)
- setTimeout(uploadStatus, 2100);
+ // Trigger an initial request (subsequent ones will be done by a timer)
+ this.onAjaxUploadStatusTimer();
+ }
+
+ /**
+ * This is called when the timer which separates XHR requests elapses.
+ * It starts a new request.
+ */
+ onAjaxUploadStatusTimer: function() {
+ var _this = this;
+ //do the api request:
+ do_api_req(
+ {
+ 'data': this.upload_status_request,
+ 'url' : this.api_url
+ },
+ function ( data ) {
+ _this.onAjaxUploadStatusResponse( data );
+ }
+ );
+ },
+
+ /**
+ * Called when a response to an upload status query is available.
+ * Starts the timer for the next upload status check.
+ */
+ onAjaxUploadStatusResponse: function( data ) {
+ var _this = this;
+ //@@check if we are done
+ if ( data.upload['apiUploadResult'] ) {
+ //update status to 100%
+ _this.updateProgress( 1 );
+ //see if we need JSON
+ mvJsLoader.doLoad( [
+ 'JSON'
+ ], function() {
+ var apiResult = {};
+ try {
+ apiResult = JSON.parse( data.upload['apiUploadResult'] ) ;
+ } catch ( e ) {
+ //could not parse api result
+ js_log( 'errro: could not parse apiUploadResult' )
}
+ _this.processApiResult( apiResult );
});
+ return ;
+ }
+
+ //@@ else update status:
+ if ( data.upload['content_length'] && data.upload['loaded'] ) {
+ //we have content length we can show percentage done:
+ var fraction = data.upload['loaded'] / data.upload['content_length'];
+ //update the status:
+ _this.updateProgress( fraction );
+ //special case update the file progress where we have data size:
+ $j( '#up-status-container' ).html(
+ gM( 'mwe-upload-stats-fileprogress',
+ [
+ $mw.lang.formatSize( data.upload['loaded'] ),
+ $mw.lang.formatSize( data.upload['content_length'] )
+ ]
+ )
+ );
+ } else if( data.upload['loaded'] ) {
+ _this.updateProgress( 1 );
+ js_log( 'just have loaded (no cotent length: ' + data.upload['loaded'] );
+ //for lack of content-length requests:
+ $j( '#up-status-container' ).html(
+ gM( 'mwe-upload-stats-fileprogress',
+ [
+ $mw.lang.formatSize( data.upload['loaded'] ),
+ gM( 'mwe-upload-unknown-size' )
+ ]
+ )
+ );
+ }
+ if ( _this.api_url == 'proxy' ) {
+ // Do the updates a bit less often: every 4.2 seconds
+ var timeout = 4200;
+ } else {
+ // We got a result: set timeout to 100ms + your server update
+ // interval (in our case 2s)
+ var timeout = 2100;
}
- uploadStatus();
+ setTimeout(
+ function() {
+ _this.onAjaxUploadStatusTimer();
+ },
+ timeout );
},
- apiUpdateErrorCheck:function( apiRes ){
+
+ /**
+ * Returns true if an action=upload API result was successful, false otherwise
+ */
+ isApiSuccess: function( apiRes ) {
+ if ( apiRes.error || ( apiRes.upload && apiRes.upload.result == "Failure" ) ) {
+ return false;
+ }
+ if ( apiRes.upload && apiRes.upload.error ) {
+ return false;
+ }
+ if ( apiRes.upload && apiRes.upload.warnings ) {
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * Given the result of an action=upload API request, display the error message
+ * to the user.
+ */
+ showApiError: function( apiRes ) {
var _this = this;
- if( apiRes.error || ( apiRes.upload && apiRes.upload.result == "Failure" ) ){
- //gennerate the error button:
- var bObj = {};
- bObj[ gM('mwe-return-to-form') ] = function(){
- _this.form_post_override = false;
- $j(this).dialog('close');
- };
+ if ( apiRes.error || ( apiRes.upload && apiRes.upload.result == "Failure" ) ) {
+ // Generate the error button
+ var buttons = {};
+ buttons[ gM( 'mwe-return-to-form' ) ] = function() {
+ _this.form_post_override = false;
+ $j( this ).dialog( 'close' );
+ };
//@@TODO should be refactored to more specialUpload page type error handling
- //check a few places for the error code:
- var error_code=0;
- var errorReplaceArg='';
- if( apiRes.error && apiRes.error.code ){
+ // Check a few places for the error code
+ var error_code = 0;
+ var errorReplaceArg = '';
+ if ( apiRes.error && apiRes.error.code ) {
error_code = apiRes.error.code;
- }else if( apiRes.upload.code ){
- if(typeof apiRes.upload.code == 'object'){
- if( apiRes.upload.code[0] ){
+ } else if ( apiRes.upload.code ) {
+ if ( typeof apiRes.upload.code == 'object' ) {
+ if ( apiRes.upload.code[0] ) {
error_code = apiRes.upload.code[0];
}
- if( apiRes.upload.code['status'] ){
+ if ( apiRes.upload.code['status'] ) {
error_code = apiRes.upload.code['status'];
- if(apiRes.upload.code['filtered'])
- errorReplaceArg =apiRes.upload.code['filtered'];
+ if ( apiRes.upload.code['filtered'] )
+ errorReplaceArg = apiRes.upload.code['filtered'];
}
- }else{
+ } else {
apiRes.upload.code;
}
}
var error_msg = '';
- if(typeof apiRes.error == 'string')
+ if ( typeof apiRes.error == 'string' )
error_msg = apiRes.error;
- //error space is too large so we don't front load it
- //this upload error space replicates code in: SpecialUpload.php::processUpload()
- //would be nice if we refactored that to the upload api.(problem is some need special actions)
+
+ // There are many possible error messages here, so we don't load all
+ // message text in advance, instead we use gMsgLoadRemote() for some.
+ //
+ // This code is similar to the error handling code formerly in
+ // SpecialUpload::processUpload()
var error_msg_key = {
'2' : 'largefileserver',
'3' : 'emptyfile',
'5' : 'illegalfilename'
};
- //@@todo: need to write conditionals that mirror SpecialUpload for handling these error types:
+ //@@todo: handle these error types
var error_onlykey = {
'1': 'BEFORE_PROCESSING',
'6': 'PROTECTED_PAGE',
'11': 'UPLOAD_VERIFICATION_ERROR',
'12': 'UPLOAD_WARNING',
'13': 'INTERNAL_ERROR',
- '14': 'MIN_LENGHT_PARTNAME'
+ '14': 'MIN_LENGTH_PARTNAME'
}
- //do a remote call to get the error msg:
- if(!error_code || error_code == 'unknown-error'){
- if(typeof JSON != 'undefined'){
- js_log('Error: apiRes: ' + JSON.stringify( apiRes) );
+ if ( !error_code || error_code == 'unknown-error' ) {
+ if ( typeof JSON != 'undefined' ) {
+ js_log( 'Error: apiRes: ' + JSON.stringify( apiRes ) );
}
- if( apiRes.upload.error == 'internal-error'){
+ if ( apiRes.upload.error == 'internal-error' ) {
+ // Do a remote message load
errorKey = apiRes.upload.details[0];
- gMsgLoadRemote(errorKey, function(){
- _this.updateProgressWin( gM( 'mwe-uploaderror' ), gM( errorKey ), bObj );
+ gMsgLoadRemote( errorKey, function() {
+ _this.updateProgressWin( gM( 'mwe-uploaderror' ), gM( errorKey ), buttons );
});
return false;
}
- _this.updateProgressWin( gM('mwe-uploaderror'), gM('mwe-unknown-error') + '<br>' + error_msg, bObj );
+ _this.updateProgressWin(
+ gM('mwe-uploaderror'),
+ gM('mwe-unknown-error') + '<br>' + error_msg,
+ buttons );
return false;
- }else{
- if(apiRes.error && apiRes.error.info ){
- _this.updateProgressWin( gM('mwe-uploaderror'), apiRes.error.info ,bObj);
- return false;
- }else{
- if(typeof error_code == 'number' && typeof error_msg_key[error_code] == 'undefined' ){
- if(apiRes.upload.code.finalExt){
- _this.updateProgressWin( gM('mwe-uploaderror'), gM('mwe-wgfogg_warning_bad_extension', apiRes.upload.code.finalExt) , bObj);
- }else{
- _this.updateProgressWin( gM('mwe-uploaderror'), gM('mwe-unknown-error') + ' : ' + error_code, bObj);
- }
- }else{
- js_log('get key: ' + error_msg_key[ error_code ])
- gMsgLoadRemote( error_msg_key[ error_code ], function(){
- _this.updateProgressWin( gM('mwe-uploaderror'), gM( error_msg_key[ error_code ], errorReplaceArg ), bObj);
- });
- js_log("api.error");
- }
- return false;
+ }
+
+ if ( apiRes.error && apiRes.error.info ) {
+ _this.updateProgressWin( gM( 'mwe-uploaderror' ), apiRes.error.info, buttons );
+ return false;
+ }
+
+ if ( typeof error_code == 'number'
+ && typeof error_msg_key[error_code] == 'undefined' )
+ {
+ if ( apiRes.upload.code.finalExt ) {
+ _this.updateProgressWin(
+ gM( 'mwe-uploaderror' ),
+ gM( 'mwe-wgfogg_warning_bad_extension', apiRes.upload.code.finalExt ),
+ buttons );
+ } else {
+ _this.updateProgressWin(
+ gM( 'mwe-uploaderror' ),
+ gM( 'mwe-unknown-error' ) + ' : ' + error_code,
+ buttons );
}
+ return false;
}
+
+ js_log( 'get key: ' + error_msg_key[ error_code ] )
+ gMsgLoadRemote( error_msg_key[ error_code ], function() {
+ _this.updateProgressWin(
+ gM( 'mwe-uploaderror' ),
+ gM( error_msg_key[ error_code ], errorReplaceArg ),
+ buttons );
+ });
+ js_log( "api.error" );
+ return false;
}
- //check for upload.error type erros.
- if( apiRes.upload && apiRes.upload.error){
- js_log(' apiRes.upload.error: ' + apiRes.upload.error );
- _this.updateProgressWin( gM('mwe-uploaderror'), gM('mwe-unknown-error') + '<br>', bObj);
+
+ // Check upload.error
+ if ( apiRes.upload && apiRes.upload.error ) {
+ js_log( ' apiRes.upload.error: ' + apiRes.upload.error );
+ _this.updateProgressWin(
+ gM( 'mwe-uploaderror' ),
+ gM( 'mwe-unknown-error' ) + '<br>',
+ buttons );
return false;
}
- //check for known warnings:
- if(apiRes.upload && apiRes.upload.warnings ){
- //debugger;
+
+ // Check for warnings:
+ if ( apiRes.upload && apiRes.upload.warnings ) {
var wmsg = '<ul>';
- for(var wtype in apiRes.upload.warnings){
+ for ( var wtype in apiRes.upload.warnings ) {
var winfo = apiRes.upload.warnings[wtype]
- wmsg+='<li>';
- switch(wtype){
+ wmsg += '<li>';
+ switch ( wtype ) {
case 'duplicate':
case 'exists':
- if(winfo[1] && winfo[1].title && winfo[1].title.mTextform){
- wmsg += gM('mwe-file-exists-duplicate') +' '+
- '<b>' + winfo[1].title.mTextform + '</b>';
- }else{
+ if ( winfo[1] && winfo[1].title && winfo[1].title.mTextform ) {
+ wmsg += gM( 'mwe-file-exists-duplicate' ) + ' ' +
+ '<b>' + winfo[1].title.mTextform + '</b>';
+ } else {
//misc error (weird that winfo[1] not present
- wmsg += gM('mwe-upload-misc-error') + ' ' + wtype;
+ wmsg += gM( 'mwe-upload-misc-error' ) + ' ' + wtype;
}
- break;
+ break;
case 'file-thumbnail-no':
- wmsg += gM('mwe-file-thumbnail-no', winfo);
- break;
+ wmsg += gM( 'mwe-file-thumbnail-no', winfo );
+ break;
default:
- wmsg += gM('mwe-upload-misc-error') + ' ' + wtype;
- break;
+ wmsg += gM( 'mwe-upload-misc-error' ) + ' ' + wtype;
+ break;
}
- wmsg+='</li>';
+ wmsg += '</li>';
}
- wmsg+='</ul>';
- if( apiRes.upload.sessionkey)
- _this.warnings_sessionkey = apiRes.upload.sessionkey;
+ wmsg += '</ul>';
+ if ( apiRes.upload.sessionkey )
+ _this.warnings_sessionkey = apiRes.upload.sessionkey;
- var bObj = {};
- bObj[ gM('mwe-ignorewarning') ] = function() {
- //check if we have a stashed key:
- if( _this.warnings_sessionkey ){
- //set to "loading"
+ // Create the "ignore warning" button
+ var buttons = {};
+ buttons[ gM( 'mwe-ignorewarning' ) ] = function() {
+ //check if we have a stashed key:
+ if ( _this.warnings_sessionkey ) {
+ //set to "loading"
$j( '#upProgressDialog' ).html( mv_get_loading_img() );
//setup loading:
var req = {
- 'action' : 'upload',
+ 'action': 'upload',
'sessionkey': _this.warnings_sessionkey,
- 'ignorewarnings':1,
- 'filename': $j('#wpDestFile').val(),
- 'token' : _this.etoken
- };
+ 'ignorewarnings': 1,
+ 'filename': $j( '#wpDestFile' ).val(),
+ 'token' : _this.editToken
+ };
//run the upload from stash request
- do_api_req({
- 'data': req,
- 'url' : _this.api_url
- }, function( data ){
- _this.processApiResult( data );
- });
- }else{
- js_log('No session key re-sending upload')
+ do_api_req(
+ {
+ 'data': req,
+ 'url' : _this.api_url
+ },
+ function( data ) {
+ _this.processApiResult( data );
+ }
+ );
+ } else {
+ js_log( 'No session key re-sending upload' )
//do a stashed upload
- $j('#wpIgnoreWarning').attr('checked', true);
+ $j( '#wpIgnoreWarning' ).attr( 'checked', true );
$j( _this.editForm ).submit();
}
};
- bObj[ gM('mwe-return-to-form') ] = function(){
- $j(this).dialog('close');
+ // Create the "return to form" button
+ bObj[ gM( 'mwe-return-to-form' ) ] = function() {
+ $j( this ).dialog( 'close' );
_this.form_post_override = false;
}
- _this.updateProgressWin( gM('mwe-uploadwarning'), '<h3>' + gM('mwe-uploadwarning') + '</h3>' +wmsg + '<p>',bObj);
+ // Show warning
+ _this.updateProgressWin(
+ gM( 'mwe-uploadwarning' ),
+ '<h3>' + gM( 'mwe-uploadwarning' ) + '</h3>' + wmsg + '<p>',
+ bObj );
return false;
}
- //should be "OK"
+ // No error!
return true;
},
- processApiResult: function( apiRes ){
+
+ /**
+ * Process the result of an action=upload API request. Display the result
+ * to the user.
+ */
+ processApiResult: function( apiRes ) {
var _this = this;
- js_log('processApiResult::');
- //check for upload api error:
- // {"upload":{"result":"Failure","error":"unknown-error","code":{"status":5,"filtered":"NGC2207%2BIC2163.jpg"}}}
- if( _this.apiUpdateErrorCheck(apiRes) === false){
- //error returned false (updated and
+ js_log( 'processApiResult::' );
+ if ( !_this.isApiSuccess( apiRes ) ) {
+ // Error detected, show it to the user
+ _this.showApiError( apiRes );
return false;
- }else{
- //check for upload_session key for async upload:
- if( apiRes.upload && apiRes.upload.upload_session_key ){
- //set the session key
- _this.upload_session_key = apiRes.upload.upload_session_key;
-
- //do ajax upload status:
- _this.doAjaxUploadStatus();
- js_log("set upload_session_key: " + _this.upload_session_key);
- return ;
+ }
+ if ( apiRes.upload && apiRes.upload.upload_session_key ) {
+ // Async upload, do AJAX status polling
+ _this.upload_session_key = apiRes.upload.upload_session_key;
+ _this.doAjaxUploadStatus();
+ js_log( "set upload_session_key: " + _this.upload_session_key );
+ return;
+ }
+
+ if ( apiRes.upload.imageinfo && apiRes.upload.imageinfo.descriptionurl ) {
+ var url = apiRes.upload.imageinfo.descriptionurl;
+
+ // Upload complete.
+ // Call the completion callback if available.
+ if ( _this.done_upload_cb && typeof _this.done_upload_cb == 'function' ) {
+ js_log( "call done_upload_cb" );
+ // This overrides our normal completion handling so we close the
+ // dialog immediately.
+ $j( '#upProgressDialog' ).dialog( 'close' );
+ _this.done_upload_cb( apiRes.upload );
+ return false;
}
- if( apiRes.upload.imageinfo && apiRes.upload.imageinfo.descriptionurl ){
- var url = apiRes.upload.imageinfo.descriptionurl;
- //check done action:
- if( _this.done_upload_cb && typeof _this.done_upload_cb == 'function'){
- js_log("call done_upload_cb");
- //close up shop:
- $j('#upProgressDialog').dialog('close');
- //call the callback:
- _this.done_upload_cb( apiRes.upload );
- return false;
- }else{
- var bObj = {};
- bObj[ gM('mwe-return-to-form')] = function(){
- $j(this).dialog('close');
- _this.form_post_override = false;
- }
- bObj[ gM('mwe-go-to-resource') ] = function(){
- window.location = url;
- };
- _this.action_done = true;
- _this.updateProgressWin( gM('mwe-successfulupload'), gM( 'mwe-upload_done', url), bObj);
- js_log('apiRes.upload.imageinfo::'+url);
- return true;
- }
+ var bObj = {};
+ // "Return" button
+ bObj[ gM( 'mwe-return-to-form' ) ] = function() {
+ $j( this ).dialog( 'close' );
+ _this.form_post_override = false;
}
+ // "Go to resource" button
+ bObj[ gM('mwe-go-to-resource') ] = function() {
+ window.location = url;
+ };
+ _this.action_done = true;
+ _this.updateProgressWin(
+ gM( 'mwe-successfulupload' ),
+ gM( 'mwe-upload_done', url),
+ bObj );
+ js_log( 'apiRes.upload.imageinfo::' + url );
+ return true;
}
},
- updateProgressWin:function(title_txt, msg, buttons){
+
+ /**
+ * Update the progress window to display a given message, with a given
+ * list of buttons below it.
+ * @param title_txt Plain text
+ * @param msg HTML
+ * @param buttons See http://docs.jquery.com/UI/Dialog#option-buttons
+ */
+ updateProgressWin: function( title_txt, msg, buttons ) {
var _this = this;
- if(!title_txt)
- title_txt = _this.getProgressTitle();
- if(!msg)
- msg = mv_get_loading_img( 'left:40%;top:40px;');
- $j( '#upProgressDialog' ).dialog('option', 'title', title_txt );
- $j( '#upProgressDialog' ).html( msg );
- if(buttons){
- $j('#upProgressDialog').dialog('option','buttons', buttons);
- }else{
- //@@todo should fix jquery ui to not use object keys as user msg's
- var bObj = {};
- bObj[ gM('mwe-ok') ] = function(){
- $j(this).dialog('close');
- };
- $j('#upProgressDialog').dialog('option','buttons', bObj);
- }
+
+ if ( !title_txt )
+ title_txt = _this.getProgressTitle();
+
+ if ( !msg )
+ msg = mv_get_loading_img( 'left:40%;top:40px;' );
+
+ if ( !buttons ) {
+ // If no buttons are specified, add a close button
+ buttons = {};
+ buttons[ gM( 'mwe-ok' ) ] = function() {
+ $j( this ).dialog( 'close' );
+ };
+ }
+
+ $j( '#upProgressDialog' ).dialog( 'option', 'title', title_txt );
+ $j( '#upProgressDialog' ).html( msg );
+ $j( '#upProgressDialog' ).dialog( 'option', 'buttons', buttons );
},
- getProgressTitle:function(){
- return gM('mwe-upload-in-progress');
+
+ /**
+ * Get the default title of the progress window
+ */
+ getProgressTitle: function() {
+ return gM( 'mwe-upload-in-progress' );
},
- getEditForm:function(){
- if( this.target_edit_from && $j( this.target_edit_from ).length != 0){
- return $j( this.target_edit_from ).get(0);
+
+ /**
+ * Get the DOMNode of the form element we are rewriting.
+ * Returns false if it can't be found.
+ */
+ getForm: function() {
+ if ( this.form_selector && $j( this.form_selector ).length != 0 ) {
+ return $j( this.form_selector ).get( 0 );
+ } else {
+ js_log( "mvBaseUploadInterface.getForm(): no form_selector" );
+ return false;
}
- //just return the first form fond on the page.
- return $j('form :first').get(0);
},
- updateProgress:function( perc ){
- //js_log('update progress: ' + perc);
- $j( '#up-progressbar' ).progressbar('value', parseInt( perc * 100 ) );
- $j( '#up-pstatus' ).html( parseInt( perc * 100 ) + '% - ' );
+
+ /**
+ * Update the progress bar to a given completion fraction (between 0 and 1)
+ */
+ updateProgress: function( fraction ) {
+ //js_log('update progress: ' + fraction);
+ $j( '#up-progressbar' ).progressbar( 'value', parseInt( fraction * 100 ) );
+ $j( '#up-pstatus' ).html( parseInt( fraction * 100 ) + '% - ' );
},
- /*update to jQuery.ui progress display type */
- dispProgressOverlay:function(){
- var _this = this;
-
- //remove old instance:
- if($j('#upProgressDialog').length !=0 ){
- $j('#upProgressDialog').dialog( 'destroy' ).remove();
- }
- //re add it:
- $j('body').append('<div id="upProgressDialog" ></div>');
-
- $j('#upProgressDialog').dialog({
- title:_this.getProgressTitle(),
- bgiframe: true,
- modal: true,
- draggable:true,
- width:400,
- heigh:200,
- beforeclose: function(event, ui) {
- if( event.button==0 && _this.action_done === false){
- return _this.cancel_action();
- }else{
- //click on button (don't do close action);
- return true;
- }
- },
- buttons: _this.cancel_button()
- });
- $j('#upProgressDialog').html(
- '<div id="up-pbar-container" style="width:90%;height:15px;" >' +
- '<div id="up-progressbar" style="height:15px;"></div>' +
- '<div id="up-status-container">'+
- '<span id="up-pstatus">0% - </span> ' +
- '<span id="up-status-state">' + gM('mwe-uploaded-status') + '</span> ' +
- '</div>'+
- '</div>'
- )
- //just display an empty progress window
- $j('#upProgressDialog').dialog('open');
-
- //setup progress bar:
- $j('#up-progressbar').progressbar({
- value:0
- });
+
+ /**
+ * Show a dialog box reporting upload progress and status
+ */
+ displayProgressOverlay: function() {
+ var _this = this;
+
+ // Remove the old instance if present
+ if( $j( '#upProgressDialog' ).length != 0 ) {
+ $j( '#upProgressDialog' ).dialog( 'destroy' ).remove();
+ }
+ // Add a new one
+ $j( 'body' ).append( '<div id="upProgressDialog" ></div>' );
+
+ $j( '#upProgressDialog' ).dialog( {
+ title: _this.getProgressTitle(),
+ bgiframe: true,
+ modal: true,
+ draggable: true,
+ width: 400,
+ heigh: 200,
+ beforeclose: function( event, ui ) {
+ // If the upload is not complete, ask the user if they want to cancel
+ if ( event.button == 0 && _this.action_done === false ) {
+ _this.onCancel();
+ return false;
+ } else {
+ // Complete already, allow close
+ return true;
+ }
+ },
+ buttons: _this.getCancelButton()
+ } );
+ $j( '#upProgressDialog' ).html(
+ '<div id="up-pbar-container" style="width:90%;height:15px;" >' +
+ '<div id="up-progressbar" style="height:15px;"></div>' +
+ '<div id="up-status-container">' +
+ '<span id="up-pstatus">0% - </span> ' +
+ '<span id="up-status-state">' + gM( 'mwe-uploaded-status' ) + '</span> ' +
+ '</div>'+
+ '</div>'
+ );
+ // Open the empty progress window
+ $j( '#upProgressDialog' ).dialog( 'open' );
+
+ // Create progress bar
+ $j( '#up-progressbar' ).progressbar({
+ value: 0
+ });
},
- cancel_button:function(){
- var _this = this;
- var cancelBtn = new Array();
- cancelBtn[ gM('mwe-cancel') ] = function(){
- return _this.cancel_action(this)
- };
- return cancelBtn;
+
+ /**
+ * Get a standard cancel button in the jQuery.ui dialog format
+ */
+ getCancelButton: function() {
+ var _this = this;
+ var cancelBtn = new Array();
+ cancelBtn[ gM( 'mwe-cancel' ) ] = function() {
+ return _this.onCancel( this )
+ };
+ return cancelBtn;
},
- cancel_action : function( dlElm ){
+
+ /**
+ * UI cancel button handler.
+ * Show a dialog box asking the user whether they want to cancel an upload.
+ * FIXME: doesn't work at all.
+ */
+ onCancel: function( dlElm ) {
//confirm:
- if( confirm( gM('mwe-cancel-confim') )){
+ if ( confirm( gM( 'mwe-cancel-confim' ) ) ) {
//@@todo (cancel the encode / upload)
- $j(this).dialog('close');
+ $j( this ).dialog( 'close' );
}
}
};
-//add some jquery binding helpers
-(function($) {
+// jQuery plugins
+
+( function( $ ) {
/**
- * doDestCheck checks the destination
+ * Check the upload destination filename for conflicts and show a conflict
+ * error message if there is one
*/
- $.fn.doDestCheck = function( opt ){
+ $.fn.doDestCheck = function( opt ) {
var _this = this;
- js_log('doDestCheck::' + _this.selector);
+ js_log( 'doDestCheck::' + _this.selector );
- //set up option defaults;
- if(!opt.warn_target)
+ // Set up option defaults
+ if ( !opt.warn_target )
opt.warn_target = '#wpDestFile-warning';
-
- //add the wpDestFile-warning target:
- if( $j( '#wpDestFile-warning' ).length == 0 )
- $j('#mw-htmlform-options tr:last').after('<tr><td></td><td id="wpDestFile-warning"></td></tr>');
-
- //empty target warn:
+
+ // Add the wpDestFile-warning row
+ if ( $j( '#wpDestFile-warning' ).length == 0 ) {
+ $j( '#mw-htmlform-options tr:last' )
+ .after( '<tr><td></td><td id="wpDestFile-warning"></td></tr>' );
+ }
+
+ // Remove any existing warning
$j( opt.warn_target ).empty();
-
- //show loading
- $j( _this.selector ).append('<img id="mw-spinner-wpDestFile" src ="'+ stylepath + '/common/images/spinner.gif" />');
-
- //try and get a thumb of the current file (check its destination)
- do_api_req({
- 'data':{
- 'titles': 'File:' + $j(_this.selector).val(),//@@todo we may need a more clever way to get a the filename
- 'prop': 'imageinfo',
- 'iiprop':'url|mime|size',
- 'iiurlwidth': 150
- }
- },function(data){
- //remove spinner:
- $j('#mw-spinner-wpDestFile').remove();
- if(data && data.query && data.query.pages){
- if( data.query.pages[-1] ){
- //all good no file there
- }else{
- for( var page_id in data.query.pages ) {
- if( data.query.pages[ page_id ].imageinfo ) {
- var ntitle = ( data.query.normalized)? data.query.normalized[0].to : data.query.pages[ page_id ].title
- var img = data.query.pages[ page_id ].imageinfo[0];
- $j('#wpDestFile-warning').html(
- gM('mwe-fileexists', ntitle) +
- '<div class="thumb tright">' +
- '<div style="width: ' + ( parseInt(img.thumbwidth)+2 ) + 'px;" class="thumbinner">' +
- '<a title="' + ntitle + '" class="image" href="' + img.descriptionurl + '">' +
- '<img width="' + img.thumbwidth + '" height="' + img.thumbheight + '" border="0" class="thumbimage" ' +
- 'src="' + img.thumburl + '"' +
- ' alt="' + ntitle + '"/>' +
- '</a>' +
- '<div class="thumbcaption">' +
- '<div class="magnify">' +
- '<a title="' + gM('thumbnail-more') + '" class="internal" ' +
- 'href="' + img.descriptionurl +'"><img width="15" height="11" alt="" ' +
- 'src="' + stylepath + "/common/images/magnify-clip.png\" />" +
- '</a>'+
- '</div>'+
- gM('mwe-fileexists-thumb') +
- '</div>' +
- '</div>'+
- '</div>'
- );
- }
+
+ // Show the AJAX spinner
+ $j( _this.selector )
+ .append( '<img id="mw-spinner-wpDestFile" ' +
+ 'src ="' + stylepath + '/common/images/spinner.gif" />' );
+
+ // Do the destination check
+ do_api_req(
+ {
+ 'data': {
+ //@@todo we may need a more clever way to get a the filename
+ 'titles': 'File:' + $j( _this.selector ).val(),
+ 'prop': 'imageinfo',
+ 'iiprop': 'url|mime|size',
+ 'iiurlwidth': 150
+ }
+ },
+ function( data ) {
+ // Remove spinner
+ $j( '#mw-spinner-wpDestFile' ).remove();
+
+ if ( !data || !data.query || !data.query.pages ) {
+ // Ignore a null result
+ return;
+ }
+
+ if ( data.query.pages[-1] ) {
+ // No conflict found
+ return;
+ }
+ for ( var page_id in data.query.pages ) {
+ if ( !data.query.pages[ page_id ].imageinfo ) {
+ continue;
}
+
+ // Conflict found, show warning
+ if ( data.query.normalized ) {
+ var ntitle = data.query.normalized[0].to;
+ } else {
+ var ntitle = data.query.pages[ page_id ].title
+ }
+ var img = data.query.pages[ page_id ].imageinfo[0];
+ $j( '#wpDestFile-warning' ).html(
+ gM( 'mwe-fileexists', ntitle ) +
+ '<div class="thumb tright">' +
+ '<div ' +
+ 'style="width: ' + ( parseInt( img.thumbwidth ) + 2 ) + 'px;" ' +
+ 'class="thumbinner">' +
+ '<a ' +
+ 'title="' + ntitle + '" ' +
+ 'class="image" ' +
+ 'href="' + img.descriptionurl + '">' +
+ '<img ' +
+ 'width="' + img.thumbwidth + '" ' +
+ 'height="' + img.thumbheight + '" ' +
+ 'border="0" ' +
+ 'class="thumbimage" ' +
+ 'src="' + img.thumburl + '" ' +
+ 'alt="' + ntitle + '"/>' +
+ '</a>' +
+ '<div class="thumbcaption">' +
+ '<div class="magnify">' +
+ '<a title="' + gM('thumbnail-more') + '" class="internal" ' +
+ 'href="' + img.descriptionurl +'">' +
+ '<img width="15" height="11" alt="" ' +
+ 'src="' + stylepath + "/common/images/magnify-clip.png\" />" +
+ '</a>' +
+ '</div>' +
+ gM( 'mwe-fileexists-thumb' ) +
+ '</div>' +
+ '</div>' +
+ '</div>'
+ );
}
}
- });
+ );
}
-})(jQuery);
+})( jQuery );
-/* adds firefogg support.
-* autodetects: new upload api or old http POST.
+/* Firefogg support.
+ * autodetects: new upload api or old http POST.
*/
loadGM({
"fogg-select_new_file" : "Select new file",
"fogg-select_url" : "Select URL",
"fogg-save_local_file" : "Save Ogg",
- "fogg-check_for_fogg" : "Checking for Firefogg...",
+ "fogg-check_for_firefogg" : "Checking for Firefogg...",
"fogg-installed" : "Firefogg is installed",
- "fogg-for_improved_uplods" : "For improved uploads:",
+ "fogg-for_improved_uploads" : "For improved uploads:",
"fogg-please_install" : "<a href=\"$1\">Install Firefogg<\/a>. More <a href=\"http:\/\/commons.wikimedia.org\/wiki\/Commons:Firefogg\">about Firefogg<\/a>.",
- "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>",
+ "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>",
"fogg-passthrough_mode" : "Your selected file is already Ogg or not a video file",
"fogg-transcoding" : "Encoding video to Ogg...",
"fogg-encoding-done" : "Encoding complete",
"fogg-hidepreview" : "Hide preview"
});
-var firefogg_install_links = {
- 'macosx': 'http://firefogg.org/macosx/Firefogg.xpi',
- 'win32': 'http://firefogg.org/win32/Firefogg.xpi',
- 'linux' : 'http://firefogg.org/linux/Firefogg.xpi'
+var firefogg_install_links = {
+ 'macosx': 'http://firefogg.org/macosx/Firefogg.xpi',
+ 'win32': 'http://firefogg.org/win32/Firefogg.xpi',
+ 'linux': 'http://firefogg.org/linux/Firefogg.xpi'
};
var default_firefogg_options = {
- // What to do when finished uploading
- 'done_upload_cb':false,
- // If firefoog is enabled
- 'fogg_enabled':false,
- // The api url to upload to
- 'api_url':null,
- // The passthrough flag (enables un-modified uploads)
+ // Callback for upload completion
+ 'done_upload_cb': false,
+
+ // True if Firefogg is enabled in the client
+ 'have_firefogg': false,
+
+ // The API URL to upload to
+ 'api_url': null,
+
+ // True when a file is uploaded without re-encoding
'passthrough': false,
- // If we will be showing the encoder interface
+
+ // True if we will be showing the encoder interface
'encoder_interface': false,
- // If we want to limit the library functionality to "only firefoog" (no upload or progress bars)
- 'only_fogg': false,
- // Callbacks:
- 'new_source_cb': false, //called on source name update passes along source name
+ // True if we want to limit the library functionality to "only firefogg"
+ // (no upload or progress bars)
+ 'only_firefogg': false,
- // Target control container or form (can't be left null)
+ // Callback which is called when the source name changes
+ 'new_source_cb': false,
+
+ // CSS selector identifying the target control container or form (can't be left null)
'selector': '',
- // If not rewriting a form we are encoding local.
- 'form_rewrite': false,
+ // May be "upload" to if we are rewriting an upload form, or "local" if we are encoding a local file
+ 'form_type': 'local',
- // Target buttons:
+ // CSS selector for the select file button
'target_btn_select_file': false,
+
+ // CSS selector for the select new file button
'target_btn_select_new_file': false,
- //'target_btn_select_url': false,
+ // CSS selector for the save local file button
'target_btn_save_local_file': false,
+
+ // CSS selector for the input file name button
'target_input_file_name': false,
+ // CSS selector for the "checking for firefogg..." message div
+ 'target_check_for_firefogg': false,
- // Target install descriptions
- 'target_check_for_fogg': false,
+ // CSS selector for the "firefogg is installed" message div
'target_installed': false,
+
+ // CSS selector for the "please install firefogg" message div
'target_please_install': false,
- 'target_use_latest_fox': false,
-
- // Status:
- 'target_passthrough_mode':false,
-
- // If firefogg should take over the form submit action
- 'firefogg_form_action':true,
-
- // If we should show a preview of encoding progress
- 'show_preview':false
-}
-
-
-var mvFirefogg = function(iObj){
- return this.init( iObj );
-}
-mvFirefogg.prototype = { //extends mvBaseUploadInterface
-
- min_firefogg_version : '0.9.9.5',
- fogg_enabled : false, //if firefogg is enabled or not.
- encoder_settings:{ //@@todo allow server to set this
+
+ // CSS selector for the "please use Firefox 3.5" message div
+ 'target_use_latest_firefox': false,
+
+ // CSS selector for the message div warning that passthrough mode is enabled
+ 'target_passthrough_mode': false,
+
+ // True if firefogg should take over the form submit action
+ 'firefogg_form_action': true,
+
+ // True if we should show a preview of the encoding progress
+ 'show_preview': false
+};
+
+
+var mvFirefogg = function( options ) {
+ return this.init( options );
+};
+
+mvFirefogg.prototype = { // extends mvBaseUploadInterface
+ min_firefogg_version: '0.9.9.5',
+ default_encoder_settings: { // @@todo allow the server to set these
'maxSize' : '400',
'videoBitrate' : '544',
'audioBitrate' : '96',
'noUpscaling' : true
},
- sourceFileInfo: {},
- ogg_extensions: ['ogg', 'ogv', 'oga'],
- video_extensions: ['avi', 'mov', 'mp4', 'mp2', 'mpeg', 'mpeg2', 'mpeg4', 'dv', 'wmv'],
+ have_firefogg: null, // lazy initialised, use getFirefogg()
+ current_encoder_settings: null, // lazy initialised, use getEncoderSettings()
+ sourceFileInfo: null, // lazy initialised, use getSourceFileInfo()
+ ogg_extensions: [ 'ogg', 'ogv', 'oga' ],
+ video_extensions: [ 'avi', 'mov', 'mp4', 'mp2', 'mpeg', 'mpeg2', 'mpeg4', 'dv', 'wmv' ],
passthrough: false,
sourceMode: 'file',
- init: function( iObj ){
- if(!iObj)
- iObj = {};
+ /**
+ * Object initialisation
+ */
+ init: function( options ) {
+ if ( !options )
+ options = {};
- // If we have no api_url set upload to "post"
- if(!iObj.api_url)
- iObj.upload_mode = 'post';
+ // If we have no api_url, set upload mode to "post"
+ if ( !options.api_url )
+ options.upload_mode = 'post';
- // Inherit iObj properties:
- for(var i in default_firefogg_options){
- if(iObj[i]){
- this[i] = iObj[i];
- }else{
+ // Set options
+ for ( var i in default_firefogg_options ) {
+ if ( options[i] ) {
+ this[i] = options[i];
+ } else {
this[i] = default_firefogg_options[i];
}
}
- // Check if we want to limit the usage:
- if(!this.only_fogg){
- var myBUI = new mvBaseUploadInterface( iObj );
- // Standard extends code:
- for(var i in myBUI){
- if(this[i]){
+ // Inherit from mvBaseUploadInterface (unless we're in only_firefogg mode)
+ if ( !this.only_firefogg ) {
+ var myBUI = new mvBaseUploadInterface( options );
+
+ // Prefix conflicting members with pe_
+ for ( var i in myBUI ) {
+ if ( this[i] ) {
this['pe_'+ i] = myBUI[i];
- }else{
+ } else {
this[i] = myBUI[i];
}
}
}
- if(!this.selector){
+ if ( !this.selector ) {
js_log('firefogg: missing selector ');
}
},
- doRewrite:function( callback ){
- var _this = this;
- js_log('sel len: ' + this.selector + '::' + $j(this.selector).length + ' tag:'+ $j(this.selector).get(0).tagName);
- if( $j(this.selector).length >=0 ){
- if( $j(this.selector).get(0).tagName.toLowerCase() == 'input' ){
- _this.form_rewrite = true;
+ /**
+ * Rewrite the upload form, or create our own upload controls for local transcoding.
+ * Called from $j.firefogg(), in mv_embed.js.
+ */
+ doRewrite: function( callback ) {
+ var _this = this;
+ js_log( 'sel len: ' + this.selector + '::' + $j( this.selector ).length +
+ ' tag:' + $j( this.selector ).get( 0 ).tagName );
+ if ( $j( this.selector ).length >= 0 ) {
+ if ( $j( this.selector ).get( 0 ).tagName.toLowerCase() == 'input' ) {
+ _this.form_type = 'upload';
}
}
- // Check if we are rewriting an input or a form:
- if( this.form_rewrite ){
+ if ( this.form_type == 'upload' ) {
+ // Initialise existing upload form
this.setupForm();
- }else{
- this.doControlHTML();
- this.doControlBindings();
+ } else {
+ // Create our own form controls
+ this.createControls();
+ this.bindControls();
}
- // doRewrite is done:
- if(callback)
+ if ( callback )
callback();
},
- doControlHTML: function( ){
+
+ /**
+ * Create controls for local transcoding and add them to the page
+ */
+ createControls: function() {
var _this = this;
var out = '';
- $j.each(default_firefogg_options, function(target, na){
- if(target.substring(0, 6)=='target'){
- //js_log('check for target html: ' + target);
- // Check for the target if missing add to the output:
- if( _this[target] === false){
- out += _this.getTargetHtml(target) + ' ';
+ $j.each( default_firefogg_options, function( target, na ) {
+ if ( /^target/.test( target ) ) {
+ // Create the control if it doesn't already exist
+ if( _this[target] === false ) {
+ out += _this.getControlHtml(target) + ' ';
// Update the target selector
- _this[target] = _this.selector + ' .' + target;
+ _this[target] = _this.selector + ' .' + target;
}
}
});
$j( this.selector ).append( out ).hide();
},
- getTargetHtml:function(target){
- if( target.substr(7,3)=='btn'){
- return '<input style="" class="' + target + '" type="button" value="' + gM( 'fogg-' + target.substring(11)) + '"/> ';
- }else if(target.substr(7,5)=='input'){
- return '<input style="" class="' + target + '" type="text" value="' + gM( 'fogg-' + target.substring(11)) + '"/> ';
- }else{
- return '<div style="" class="' + target + '" >'+ gM('fogg-'+ target.substring(7)) + '</div> ';
+
+ /**
+ * Get the HTML for the control with a particular name
+ */
+ getControlHtml: function( target ) {
+ if ( /^target_btn_/.test( target ) ) {
+ // Button
+ var msg = gM( target.replace( /^target_btn_/, 'fogg-' ) );
+ return '<input style="" ' +
+ 'class="' + target + '" ' +
+ 'type="button" ' +
+ 'value="' + msg + '"/> ';
+ } else if ( /^target_input_/.test( target ) ) {
+ // Text input
+ var msg = gM( target.replace( /^target_input_/, 'fogg-' ) );
+ return '<input style="" ' +
+ 'class="' + target + '" ' +
+ 'type="text" ' +
+ 'value="' + msg + '"/> ';
+ } else if ( /^target_/.test( target ) ) {
+ // Message
+ var msg = gM( target.replace( '/^target_/', 'fogg-' ) );
+ return '<div style="" class="' + target + '" >' + msg + '</div> ';
+ } else {
+ js_error( 'Invalid target: ' + target );
+ return '';
}
},
- doControlBindings: function(){
+
+ /**
+ * Set up events for the controls which were created with createControls()
+ */
+ bindControls: function() {
var _this = this;
- // Hide all targets:
- var hide_target_list='';
- var coma='';
- $j.each( default_firefogg_options, function(target, na) {
- if(target.substring(0, 6)=='target'){
- hide_target_list+=coma + _this[target];
- coma=',';
+ // Hide all controls
+ var hide_target_list = '';
+ var comma = '';
+ $j.each( default_firefogg_options, function( target, na ) {
+ if ( /^target/.test( target ) ) {
+ hide_target_list += comma + _this[target];
+ comma = ',';
}
});
-
- // Hide all but check-for-fogg
$j( hide_target_list ).hide();
- // Now that the proper set of items has been hiiden show:
+
+ // Now show the form
$j( _this.selector ).show();
-
- // Check for firefogg
- if( _this.firefoggCheck() ){
- // If rewriting the form lets keep the text input around:
- if( _this.form_rewrite )
+ if ( _this.firefoggCheck() ) {
+ // Firefogg enabled
+ // If we're in upload mode, show the input filename
+ if ( _this.form_type == 'upload' )
$j( _this.target_input_file_name ).show();
- // Show select file:
- $j( this.target_btn_select_file ).unbind(
- ).attr('disabled', false
- ).css({'display':'inline'}
- ).click(function(){
- _this.selectFogg();
- });
+ // Show the select file button
+ $j( this.target_btn_select_file )
+ .unbind()
+ .attr( 'disabled', false )
+ .css( { 'display': 'inline' } )
+ .click( function() {
+ _this.selectSourceFile();
+ } );
- //also setup the text file display on Click to select file:
- $j(this.target_input_file_name).unbind().attr('readonly', 'readonly').click(function(){
- _this.selectFogg();
- })
+ // Set up the click handler for the filename box
+ $j( this.target_input_file_name )
+ .unbind()
+ .attr( 'readonly', 'readonly' )
+ .click( function() {
+ _this.selectSourceFile();
+ });
+ } else {
+ // Firefogg disabled
+ // FIXME: move this elsewhere. None of this is related to binding.
- }else{
- // First check firefox version:
- if(!( $j.browser.mozilla && $j.browser.version >= '1.9.1' )) {
- js_log( 'show use latest::' + _this.target_use_latest_fox );
- if( _this.target_use_latest_fox ){
- if( _this.form_rewrite )
- $j( _this.target_use_latest_fox ).prepend( gM('fogg-for_improved_uplods') );
+ // Show the "use latest Firefox" message if necessary
+ if ( !( $j.browser.mozilla && $j.browser.version >= '1.9.1' ) ) {
+ js_log( 'show use latest::' + _this.target_use_latest_firefox );
+ if ( _this.target_use_latest_firefox ) {
+ if ( _this.form_type == 'upload' )
+ $j( _this.target_use_latest_firefox )
+ .prepend( gM( 'fogg-for_improved_uploads' ) );
- $j( _this.target_use_latest_fox ).show();
+ $j( _this.target_use_latest_firefox ).show();
}
- return ;
+ return;
}
- // If rewriting form use upload msg text
- var upMsg = (_this.form_rewrite) ? gM('fogg-for_improved_uplods') : '';
- $j( _this.target_please_install ).html( upMsg + gM('fogg-please_install', _this.getOSlink() )).css('padding', '10px').show();
+ // Otherwise show the "install Firefogg" message
+ // FIXME: getFirefoggInstallUrl() may return false, this is not handled
+ var upMsg = ( _this.form_type == 'upload' ) ? gM( 'fogg-for_improved_uploads' ) : '';
+ $j( _this.target_please_install )
+ .html( upMsg + gM( 'fogg-please_install', _this.getFirefoggInstallUrl() ) )
+ .css( 'padding', '10px' )
+ .show();
}
- // Setup the target save local file bindings:
- $j( _this.target_btn_save_local_file ).unbind().click(function(){
- _this.saveLocalFogg();
- });
+
+ // Set up the click handler for the "save local file" button
+ $j( _this.target_btn_save_local_file )
+ .unbind()
+ .click( function() {
+ _this.doLocalEncodeAndSave();
+ } );
},
+
/*
- * returns the firefogg link for your os:
+ * Get the URL for installing firefogg on the client OS
*/
- getOSlink:function(){
+ getFirefoggInstallUrl: function() {
var os_link = false;
- if(navigator.oscpu){
- if(navigator.oscpu.search('Linux') >= 0)
+ if ( navigator.oscpu ) {
+ if ( navigator.oscpu.search( 'Linux' ) >= 0 )
os_link = firefogg_install_links['linux'];
- else if(navigator.oscpu.search('Mac') >= 0)
- os_link = firefogg_install_links['macosx'];
- else if(navigator.oscpu.search('Win') >= 0)
- os_link = firefogg_install_links['win32'];
+ else if ( navigator.oscpu.search( 'Mac' ) >= 0 )
+ os_link = firefogg_install_links['macosx'];
+ else if (navigator.oscpu.search( 'Win' ) >= 0 )
+ os_link = firefogg_install_links['win32'];
}
- return os_link
+ return os_link;
},
- firefoggCheck:function(){
- if(typeof(Firefogg) != 'undefined' && Firefogg().version >= this.min_firefogg_version){
- this.fogg = new Firefogg();
- this.fogg_enabled = true;
- return true;
- }else{
- return false;
+
+ /**
+ * Get the Firefogg instance (or false if firefogg is unavailable)
+ */
+ getFirefogg: function() {
+ if ( this.have_firefogg == null ) {
+ if ( typeof( Firefogg ) != 'undefined'
+ && Firefogg().version >= this.min_firefogg_version )
+ {
+ this.have_firefogg = true;
+ this.fogg = new Firefogg();
+ } else {
+ this.have_firefogg = false;
+ this.fogg = false;
+ }
}
+ return this.fogg;
},
- // Assume input target
- setupForm: function(){
- js_log('firefogg::setupForm::');
- //to parent form setup if we want http updates
- if( this.form_rewrite ){
- //do parent form setup:
+
+ /**
+ * Set up the upload form
+ */
+ setupForm: function() {
+ js_log( 'firefogg::setupForm::' );
+
+ // Set up the parent if we are in upload mode
+ if ( this.form_type == 'upload' ) {
this.pe_setupForm();
}
- // Check if we have firefogg (if not just add a link and stop processing)
- if( !this.firefoggCheck() ){
- //add some status indicators if not provided:
- if(!this.target_please_install){
- $j(this.selector).after ( this.getTargetHtml('target_please_install') );
+ // If Firefogg is not available, just show a "please install" message
+ if ( !this.firefoggCheck() ) {
+ if ( !this.target_please_install ) {
+ $j( this.selector ).after( this.getControlHtml( 'target_please_install' ) );
this.target_please_install = this.selector + ' ~ .target_please_install';
}
- if(!this.target_use_latest_fox){
- $j(this.selector).after ( this.getTargetHtml('target_use_latest_fox') );
- this.target_use_latest_fox = this.selector + ' ~ .target_use_latest_fox';
+ if ( !this.target_use_latest_firefox ) {
+ $j( this.selector ).after( this.getControlHtml( 'target_use_latest_firefox' ) );
+ this.target_use_latest_firefox = this.selector + ' ~ .target_use_latest_firefox';
}
- // Update download link:
- this.doControlBindings();
- return ;
+ // Show download link
+ this.bindControls();
+ return;
}
- // Change the file browser to type text: (can't directly change input from "file" to "text" so longer way:
- var inTag = '<input ';
- $j.each($j(this.selector).get(0).attributes, function(i, attr){
+ // Change the file browser to type text. We can't simply change the attribute so
+ // we have to delete and recreate.
+ var inputTag = '<input ';
+ $j.each( $j( this.selector ).get( 0 ).attributes, function( i, attr ) {
var val = attr.value;
- if( attr.name == 'type')
+ if ( attr.name == 'type' )
val = 'text';
- inTag += attr.name + '="' + val + '" ';
- });
- if(!$j(this.selector).attr('style'))
- inTag += 'style="display:inline" ';
+ inputTag += attr.name + '="' + val + '" ';
+ } );
+ if ( !$j( this.selector ).attr( 'style' ) )
+ inputTag += 'style="display:inline" ';
- inTag+= '/><span id="' + $j(this.selector).attr('name') + '_fogg-control"></span>';
+ var id = $j( this.selector ).attr( 'name' ) + '_firefogg-control';
+ inputTag += '/><span id="' + id + '"></span>';
- js_log('set input: ' + inTag);
- $j(this.selector).replaceWith(inTag);
+ js_log( 'set input: ' + inputTag );
+ $j( this.selector ).replaceWith( inputTag );
- this.target_input_file_name = 'input[name=' + $j(this.selector).attr('name') + ']';
-
- // Update the selector to the control target:
- this.selector = '#' + $j(this.selector).attr('name') + "_fogg-control";
+ this.target_input_file_name = 'input[name=' + $j( this.selector ).attr( 'name' ) + ']';
- this.doControlHTML();
+ // Point the selector at the span we just created
+ this.selector = '#' + id;
- // Update the bindings:
- this.doControlBindings();
+ // Create controls for local transcoding
+ this.createControls();
+ this.bindControls();
},
- // Do firefogg specific additions:
- dispProgressOverlay:function(){
- this.pe_dispProgressOverlay();
- // If we are uploading video (not in passthrough mode show preview button)
- if( this.fogg_enabled && ! this.encoder_settings['passthrough'] && ! this.http_copy_upload ){
- this.doPreviewControl();
+
+ /**
+ * Display an upload progress overlay. Overrides the function in mvBaseUploadInterface.
+ */
+ displayProgressOverlay: function() {
+ this.pe_dispProgressOverlay();
+ // If we are uploading video (not in passthrough mode), show preview button
+ if( this.getFirefogg() && !this.getEncoderSettings()['passthrough']
+ && !this.isCopyUpload() )
+ {
+ this.createPreviewControls();
}
},
- doPreviewControl:function(){
+
+ /**
+ * Create controls for showing a transcode/crop/resize preview
+ */
+ createPreviewControls: function() {
var _this = this;
- // Prepend preview (if fogg)
- $j('#upProgressDialog').append(
- '<div style="clear:both;height:3em"/>'+
- $j.btnHtml(gM('fogg-preview'), 'fogg_preview', 'triangle-1-e') +
- '<div style="padding:10px;">' +
+ // Add the preview button and canvas
+ $j( '#upProgressDialog' ).append(
+ '<div style="clear:both;height:3em"/>' +
+ $j.btnHtml( gM( 'fogg-preview' ), 'fogg_preview', 'triangle-1-e' ) +
+ '<div style="padding:10px;">' +
'<canvas style="margin:auto;" id="fogg_preview_canvas" />' +
'</div>'
);
- // Set initial state
- if( _this.show_preview == true){
- $j('#fogg_preview_canvas').show();
- }else{
- // Update icon:
- $j(this).children('.ui-icon')
- .removeClass('ui-icon-triangle-1-s')
- .addClass('ui-icon-triangle-1-e');
- // Update text:
- $j(this).children('.btnText').text( gM('fogg-preview') );
- $j('#fogg_preview_canvas').hide();
- }
- // Apply preview binding:
- $j('#upProgressDialog .fogg_preview').btnBind().click( function(){
- js_log("click .foog_preview" + $j(this).children('.ui-icon').attr('class') );
- // Check state:
- if( $j(this).children('.ui-icon').hasClass('ui-icon-triangle-1-e') ){
- _this.show_preview = true;
- // Update icon:
- $j(this).children('.ui-icon')
- .removeClass('ui-icon-triangle-1-e')
- .addClass('ui-icon-triangle-1-s');
- // Update text
- $j(this).children('.btnText').text( gM('fogg-hidepreview') );
-
- // Show preview window
- $j('#fogg_preview_canvas').show('fast');
- }else{
- _this.show_preview = false;
- // Update icon:
- $j(this).children('.ui-icon')
- .removeClass('ui-icon-triangle-1-s')
- .addClass('ui-icon-triangle-1-e');
- // Update text:
- $j(this).children('.btnText').text( gM('fogg-preview') );
-
- $j('#fogg_preview_canvas').hide('slow');
- }
- // Don't follow the #
- return false;
+
+ // Set the initial state
+ if ( _this.show_preview == true ) {
+ $j( '#fogg_preview_canvas' ).show();
+ } else {
+ // Fix the icon class
+ $j( this ).children( '.ui-icon' )
+ .removeClass( 'ui-icon-triangle-1-s' )
+ .addClass( 'ui-icon-triangle-1-e' );
+ // Set the button text
+ $j( this ).children( '.btnText' ).text( gM( 'fogg-preview' ) );
+ $j( '#fogg_preview_canvas' ).hide();
+ }
+
+ // Bind the preview button
+ $j( '#upProgressDialog .fogg_preview' ).btnBind().click( function() {
+ return _this.onPreviewClick( this );
});
- },
- doRenderPreview:function(){
- var _this = this;
- // Set up the hidden video to pull frames from:
- if( $j('#fogg_preview_vid').length == 0 )
- $j('body').append('<video id="fogg_preview_vid" style="display:none"></video>');
- var v = $j('#fogg_preview_vid').get(0);
-
- function seekToEnd(){
- var v = $j('#fogg_preview_vid').get(0);
- v.currentTime = v.duration-0.4;
- }
- function getFrame() {
- var v = $j('#fogg_preview_vid').get(0);
- var canvas = $j('#fogg_preview_canvas').get(0);
- if( canvas ){
+ },
+
+ /**
+ * onclick handler for the hide/show preview button
+ */
+ onPreviewClick: function( sourceNode ) {
+ var button = $j( sourceNode );
+ var icon = button.children( '.ui-icon' );
+ js_log( "click .fogg_preview" + icon.attr( 'class' ) );
+
+ if ( icon.hasClass( 'ui-icon-triangle-1-e' ) ) {
+ // Show preview
+ // Toggle button class and set button text to "hide".
+ this.show_preview = true;
+ icon.removeClass( 'ui-icon-triangle-1-e' ).addClass( 'ui-icon-triangle-1-s' );
+ button.children( '.btnText' ).text( gM( 'fogg-hidepreview' ) );
+ $j( '#fogg_preview_canvas' ).show( 'fast' );
+ } else {
+ // Hide preview
+ // Toggle button class and set button text to "show".
+ this.show_preview = false;
+ icon.removeClass( 'ui-icon-triangle-1-s' ).addClass( 'ui-icon-triangle-1-e' );
+ button.children( '.btnText' ).text( gM( 'fogg-preview' ) );
+ $j( '#fogg_preview_canvas' ).hide( 'slow' );
+ }
+ // Don't follow the # link
+ return false;
+ },
+
+ /**
+ * Render the preview frame (asynchronously)
+ */
+ renderPreview: function() {
+ var _this = this;
+ // Set up the hidden video to pull frames from
+ if( $j( '#fogg_preview_vid' ).length == 0 )
+ $j( 'body' ).append( '<video id="fogg_preview_vid" style="display:none"></video>' );
+ var v = $j( '#fogg_preview_vid' ).get( 0 );
+
+ function seekToEnd() {
+ var v = $j( '#fogg_preview_vid' ).get( 0 );
+ // TODO: document arbitrary 0.4s constant
+ v.currentTime = v.duration - 0.4;
+ }
+ function renderFrame() {
+ var v = $j( '#fogg_preview_vid' ).get( 0 );
+ var canvas = $j( '#fogg_preview_canvas' ).get( 0 );
+ if ( canvas ) {
canvas.width = 160;
- canvas.height = canvas.width * v.videoHeight/v.videoWidth;
- var ctx = canvas.getContext("2d");
- ctx.drawImage(v, 0, 0, canvas.width, canvas.height);
+ canvas.height = canvas.width * v.videoHeight / v.videoWidth;
+ var ctx = canvas.getContext( "2d" );
+ ctx.drawImage( v, 0, 0, canvas.width, canvas.height );
}
- }
- var previewI=null;
- function preview() {
- // Initialize the video if not setup already:
- var v = $j('#fogg_preview_vid').get(0);
- if( v.src != _this.fogg.previewUrl ){
- js_log('init preview with url:' + _this.fogg.previewUrl);
+ }
+ function preview() {
+ // Initialize the video if it is not set up already
+ var v = $j( '#fogg_preview_vid' ).get( 0 );
+ if ( v.src != _this.fogg.previewUrl ) {
+ js_log( 'init preview with url:' + _this.fogg.previewUrl );
v.src = _this.fogg.previewUrl;
-
- // Set the video to seek to the end of the video
- v.removeEventListener("loadedmetadata", seekToEnd, true);
- v.addEventListener("loadedmetadata", seekToEnd, true);
-
- // Render a frame once seek is complete:
- v.removeEventListener("seeked", getFrame, true);
- v.addEventListener("seeked", getFrame, true);
-
- // Refresh the video duration/meta:
- clearInterval(previewI);
- var previewI = setInterval(function(){
- if (_this.fogg.status() != "encoding"){
- clearInterval(previewI);
+
+ // Once it's loaded, seek to the end
+ v.removeEventListener( "loadedmetadata", seekToEnd, true );
+ v.addEventListener( "loadedmetadata", seekToEnd, true );
+
+ // When the seek is done, render a frame
+ v.removeEventListener( "seeked", renderFrame, true );
+ v.addEventListener( "seeked", renderFrame, true );
+
+ // Refresh the video duration and metadata
+ var previewTimer = setInterval( function() {
+ if ( _this.fogg.status() != "encoding" ) {
+ clearInterval( previewTimer );
_this.show_preview == false;
}
- if (_this.show_preview == true) {
+ if ( _this.show_preview == true ) {
v.load();
}
- }, 1000);
- }
- }
- preview();
+ }, 1000 );
+ }
+ }
+ preview();
},
- getEditForm:function(){
- if( this.target_edit_from )
- return this.pe_getEditForm();
- // Else try to get the parent "from" of the file selector:
- return $j(this.selector).parents('form:first').get(0);
+
+ /**
+ * Get the DOMNode of the form element we are rewriting.
+ * Returns false if it can't be found.
+ * Overrides mvBaseUploadInterface.getForm().
+ */
+ getForm: function() {
+ if ( this.form_selector ) {
+ return this.pe_getForm();
+ } else {
+ // No configured form selector
+ // Use the first form descendant of the current container
+ return $j( this.selector ).parents( 'form:first' ).get( 0 );
+ }
},
- selectFogg:function(){
+
+ /**
+ * Show a dialog box allowing the user to select the source file of the
+ * encode/upload operation. The filename is stored by Firefogg until the
+ * next encode/upload call.
+ *
+ * After a successful select, the UI is updated accordingly.
+ */
+ selectSourceFile: function() {
var _this = this;
- if(_this.fogg.selectVideo() ){
- this.selectFoggActions();
+ if( !_this.fogg.selectVideo() ) {
+ // User clicked "cancel"
+ return;
}
+ _this.clearSourceInfoCache();
+ _this.updateSourceFileUI();
},
- selectFoggActions:function(){
- var _this = this;
- js_log('videoSelectReady');
- // If not already hidden hide select file and show "select new":
- $j(_this.target_btn_select_file).hide();
-
- // Show and setup binding for select new file:
- $j(_this.target_btn_select_new_file).show().unbind().click(function(){
- //create new fogg instance:
- _this.fogg = new Firefogg();
- _this.selectFogg();
- });
- // Update if we are in passthrough mode or going to encode
- if( _this.fogg.sourceInfo && _this.fogg.sourceFilename ){
- //update the source status
- try{
- _this.sourceFileInfo = JSON.parse( _this.fogg.sourceInfo ) ;
- }catch (e){
- js_error('error could not parse fogg sourceInfo');
+ /**
+ * Update the UI due to the source file changing
+ */
+ updateSourceFileUI: function() {
+ js_log( 'videoSelectReady' );
+
+ if ( !_this.fogg.sourceInfo || !_this.fogg.sourceFilename ) {
+ // Something wrong with the source file?
+ js_log( 'selectSourceFile: sourceInfo/sourceFilename missing' );
+ return;
+ }
+
+ // Hide the "select file" button and show "select new"
+ $j( _this.target_btn_select_file ).hide();
+ $j( _this.target_btn_select_new_file)
+ .show()
+ .unbind()
+ .click( function() {
+ _this.fogg = new Firefogg();
+ _this.selectSourceFile();
+ } );
+
+ var settings = this.getEncoderSettings();
+
+ // If we're in passthrough mode, update the interface (if not a form)
+ if ( settings['passthrough'] == true && _this.form_type == 'local' ) {
+ $j( _this.target_passthrough_mode ).show();
+ } else {
+ $j( _this.target_passthrough_mode ).hide();
+ // Show the "save file" button if this is a local form
+ if ( _this.form_type == 'local' ) {
+ $j( _this.target_btn_save_local_file ).show();
+ } // else the upload will be done on form submit
+ }
+
+ // Update the input file name box and show it
+ js_log( " should update: " + _this.target_input_file_name +
+ ' to: ' + _this.fogg.sourceFilename );
+ $j( _this.target_input_file_name )
+ .val( _this.fogg.sourceFilename )
+ .show();
+
+
+ // Notify callback new_source_cb
+ if ( _this.new_source_cb ) {
+ if ( settings['passthrough'] ) {
+ var fName = _this.fogg.sourceFilename;
+ } else {
+ var oggExt = _this.isSourceAudio() ? 'oga' : 'ogg';
+ oggExt = _this.isSourceVideo() ? 'ogv' : oggExt;
+ oggExt = _this.isUnknown() ? 'ogg' : oggExt;
+ oggName = _this.fogg.sourceFilename.substr( 0,
+ _this.fogg.sourceFilename.lastIndexOf( '.' ) );
+ var fName = oggName + '.' + oggExt;
}
+ _this.new_source_cb( _this.fogg.sourceFilename, fName );
+ }
+ },
- // Now setup encoder settings based source type:
- _this.autoEncoderSettings();
-
- // If set to passthough update the interface (if not a form)
- if(_this.encoder_settings['passthrough'] == true && !_this.form_rewrite){
- $j(_this.target_passthrough_mode).show();
- }else{
- $j(_this.target_passthrough_mode).hide();
- // If set to encoder expose the encode button:
- if( !_this.form_rewrite ){
- $j(_this.target_btn_save_local_file).show();
- }
+ /**
+ * Get the source file info for the current file selected into this.fogg
+ */
+ getSourceFileInfo: function() {
+ if ( this.sourceFileInfo == null ) {
+ if ( !this.fogg.sourceInfo ) {
+ js_error( 'No firefogg source info is available' );
+ return false;
}
- //~otherwise the encoding will be triggered by the form~
-
- // Do source name update callback:
- js_log(" should update: " + _this.target_input_file_name + ' to: ' + _this.fogg.sourceFilename );
- $j(_this.target_input_file_name).val(_this.fogg.sourceFilename).show();
-
- if(_this.new_source_cb){
- if(_this.encoder_settings['passthrough']){
- var fName = _this.fogg.sourceFilename
- }else{
- var oggExt = (_this.isSourceAudio())?'oga':'ogg';
- oggExt = (_this.isSourceVideo())?'ogv':oggExt;
- oggExt = (_this.isUnknown())?'ogg':oggExt;
- oggName = _this.fogg.sourceFilename.substr(0,
- _this.fogg.sourceFilename.lastIndexOf('.'));
- var fName = oggName +'.'+ oggExt
- }
- _this.new_source_cb( _this.fogg.sourceFilename , fName);
+ try {
+ this.sourceFileInfo = JSON.parse( firefogg.sourceInfo );
+ } catch ( e ) {
+ js_error( 'error could not parse fogg sourceInfo' );
+ return false;
}
}
+ return this.sourceFileInfo;
},
- saveLocalFogg:function(){
- // Request target location:
- if(this.fogg){
- if(!this.fogg.saveVideoAs() )
- return false;
-
- // We have set a target now call the encode:
- this.doEncode();
- }
+
+ /**
+ * Clear the cache of the source file info, presumably due to a new file
+ * being selected into this.fogg
+ */
+ clearSourceInfoCache: function() {
+ this.sourceFileInfo = null;
+ this.current_encoder_settings = null;
},
- // Simple auto encoder settings just enable passthough if file is not video or > 480 pixles tall
- autoEncoderSettings:function(){
+
+ /**
+ * Save the result of the transcode as a local file
+ */
+ doLocalEncodeAndSave: function() {
var _this = this;
- // Grab the extension:
- var sf = _this.fogg.sourceFilename;
- var ext = '';
- if( sf.lastIndexOf('.') != -1)
- ext = sf.substring( sf.lastIndexOf('.')+1 ).toLowerCase();
-
- // Set to passthrough to true by default (images, arbitrary files that we want to send with http chunks)
- this.encoder_settings['passthrough'] = true;
-
- // See if we have video or audio:
- if( _this.isSourceAudio() || _this.isSourceVideo() )
- _this.encoder_settings['passthrough'] = false;
-
- // Special case see if we already have ogg video:
- if( _this.isOggFormat() )
- _this.encoder_settings['passthrough'] = true;
-
- js_log('base autoEncoderSettings::' + _this.sourceFileInfo.contentType + ' passthrough:' + _this.encoder_settings['passthrough']);
+ if ( !this.fogg ) {
+ js_error( 'doLocalEncodeAndSave: no Firefogg object!' );
+ return false;
+ }
+
+ // Set up the target location
+ // Firefogg shows the "save as" dialog box, and sets the path chosen as
+ // the destination for a later encode() call.
+ if ( !this.fogg.saveVideoAs() ) {
+ // User clicked "cancel"
+ return false;
+ }
+
+ // We have a source file, now do the encode
+ this.doEncode(
+ function /* onProgress */ ( progress ) {
+ _this.updateProgress( progress );
+ },
+ function /* onDone */ () {
+ js_log( "done with encoding (no upload) " );
+ // Set status to 100% for one second
+ // FIXME: this is either a hack or a waste of time, not sure which
+ _this.updateProgress( 1 );
+ setTimeout( function() {
+ _this.onLocalEncodeDone();
+ }
+ }
+ );
},
- isUnknown:function(){
- return (this.sourceFileInfo.contentType.indexOf("unknown") != -1);
+
+ /**
+ * This is called when a local encode operation has completed. It updates the UI.
+ */
+ onLocalEncodeDone() {
+ var _this = this;
+ _this.updateProgressWin( gM( 'fogg-encoding-done' ),
+ gM( 'fogg-encoding-done' ) + '<br>' +
+ //show the video at full resolution upto 720px wide
+ '<video controls="true" style="margin:auto" id="fogg_final_vid" src="' +
+ _this.fogg.previewUrl + '"></video>'
+ );
+ //load the video and set a callback:
+ var v = $j( '#fogg_final_vid' ).get( 0 );
+ function resizeVid() {
+ var v = $j( '#fogg_final_vid' ).get(0);
+ if ( v.videoWidth > 720 ) {
+ var vW = 720;
+ var vH = 720 * v.videoHeight / v.videoWidth;
+ } else {
+ var vW = v.videoWidth;
+ var vH = v.videoHeight;
+ }
+ //reize the video:
+ $j( v ).css({
+ 'width': vW,
+ 'height': vH
+ });
+ //if large video resize the dialog box:
+ if( vW + 5 > 400 ) {
+ //also resize the dialog box
+ $j( '#upProgressDialog' ).dialog( 'option', 'width', vW + 20 );
+ $j( '#upProgressDialog' ).dialog( 'option', 'height', vH + 120 );
+
+ //also position the dialog container
+ $j( '#upProgressDialog') .dialog( 'option', 'position', 'center' );
+ }
+ }
+ v.removeEventListener( "loadedmetadata", resizeVid, true );
+ v.addEventListener( "loadedmetadata", resizeVid, true );
+ v.load();
},
- isSourceAudio:function(){
- return (this.sourceFileInfo.contentType.indexOf("audio/") != -1);
+
+ /**
+ * Get the appropriate encoder settings for the current Firefogg object,
+ * into which a video has already been selected.
+ */
+ getEncoderSettings function() {
+ if ( this.current_encoder_settings == null ) {
+ // Clone the default settings
+ var defaults = function () {};
+ var defaults.prototype = this.default_encoder_settings;
+ var settings = new defaults();
+
+ // Grab the extension
+ var sf = this.fogg.sourceFilename;
+ if ( !sf ) {
+ js_error( 'getEncoderSettings(): No Firefogg source filename is available!' );
+ return false;
+ }
+ var ext = '';
+ if ( sf.lastIndexOf('.') != -1 )
+ ext = sf.substring( sf.lastIndexOf( '.' ) + 1 ).toLowerCase();
+
+ // Determine passthrough mode
+ if ( this.isOggFormat() ) {
+ // Already Ogg, no need to encode
+ settings['passthrough'] = true;
+ } else if ( this.isSourceAudio() || this.isSourceVideo() ) {
+ // OK to encode
+ settings['passthrough'] = false;
+ } else {
+ // Not audio or video, can't encode
+ settings['passthrough'] = true;
+ }
+
+ js_log( 'base setupAutoEncoder::' + this.getSourceFileInfo().contentType +
+ ' passthrough:' + settings['passthrough'] );
+ this.current_encoder_settings = settings;
+ }
+ return this.current_encoder_settings;
},
- isSourceVideo:function(){
- return (this.sourceFileInfo.contentType.indexOf("video/") != -1);
+
+ isUnknown: function() {
+ return ( this.getSourceFileInfo().contentType.indexOf("unknown") != -1 );
+ },
+
+ isSourceAudio: function() {
+ return ( this.getSourceFileInfo().contentType.indexOf("audio/") != -1 );
},
- isOggFormat:function(){
- return ( this.sourceFileInfo.contentType.indexOf("video/ogg") != -1 ||
- this.sourceFileInfo.contentType.indexOf("application/ogg") != -1 );
+
+ isSourceVideo: function() {
+ return ( this.getSourceFileInfo().contentType.indexOf("video/") != -1 );
+ },
+
+ isOggFormat: function() {
+ var contentType = this.getSourceFileInfo().contentType;
+ return ( contentType.indexOf("video/ogg") != -1
+ || contentType.indexOf("application/ogg") != -1 );
},
- getProgressTitle:function(){
- js_log("fogg:getProgressTitle f:" + this.fogg_enabled + ' rw:' + this.form_rewrite);
- // Return the parent if we don't have fogg turned on:
- if(! this.fogg_enabled || !this.firefogg_form_action )
+
+ /**
+ * Get the default title of the progress window
+ */
+ getProgressTitle: function() {
+ js_log( "fogg:getProgressTitle f:" + ( this.getFirefogg() ? 'on' : 'off' ) +
+ ' mode:' + this.form_type );
+ // Return the parent's title if we don't have Firefogg turned on
+ if ( !this.getFirefogg() || !this.firefogg_form_action ) {
return this.pe_getProgressTitle();
- if( !this.form_rewrite )
- return gM('fogg-transcoding');
- // Else return our upload+transcode msg:
- return gM('mwe-upload-transcode-in-progress');
+ } else if ( this.form_type == 'local' ) {
+ return gM( 'fogg-transcoding' );
+ } else {
+ return gM( 'mwe-upload-transcode-in-progress' );
+ }
},
- doUploadSwitch:function(){
- var _this = this;
- js_log("firefogg: doUploadSwitch:: " + this.fogg_enabled + ' up mode:' + _this.upload_mode);
- // Make sure firefogg is enabled otherwise do parent UploadSwich:
- if( !this.fogg_enabled || !this.firefogg_form_action )
- return _this.pe_doUploadSwitch();
-
- // Check what mode to use firefogg in:
- if( _this.upload_mode == 'post' ){
- _this.doEncode();
- }else if( _this.upload_mode == 'api' ){ //if api mode and chunks supported do chunkUpload
+
+ /**
+ * Do an upload, with the mode given by this.upload_mode
+ */
+ doUpload: function() {
+ var _this = this;
+ js_log( "firefogg: doUpload:: " +
+ ( this.getFirefogg() ? 'on' : 'off' ) +
+ ' up mode:' + _this.upload_mode );
+
+ // If Firefogg is disabled, just invoke the parent method
+ if( !this.getFirefogg() || !this.firefogg_form_action ) {
+ _this.pe_doUpload();
+ return;
+ }
+
+ if ( _this.upload_mode == 'post' ) {
+ // Encode and then do a post upload
+ _this.doEncode(
+ function /* onProgress */ ( progress ) {
+ _this.updateProgress( progress );
+ },
+ function /* onDone */ () {
+ js_log( 'done with encoding do POST upload:' + _this.editForm.action );
+ // ignore warnings & set source type
+ //_this.formData[ 'wpIgnoreWarning' ]='true';
+ _this.formData['wpSourceType'] = 'upload';
+ _this.formData['action'] = 'submit';
+ // wpUploadFile is set by firefogg
+ delete _this.formData['file'];
+
+ _this.fogg.post( _this.editForm.action, 'wpUploadFile',
+ JSON.stringify( _this.formData ) );
+ _this.doUploadStatus();
+ }
+ );
+ } else if ( _this.upload_mode == 'api' ) {
+ // We have the API so we can do a chunk upload
_this.doChunkUpload();
- }else{
+ } else {
js_error( 'Error: unrecongized upload mode: ' + _this.upload_mode );
}
},
+
/**
- * doChunkUpload
- * does both uploading and encoding at the same time and uploads one meg chunks
- */
- doChunkUpload : function(){
- js_log('firefogg::doChunkUpload');
+ * Do both uploading and encoding at the same time. Uploads 1MB chunks as
+ * they become ready.
+ */
+ doChunkUpload : function() {
+ js_log( 'firefogg::doChunkUpload' );
var _this = this;
_this.action_done = false;
-
- // File extension should already be ogg but since its user editable,
- // (should not be needed for passthrough mode)
- var sf = _this.formData['filename'];
- var ext = '';
- if( sf.lastIndexOf('.') != -1){
- ext = sf.substring( sf.lastIndexOf('.') ).toLowerCase();
- }
- if( !_this.encoder_settings['passthrough'] && $j.inArray(ext.substr(1), _this.ogg_extensions) == -1 ){
- var extreg = new RegExp(ext + '$', 'i');
- _this.formData['filename'] = sf.replace(extreg, '.ogg');
- }
- // Add chunk response hook to build the resultURL when uploading chunks
-
- // Check for editToken:
- if(!this.etoken){
- js_log('missing token try ' + _this.formData['token']);
- if( _this.formData['token']){
- _this.etoken = _this.formData['token'];
- _this.doChunkWithFormData();
- }else{
- get_mw_token(
- 'File:'+ _this.formData['filename'],
- _this.api_url,
- function( eToken ){
- if( !eToken || eToken == '+\\' ){
- _this.updateProgressWin( gM('fogg-badtoken'), gM('fogg-badtoken') );
- return false;
- }
- _this.etoken = eToken;
- _this.doChunkWithFormData();
- }
- );
+
+ if ( !_this.getEncoderSettings()['passthrough'] ) {
+ // We are transcoding to Ogg. Fix the destination extension, it
+ // must be ogg/ogv/oga.
+ var fileName = _this.formData['filename'];
+ var ext = '';
+ var dotPos = fileName.lastIndexOf( '.' );
+ if ( dotPos != -1 ) {
+ ext = fileName.substring( dotPos ).toLowerCase();
}
- }else{
- js_log('we already have token: ' + this.etoken);
- _this.doChunkWithFormData();
+ if ( $j.inArray( ext.substr( 1 ), _this.ogg_extensions ) == -1 ) {
+ _this.formData['filename'] = fileName.substr(
+ 0,
+
+
+ var extreg = new RegExp( ext + '$', 'i' );
+ _this.formData['filename'] = fileName.replace( extreg, '.ogg' );
+ }
+ }
+
+ // Get the edit token from formData if it's not set already
+ if ( !_this.editToken && _this.formData['token'] ) {
+ _this.editToken = _this.formData['token'];
}
+
+ if( _this.editToken ) {
+ js_log( 'we already have an edit token: ' + _this.editToken );
+ _this.doChunkUploadWithFormData();
+ return;
+ }
+
+ // No edit token. Fetch it asynchronously and then do the upload.
+ get_mw_token(
+ 'File:'+ _this.formData['filename'],
+ _this.api_url,
+ function( editToken ) {
+ if( !editToken || editToken == '+\\' ) {
+ _this.updateProgressWin( gM( 'fogg-badtoken' ), gM( 'fogg-badtoken' ) );
+ return false;
+ }
+ _this.editToken = editToken;
+ _this.doChunkUploadWithFormData();
+ }
+ );
},
- doChunkWithFormData:function(){
+
+ /**
+ * Internal function called from doChunkUpload() when the edit token is available
+ */
+ doChunkUploadWithFormData: function() {
var _this = this;
- js_log("firefogg::doChunkWithFormData" + _this.etoken);
- // Build the api url:
- var aReq ={
+ js_log( "firefogg::doChunkUploadWithFormData" + _this.editToken );
+ // Build the API URL
+ var aReq = {
'action': 'upload',
'format': 'json',
'filename': _this.formData['filename'],
'enablechunks': 'true'
};
- if( _this.etoken )
- aReq['token'] = this.etoken;
+ if ( _this.editToken )
+ aReq['token'] = this.editToken;
- if( _this.formData['watch'] )
- aReq['watch'] = _this.formData['watch'];
+ if ( _this.formData['watch'] )
+ aReq['watch'] = _this.formData['watch'];
- if( _this.formData['ignorewarnings'] )
+ if ( _this.formData['ignorewarnings'] )
aReq['ignorewarnings'] = _this.formData['ignorewarnings'];
- js_log('do fogg upload/encode call: '+ _this.api_url + ' :: ' + JSON.stringify( aReq ) );
- js_log('foggEncode: '+ JSON.stringify( _this.encoder_settings ) );
- _this.fogg.upload( JSON.stringify( _this.encoder_settings ), _this.api_url , JSON.stringify( aReq ) );
+ var encoderSettings = this.getEncoderSettings();
+ js_log( 'do fogg upload/encode call: ' + _this.api_url + ' :: ' + JSON.stringify( aReq ) );
+ js_log( 'foggEncode: ' + JSON.stringify( encoderSettings ) );
+ _this.fogg.upload( JSON.stringify( encoderSettings ), _this.api_url,
+ JSON.stringify( aReq ) );
- // Update upload status:
+ // Start polling the upload status
_this.doUploadStatus();
},
- // doEncode and monitor progress:
- doEncode : function(){
+
+ /**
+ * Encode the video and monitor progress.
+ *
+ * Calls progressCallback() regularly with a number between 0 and 1 indicating progress.
+ * Calls doneCallback() when the encode is finished.
+ *
+ * Asynchronous, returns immediately.
+ */
+ doEncode : function( progressCallback, doneCallback ) {
var _this = this;
_this.action_done = false;
- _this.dispProgressOverlay();
- js_log('doEncode: with: ' + JSON.stringify( _this.encoder_settings ) );
- _this.fogg.encode( JSON.stringify( _this.encoder_settings ) );
+ _this.displayProgressOverlay();
+ var encoderSettings = this.getEncoderSettings();
+ js_log( 'doEncode: with: ' + JSON.stringify( encoderSettings ) );
+ _this.fogg.encode( JSON.stringify( encoderSettings ) );
- // Show transcode status:
- $j('#up-status-state').html( gM('mwe-upload-transcoded-status') );
+ //show transcode status:
+ $j( '#up-status-state' ).html( gM( 'mwe-upload-transcoded-status' ) );
- // Setup a local function for timed callback:
+ //setup a local function for timed callback:
var encodingStatus = function() {
var status = _this.fogg.status();
- if( _this.show_preview == true && _this.fogg.state == 'encoding'){
- _this.doRenderPreview();
+ if ( _this.show_preview == true && _this.fogg.state == 'encoding' ) {
+ _this.renderPreview();
}
- // Update progress bar
- _this.updateProgress( _this.fogg.progress() );
+ // Update progress
+ progressCallback( _this.fogg.progress() );
- // Loop to get new status if still encoding
- if( _this.fogg.state == 'encoding' ) {
- setTimeout(encodingStatus, 500);
- }else if ( _this.fogg.state == 'encoding done' ) { //encoding done, state can also be 'encoding failed
- _this.encodeDone();
- }else if(_this.fogg.state == 'encoding fail'){
+ //loop to get new status if still encoding
+ if ( _this.fogg.state == 'encoding' ) {
+ setTimeout( encodingStatus, 500 );
+ } else if ( _this.fogg.state == 'encoding done' ) {
+ _this.action_done = true;
+ progressCallback( 1 );
+ doneCallback();
+ } else if ( _this.fogg.state == 'encoding fail' ) {
//@@todo error handling:
- js_error('encoding failed');
+ js_error( 'encoding failed' );
}
}
encodingStatus();
},
- encodeDone:function(){
- var _this = this;
- js_log('::encodeDone::');
- _this.action_done = true;
-
- // Send to the post url:
- if( _this.form_rewrite && _this.upload_mode == 'post' ){
- js_log('done with encoding do POST upload:' + _this.editForm.action);
- // ignore warnings & set source type
- //_this.formData[ 'wpIgnoreWarning' ]='true';
- _this.formData[ 'wpSourceType' ] = 'upload';
- _this.formData[ 'action' ] = 'submit';
- //wpUploadFile is set by firefogg
- delete _this.formData[ 'file' ];
-
- _this.fogg.post( _this.editForm.action, 'wpUploadFile', JSON.stringify( _this.formData ) );
- // Update upload status:
- _this.doUploadStatus();
- }else{
- js_log("done with encoding (no upload) ");
- // Set status to 100% for one second:
- _this.updateProgress( 1 );
- setTimeout(function(){
- _this.updateProgressWin(gM('fogg-encoding-done'),
- gM('fogg-encoding-done') + '<br>' +
- // Show the video at full resolution up-to 720px wide
- '<video controls="true" style="margin:auto" id="fogg_final_vid" src="' +
- _this.fogg.previewUrl + '"></video>'
- );
- //load the video and set a callback:
- var v = $j('#fogg_final_vid').get(0);
- function resizeVid(){
- var v = $j('#fogg_final_vid').get(0);
- if( v.videoWidth > 720 ){
- var vW = 720;
- var vH = 720 * (v.videoHeight/v.videoWidth)
- }else{
- var vW = v.videoWidth;
- var vH = v.videoHeight;
- }
- // Resize the video:
- $j(v).css({
- 'width' : vW,
- 'height': vH
- });
- // If large video resize the dialog box:
- if( vW + 5 > 400){
- //also resize the dialog box
- $j('#upProgressDialog').dialog('option', 'width', vW + 20);
- $j('#upProgressDialog').dialog('option', 'height', vH + 120);
-
- //also position the dialog container
- $j('#upProgressDialog').dialog('option', 'position', 'center');
- }
- }
- v.removeEventListener("loadedmetadata", resizeVid, true);
- v.addEventListener("loadedmetadata", resizeVid, true);
- v.load();
- }, 1000);
- }
- },
- doUploadStatus:function() {
+
+ /**
+ * Poll the upload progress and update the UI regularly until the upload is complete.
+ *
+ * Asynchronous, returns immediately.
+ */
+ doUploadStatus: function() {
var _this = this;
- $j( '#up-status-state' ).html( gM('mwe-uploaded-status') );
+ $j( '#up-status-state' ).html( gM( 'mwe-uploaded-status' ) );
_this.oldResponseText = '';
- // Setup a local function for timed callback:
- var uploadStatus = function(){
- // Get the response text:
- var response_text = _this.fogg.responseText;
- if(!response_text){
- try{
- var pstatus = JSON.parse( _this.fogg.uploadstatus() );
- response_text = pstatus["responseText"];
- }catch(e){
- js_log("could not parse uploadstatus / could not get responseText");
- }
+
+ // Create a local function for timed callback
+ var uploadStatus = function() {
+ var response_text = _this.fogg.responseText;
+ if ( !response_text ) {
+ try {
+ var pstatus = JSON.parse( _this.fogg.uploadstatus() );
+ response_text = pstatus["responseText"];
+ } catch( e ) {
+ js_log( "could not parse uploadstatus / could not get responseText" );
+ }
}
- if( _this.oldResponseText != response_text){
- js_log('new result text:' + response_text + ' state:' + _this.fogg.state);
+ if ( _this.oldResponseText != response_text ) {
+ js_log( 'new result text:' + response_text + ' state:' + _this.fogg.state );
_this.oldResponseText = response_text;
- // Try and parse the response text and check for errors
- try{
+ // Parse the response text and check for errors
+ try {
var apiResult = JSON.parse( response_text );
- }catch(e){
- js_log("could not parse response_text::" + response_text + ' ...for now try with eval...');
- try{
+ } catch( e ) {
+ js_log( "could not parse response_text::" + response_text +
+ ' ...for now try with eval...' );
+ try {
var apiResult = eval( response_text );
- }catch(e){
+ } catch( e ) {
var apiResult = null;
- }
+ }
}
- if(apiResult && _this.apiUpdateErrorCheck( apiResult ) === false){
- // Stop status update we have an error
+ if ( apiResult && !_this.isApiSuccess( apiResult ) ) {
+ // Show the error and stop the upload
+ _this.showApiError( apiResult );
_this.action_done = true;
_this.fogg.cancel();
return false;
}
}
- if( _this.show_preview == true ){
- if( _this.fogg.state == 'encoding' ){
- _this.doRenderPreview();
+ if ( _this.show_preview == true ) {
+ if ( _this.fogg.state == 'encoding' ) {
+ _this.renderPreview();
}
}
-
- // Update progress bar
+
+ // Update the progress bar
_this.updateProgress( _this.fogg.progress() );
- // Loop to get new status if still uploading (could also be encoding if we are in chunk upload mode)
- if( _this.fogg.state == 'encoding' || _this.fogg.state == 'uploading') {
- setTimeout(uploadStatus, 100);
- }// Check upload state
- else if( _this.fogg.state == 'upload done' ||
- _this.fogg.state == 'done' ||
- _this.fogg.state == 'encoding done' ) {
- // If in "post" upload mode read the html response (should be deprecated):
- if( _this.upload_mode == 'api' ){
- if( apiResult && apiResult.resultUrl ){
- var buttons ={};
- buttons[gM('mwe-go-to-resource')] = function(){
- window.location = apiResult.resultUrl;
- }
- var go_to_url_txt = gM('mwe-go-to-resource');
- if( typeof _this.done_upload_cb == 'function' ){
- // If done action return 'true'
- if( _this.done_upload_cb( _this.formData ) ){
- // Update status
- _this.updateProgressWin( gM('mwe-successfulupload'), gM( 'mwe-upload_done', apiResult.resultUrl),buttons);
- }else{
- // If done action returns 'false' //close progress window
- this.action_done = true;
- $j('#upProgressDialog').empty().dialog('close');
- }
- }else{
- // Update status (without done_upload_cb)
- _this.updateProgressWin( gM('mwe-successfulupload'), gM( 'mwe-upload_done', apiResult.resultUrl),buttons);
- }
- }else{
- // Done state with error? ..not really possible given how firefogg works
- js_log(" Upload done in chunks mode, but no resultUrl!");
- }
- }else{
- js_log("Error:: not supported upload mode" + _this.upload_mode);
- }
- }else{
- // Upload error:
- js_log('Error:firefogg upload error: ' + _this.fogg.state );
- }
- }
- uploadStatus();
+ // If we're still uploading or encoding, continue to poll the status
+ if ( _this.fogg.state == 'encoding' || _this.fogg.state == 'uploading' ) {
+ setTimeout( uploadStatus, 100 );
+ return;
+ }
+
+ // Upload done?
+ if ( -1 == $j.inArray( _this.fogg.state, [ 'upload done', 'done', 'encoding done' ] ) ) {
+ js_log( 'Error:firefogg upload error: ' + _this.fogg.state );
+ return;
+ }
+
+ if ( _this.upload_mode == 'api' ) {
+ if ( apiResult && apiResult.resultUrl ) {
+ var buttons = {};
+ buttons[ gM( 'mwe-go-to-resource' ) ] = function() {
+ window.location = apiResult.resultUrl;
+ }
+ var go_to_url_txt = gM( 'mwe-go-to-resource' );
+ var showMessage = true;
+ if ( typeof _this.done_upload_cb == 'function' ) {
+ // Call the callback
+ // It will return false if it doesn't want us to show our own "done" message
+ showMessage = _this.done_upload_cb( _this.formData );
+ }
+ if ( showMessage ) {
+ _this.updateProgressWin( gM( 'mwe-successfulupload' ),
+ gM( 'mwe-upload_done', apiResult.resultUrl ), buttons );
+ } else {
+ this.action_done = true;
+ $j( '#upProgressDialog' ).empty().dialog( 'close' );
+ }
+ } else {
+ // Done state with error? Not really possible given how firefogg works...
+ js_log( " Upload done in chunks mode, but no resultUrl!" );
+ }
+ } else {
+ js_log( "Error:: not supported upload mode" + _this.upload_mode );
+ }
+ }
+ uploadStatus();
},
- cancel_action:function( dlElm ){
- if(!this.fogg_enabled){
+
+ /**
+ * This is the cancel button handler, referenced by getCancelButton() in the parent.
+ */
+ onCancel: function( dlElm ) {
+ if ( !this.have_firefogg ) {
return this.pe_cancel_action();
}
- js_log('firefogg:cancel')
- if( confirm( gM('mwe-cancel-confim') )){
- if(navigator.oscpu && navigator.oscpu.search('Win') >= 0){
- alert( 'sorry we do not yet support cancel on windows' );
- }else{
- this.action_done = true;
- this.fogg.cancel();
- $j(dlElm).empty().dialog('close');
- }
- }
- // Dont' follow the link:
- return false;
+ js_log( 'firefogg:cancel' )
+ if ( confirm( gM( 'mwe-cancel-confim' ) ) ) {
+ // FIXME: sillyness
+ if ( navigator.oscpu && navigator.oscpu.search( 'Win' ) >= 0 ) {
+ alert( 'sorry we do not yet support cancel on windows' );
+ } else {
+ this.action_done = true;
+ this.fogg.cancel();
+ $j( dlElm ).empty().dialog( 'close' );
+ }
+ }
+ // Don't follow the # link:
+ return false;
}
};
'fogg-select_new_file' => 'Select new file',
'fogg-select_url' => 'Select URL',
'fogg-save_local_file' => 'Save Ogg',
- 'fogg-check_for_fogg' => 'Checking for Firefogg...',
+ 'fogg-check_for_firefogg' => 'Checking for Firefogg...',
'fogg-installed' => 'Firefogg is installed',
- 'fogg-for_improved_uplods' => 'For improved uploads:',
+ 'fogg-for_improved_uploads' => 'For improved uploads:',
'fogg-please_install' => '<a href="$1">Install Firefogg</a>. More <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">about Firefogg</a>.',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Your selected file is already Ogg or not a video file',
'fogg-transcoding' => 'Encoding video to Ogg...',
'fogg-encoding-done' => 'Encoding complete',
'fogg-select_new_file' => 'اختر ملفًا جديدًا',
'fogg-select_url' => 'اختر مسارًا',
'fogg-save_local_file' => 'احفظ Ogg',
- 'fogg-check_for_fogg' => 'يلتمس Firefogg...',
+ 'fogg-check_for_firefogg' => 'يلتمس Firefogg...',
'fogg-installed' => 'Firefogg مُثبّت',
'fogg-transcoding' => 'ترميز الفيديو إلى Ogg',
'fogg-encoding-done' => 'انتهى الترميز',
'fogg-select_new_file' => 'Выберыце новы файл',
'fogg-select_url' => 'Выберыце URL-адрас',
'fogg-save_local_file' => 'Захаваць Ogg',
- 'fogg-check_for_fogg' => 'Праверка наяўнасьці Firefogg …',
+ 'fogg-check_for_firefogg' => 'Праверка наяўнасьці Firefogg …',
'fogg-installed' => 'Firefogg усталяваны',
- 'fogg-for_improved_uplods' => 'Для палепшаных загрузак:',
+ 'fogg-for_improved_uploads' => 'Для палепшаных загрузак:',
'fogg-please_install' => '<a href="$1">Усталяваць Firefogg</a>. Болей <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">пра Firefogg</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Выбраны Вамі файл ужо ў фармаце Ogg альбо не зьяўляецца відэа-файлам',
'fogg-transcoding' => 'Перакадыроўка відэа ў фармат Ogg',
'fogg-encoding-done' => 'Перакадыроўка скончаная',
'fogg-select_new_file' => 'Odaberi novu datoteku',
'fogg-select_url' => 'Odaberi URL',
'fogg-save_local_file' => 'Sačuvaj Ogg',
- 'fogg-check_for_fogg' => 'Provjera za Firefogg ...',
+ 'fogg-check_for_firefogg' => 'Provjera za Firefogg ...',
'fogg-installed' => 'Firefogg je instaliran',
'fogg-passthrough_mode' => 'Vaša odabrana datoteka je već Ogg ili nije video datoteka',
'fogg-badtoken' => 'Token nije valjan',
'mwe-loading_txt' => 'Načítá se …',
'mwe-loading-add-media-wiz' => 'Načítá se průvodce pro přidání souboru',
'mwe-cancel' => 'Storno',
- 'fogg-check_for_fogg' => 'Ověřuje se Firefogg…',
+ 'fogg-check_for_firefogg' => 'Ověřuje se Firefogg…',
'fogg-installed' => 'Firefogg je nainstalován',
- 'fogg-for_improved_uplods' => 'Pro vylepšené načítání:',
+ 'fogg-for_improved_uploads' => 'Pro vylepšené načítání:',
'fogg-please_install' => '<a href="$1">Nainstalujte si Firefogg.</a> <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg/cs">Další informace o Firefoggu</a>',
- '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>',
+ '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>',
'mwe-add_media_wizard' => 'Průvodce pro přidání souboru',
'mwe-media_search' => 'Hledání multimédií',
'rsd_box_layout' => 'Ikony',
'fogg-select_new_file' => 'Wähle eine neue Datei',
'fogg-select_url' => 'Wähle eine URL',
'fogg-save_local_file' => 'Ogg speichern',
- 'fogg-check_for_fogg' => 'Suche nach Firefogg …',
+ 'fogg-check_for_firefogg' => 'Suche nach Firefogg …',
'fogg-installed' => 'Firefogg ist installiert',
- 'fogg-for_improved_uplods' => 'Für verbessertes Hochladen:',
+ 'fogg-for_improved_uploads' => 'Für verbessertes Hochladen:',
'fogg-please_install' => '<a href="$1">Installiere Firefogg</a>. Mehr <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">über Firefogg</a>',
- 'fogg-use_latest_fox' => 'Installiere bitte zuerst [http://de.www.mozilla.com/de/ Firefox 3.5] (oder eine spätere Version).
+ 'fogg-use_latest_firefox' => 'Installiere bitte zuerst [http://de.www.mozilla.com/de/ Firefox 3.5] (oder eine spätere Version).
<i>Besuche danach die Seite neu, um die <b>Firefogg</b>-Erweiterung zu installieren.</i>',
'fogg-passthrough_mode' => 'Deine ausgewählte Datei ist bereits Ogg oder keine Videodatei',
'fogg-transcoding' => 'Codiere Video nach Ogg',
'fogg-select_new_file' => 'dosyaya neweyi bıweçin',
'fogg-select_url' => 'URL bıweçin',
'fogg-save_local_file' => 'Ogg qeyd bıker',
- 'fogg-check_for_fogg' => 'Firefogg kontrol beno...',
+ 'fogg-check_for_firefogg' => 'Firefogg kontrol beno...',
'fogg-installed' => 'Firefogg bar bı',
- 'fogg-for_improved_uplods' => 'qey barkerdışê dewlemend biyayeyani:',
+ 'fogg-for_improved_uploads' => 'qey barkerdışê dewlemend biyayeyani:',
'fogg-please_install' => '<a href="$1">Firefogg bar ker</a>. <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">derheqê firefoggi de</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'dosyaya ke şıma weçina ca ra yew dosyaya Oggi ya zi videoyi niyo',
'fogg-transcoding' => 'Video Ogg ra kod beno',
'fogg-encoding-done' => 'kodkerdış temam bı',
'fogg-select_new_file' => 'Nowu dataju wubraś',
'fogg-select_url' => 'URL wubraś',
'fogg-save_local_file' => 'Ogg składowaś',
- 'fogg-check_for_fogg' => 'Za Firefogg pśeglědaś ...',
+ 'fogg-check_for_firefogg' => 'Za Firefogg pśeglědaś ...',
'fogg-installed' => 'Firefogg jo instalěrowany.',
- 'fogg-for_improved_uplods' => 'Za pólěpšone nagraśa:',
+ 'fogg-for_improved_uploads' => 'Za pólěpšone nagraśa:',
'fogg-please_install' => '<a href="$1">Firefogg instalěrowaś</a>. Wjace <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">wó Firefogg</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Twója wubrana dataja jo južo dataja Ogg abo njejo wideojowa dataja',
'fogg-transcoding' => 'Wideo do Ogg koděrowaś',
'fogg-encoding-done' => 'Koděrowanje skóńcone',
'fogg-select_url' => 'Επιλογή URL',
'fogg-save_local_file' => 'Αποθήκευση Οgg',
'fogg-installed' => 'Ο Firefogg είναι εγκατεστημένος',
- 'fogg-for_improved_uplods' => 'Για βελτιωμένες φορτώσεις:',
+ 'fogg-for_improved_uploads' => 'Για βελτιωμένες φορτώσεις:',
'fogg-transcoding' => 'Κωδικοποίηση βίντεο σε Ogg',
'fogg-encoding-done' => 'Κωδικοποίηση πλήρης',
'fogg-badtoken' => 'Το δείγμα δεν είναι έγκυρο',
'fogg-select_new_file' => 'Elekti novan dosieron',
'fogg-select_url' => 'Elekti URL-on',
'fogg-installed' => 'Instalis Firefogg',
- '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>',
+ '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>',
'fogg-hidepreview' => 'Kaŝi antaŭvidon',
'fogg-videoQuality-title' => 'Videa kvalito',
'fogg-starttime-title' => 'Komenca sekundo',
'fogg-select_new_file' => 'Seleccionar nuevo archivo',
'fogg-select_url' => 'Seleccionar URL',
'fogg-save_local_file' => 'Grabar Ogg',
- 'fogg-check_for_fogg' => 'Verificando Firefogg ...',
+ 'fogg-check_for_firefogg' => 'Verificando Firefogg ...',
'fogg-installed' => 'Firefogg está instalado',
- 'fogg-for_improved_uplods' => 'Para cargas mejoradas:',
+ 'fogg-for_improved_uploads' => 'Para cargas mejoradas:',
'fogg-please_install' => '<a href="$1">Instalar Firefogg</a>. Más <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">acerca de Firefogg</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Tu archivo seleccionado ya es Ogg o no es un archivo de video',
'fogg-transcoding' => 'Codificando video a Ogg',
'fogg-encoding-done' => 'Codificación completa',
'fogg-select_url' => 'Valitse URL',
'fogg-save_local_file' => 'Tallenna Ogg',
'fogg-installed' => 'Firefogg on asennettu',
- 'fogg-for_improved_uplods' => 'Parannettua tallentamista varten:',
+ 'fogg-for_improved_uploads' => 'Parannettua tallentamista varten:',
'fogg-please_install' => '<a href="$1">Asenna Firefogg</a> – <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">Tietoja Firefoggista</a>.',
- '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>',
+ '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>',
'fogg-preview' => 'Videon esikatselu',
'fogg-hidepreview' => 'Piilota esikatselu',
'fogg-audioQuality-title' => 'Äänenlaatu',
'fogg-select_new_file' => 'Sélectionnez un nouveau fichier',
'fogg-select_url' => 'Sélectionnez une URL',
'fogg-save_local_file' => 'Sauvegarder au format Ogg',
- 'fogg-check_for_fogg' => 'Vérification de Firefogg ...',
+ 'fogg-check_for_firefogg' => 'Vérification de Firefogg ...',
'fogg-installed' => 'Firefogg est installé',
- 'fogg-for_improved_uplods' => 'Pour des téléversements améliorés :',
+ 'fogg-for_improved_uploads' => 'Pour des téléversements améliorés :',
'fogg-please_install' => '<a href="$1">Installer Firefogg</a>. Plus d\'infos <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">sur Firefogg</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => "Le fichier que vous avez sélectionné est déjà au format Ogg ou n'est pas un fichier vidéo",
'fogg-transcoding' => "Encodage d'une vidéo au format Ogg",
'fogg-encoding-done' => 'Encodage terminé',
'fogg-select_new_file' => 'Seleccione un ficheiro novo',
'fogg-select_url' => 'Seleccione un enderezo URL',
'fogg-save_local_file' => 'Gardar en formato Ogg',
- 'fogg-check_for_fogg' => 'Examinando en busca do Firefogg...',
+ 'fogg-check_for_firefogg' => 'Examinando en busca do Firefogg...',
'fogg-installed' => 'O Firefogg está instalado',
- 'fogg-for_improved_uplods' => 'Para cargas melloradas:',
+ 'fogg-for_improved_uploads' => 'Para cargas melloradas:',
'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>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'O ficheiro que seleccionou xa está en formato Ogg ou non é un ficheiro de vídeo',
'fogg-transcoding' => 'Codificando o vídeo en formato Ogg',
'fogg-encoding-done' => 'Codificación completa',
'fogg-select_new_file' => 'Neji Datei uuswehle',
'fogg-select_url' => 'URL uuswehle',
'fogg-save_local_file' => 'Ogg spychere',
- 'fogg-check_for_fogg' => 'Am Priefe vu Firefogg ...',
+ 'fogg-check_for_firefogg' => 'Am Priefe vu Firefogg ...',
'fogg-installed' => 'Firefogg isch inschtalliert',
- 'fogg-for_improved_uplods' => 'Fir e verbesseret Uffelade:',
+ 'fogg-for_improved_uploads' => 'Fir e verbesseret Uffelade:',
'fogg-please_install' => '<a href="$1">Firefogg inschtalliere</a>. Meh <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">Informatione iber Firefogg</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'D Datei, wu Du uusgwehlt hesch, isch schon im Ogg-Format oder s het kei Video din',
'fogg-transcoding' => 'Am Umwandle vum Video in s Ogg-Format',
'fogg-encoding-done' => 'Umwandlig fertig',
'fogg-select_new_file' => 'בחירת קובץ חדש',
'fogg-select_url' => 'בחירת כתובת',
'fogg-save_local_file' => 'שמירת ה־Ogg',
- 'fogg-check_for_fogg' => 'מתבצעת בדיקה האם מותקן Firefogg ...',
+ 'fogg-check_for_firefogg' => 'מתבצעת בדיקה האם מותקן Firefogg ...',
'fogg-installed' => 'Firefogg מותקן',
- 'fogg-for_improved_uplods' => 'להעלאות משופרות:',
+ 'fogg-for_improved_uploads' => 'להעלאות משופרות:',
'fogg-please_install' => '<a href="$1">להתקנת Firefogg</a>. עוד <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">אודות Firefogg</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'הקובץ שנבחר הוא כבר קובץ Ogg או שאינו קובץ וידאו',
'fogg-transcoding' => 'קידוד הווידאו ל־Ogg',
'fogg-encoding-done' => 'הקידוד הושלם',
'fogg-select_new_file' => 'Nowu dataju wubrać',
'fogg-select_url' => 'URL wubrać',
'fogg-save_local_file' => 'Ogg składować',
- 'fogg-check_for_fogg' => 'Pruwowanje za Firefogg ...',
+ 'fogg-check_for_firefogg' => 'Pruwowanje za Firefogg ...',
'fogg-installed' => 'Firefogg so instaluje',
- 'fogg-for_improved_uplods' => 'Za polěpšene nahraća:',
+ 'fogg-for_improved_uploads' => 'Za polěpšene nahraća:',
'fogg-please_install' => '<a href="$1">Firefogg instalować</a>. Wjace <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">wo Firefoggu</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Twoja wubrana dataja je hižo Ogg abo njeje widejowa dataja',
'fogg-transcoding' => 'Kodowanje wideja do Ogg',
'fogg-encoding-done' => 'Kodowanje hotowe',
'fogg-select_new_file' => 'Új fájl kiválasztása',
'fogg-select_url' => 'URL kiválasztása',
'fogg-save_local_file' => 'Ogg mentése',
- 'fogg-check_for_fogg' => 'Firefogg keresése…',
+ 'fogg-check_for_firefogg' => 'Firefogg keresése…',
'fogg-installed' => 'Firefogg telepítve',
- 'fogg-for_improved_uplods' => 'Fejlettebb feltöltésekhez:',
+ 'fogg-for_improved_uploads' => 'Fejlettebb feltöltésekhez:',
'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.',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Az általad kiválasztott fájl már Ogg formátumban van, vagy nem videófájl',
'fogg-transcoding' => 'Videó kódolása Ogg formátumba',
'fogg-encoding-done' => 'A kódolás kész',
'fogg-select_new_file' => 'Seliger nove file',
'fogg-select_url' => 'Seliger URL',
'fogg-save_local_file' => 'Immagazinar in Ogg',
- 'fogg-check_for_fogg' => 'Verifica presentia de Firefogg ...',
+ 'fogg-check_for_firefogg' => 'Verifica presentia de Firefogg ...',
'fogg-installed' => 'Firefogg es installate',
- 'fogg-for_improved_uplods' => 'Pro cargamentos meliorate:',
+ 'fogg-for_improved_uploads' => 'Pro cargamentos meliorate:',
'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>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Le file que tu seligeva ja es in Ogg, o non es un file video',
'fogg-transcoding' => 'Codification del video in Ogg',
'fogg-encoding-done' => 'Codification complete',
'fogg-select_new_file' => 'Pilih berkas baru',
'fogg-select_url' => 'Pilih URL',
'fogg-save_local_file' => 'Simpan Ogg',
- 'fogg-check_for_fogg' => 'Mengecek Firefogg...',
+ 'fogg-check_for_firefogg' => 'Mengecek Firefogg...',
'fogg-installed' => 'Firefogg telah terinstal',
- 'fogg-for_improved_uplods' => 'Untuk pengunggahan canggih:',
+ 'fogg-for_improved_uploads' => 'Untuk pengunggahan canggih:',
'fogg-please_install' => '<a href="$1">Instal Firefogg.</a> Lebih lanjut <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">tentang Firefogg.</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Berkas yang dipilih sudah berformat Ogg atau bukan suatu berkas video',
'fogg-transcoding' => 'Mengkodekan video ke Ogg...',
'fogg-encoding-done' => 'Pengkodean selesai',
'fogg-select_new_file' => '別のファイルを選択',
'fogg-select_url' => 'URLを選択',
'fogg-save_local_file' => 'Ogg を保存',
- 'fogg-check_for_fogg' => 'Firefogg を確認しています ...',
+ 'fogg-check_for_firefogg' => 'Firefogg を確認しています ...',
'fogg-installed' => 'Firefogg はインストールされています',
- 'fogg-for_improved_uplods' => 'アップロードをより便利にするには:',
+ 'fogg-for_improved_uploads' => 'アップロードをより便利にするには:',
'fogg-please_install' => '<a href="$1">Firefogg をインストール</a>。<a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">Firefogg について</a>。',
- '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>',
+ '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>',
'fogg-passthrough_mode' => '選択したファイルはすでに Ogg 形式であるか、動画ファイルではありません',
'fogg-transcoding' => '動画を Ogg に形式変換',
'fogg-encoding-done' => '形式変換終了',
'fogg-select_new_file' => 'Neu Dattei ußwähle',
'fogg-select_url' => '<i lang="en">URL</i> ußwähle',
'fogg-save_local_file' => 'Ogg afshpeijshere',
- 'fogg-check_for_fogg' => 'Op <i lang="en">Firefogg</i> aam Prööve …',
+ 'fogg-check_for_firefogg' => 'Op <i lang="en">Firefogg</i> aam Prööve …',
'fogg-installed' => '<i lang="en">Firefogg</i> es ennjeresht',
- 'fogg-for_improved_uplods' => 'För e verbäßert Huhlaade: ',
+ 'fogg-for_improved_uploads' => 'För e verbäßert Huhlaade: ',
'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>.',
- '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.',
+ '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.',
'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.',
'fogg-transcoding' => 'Dä Viddejo weedt jraadt noh em <i lang="en">Ogg</i>-Fommaat ömjewandelt',
'fogg-encoding-done' => 'Ömwandlung es fäädesch',
'fogg-select_new_file' => 'Neie Fichier eraussichen',
'fogg-select_url' => 'URL eraussichen',
'fogg-save_local_file' => 'Ogg späicheren',
- 'fogg-check_for_fogg' => 'Sichen no Firefogg ...',
+ 'fogg-check_for_firefogg' => 'Sichen no Firefogg ...',
'fogg-installed' => 'Firefogg ass installéiert',
- 'fogg-for_improved_uplods' => 'Fir verbessert Eroplueden:',
+ 'fogg-for_improved_uploads' => 'Fir verbessert Eroplueden:',
'fogg-please_install' => '<a href="$1">Installéiert Firefogg</a>. Méi <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">iwwer Firefogg</a>',
- '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>",
+ '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>",
'fogg-preview' => 'Video kucken ouni ze späicheren',
'mwe-imported_from' => "$1 huet vun [$2 $3] importéiert. Kuckt d'[$4 Originalquellsäit] fir méi Informatiounen.",
'mwe-stream_title' => '$1 $2 bis $3',
'fogg-select_new_file' => 'പുതിയ പ്രമാണം തിരഞ്ഞെടുക്കുക',
'fogg-select_url' => 'യു.ആർ.എൽ. തിരഞ്ഞെടുക്കുക',
'fogg-save_local_file' => 'ഓഗ് ആയി സേവ് ചെയ്യുക',
- 'fogg-check_for_fogg' => 'ഫയർഫോഗ് തിരയുന്നു...',
+ 'fogg-check_for_firefogg' => 'ഫയർഫോഗ് തിരയുന്നു...',
'fogg-installed' => 'ഫയർഫോഗ് ഇൻസ്റ്റോൾ ചെയ്തിട്ടുണ്ട്',
- 'fogg-for_improved_uplods' => 'മെച്ചപ്പെടുത്തിയ അപ്ലോഡുകൾക്കു വേണ്ടി:',
+ 'fogg-for_improved_uploads' => 'മെച്ചപ്പെടുത്തിയ അപ്ലോഡുകൾക്കു വേണ്ടി:',
'fogg-please_install' => '<a href="$1">ഫയർഫോഗ് ഇൻസ്റ്റോൾ ചെയ്യുക</a>. <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">ഫയർഫോഗിനെ കുറിച്ചു കൂടുതൽ</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'താങ്കൾ തിരഞ്ഞെടുത്ത പ്രമാണം ഓഗ് (Ogg) തന്നെയാണ് അല്ലങ്കിൽ വീഡിയോ പ്രമാണം അല്ല',
'fogg-transcoding' => 'ചലച്ചിത്രം ഓഗ് ആയി എൻകോഡ് ചെയ്യുന്നു...',
'fogg-encoding-done' => 'എൻകോഡിങ് പൂർണ്ണം',
'fogg-select_new_file' => 'Kies nuwe lêer',
'fogg-select_url' => 'URL selecteren',
'fogg-save_local_file' => 'Ogg opslaan',
- 'fogg-check_for_fogg' => 'Firefogg aan het controleren ...',
+ 'fogg-check_for_firefogg' => 'Firefogg aan het controleren ...',
'fogg-installed' => 'Firefogg is geïnstalleerd',
- 'fogg-for_improved_uplods' => 'Voor verbeterde uploads:',
+ 'fogg-for_improved_uploads' => 'Voor verbeterde uploads:',
'fogg-please_install' => '<a href="$1">Installeer Firefogg</a>. Meer <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">over Firefogg</a>',
- '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).
+ '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).
<i>Kom daarna terug naar deze pagina om de uitbreiding <b>Firefogg</b> te installeren.</i>',
'fogg-passthrough_mode' => 'Het geselecteerde bestand is al een Ogg-bestand of geen videobestand',
'fogg-transcoding' => 'Bezig met het converteren van video naar Ogg',
'fogg-select_new_file' => 'Seleccionatz un fichièr novèl',
'fogg-select_url' => 'Seleccionatz una URL',
'fogg-save_local_file' => 'Salvar al format Ogg',
- 'fogg-check_for_fogg' => 'Verificacion de Firefogg ...',
+ 'fogg-check_for_firefogg' => 'Verificacion de Firefogg ...',
'fogg-installed' => 'Firefogg es installat',
- 'fogg-for_improved_uplods' => 'Per de telecargaments melhorats :',
+ 'fogg-for_improved_uploads' => 'Per de telecargaments melhorats :',
'fogg-please_install' => '<a href="$1">Installer Firefogg</a>. Mai d\'entresenhas <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">sus Firefogg</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => "Lo fichièr qu'avètz seleccionat es ja al format Ogg o es pas un fichièr vidèo",
'fogg-transcoding' => "Encodatge d'una vidèo al format Ogg",
'fogg-encoding-done' => 'Encodatge acabat',
'fogg-select_new_file' => 'Wybierz nowy plik',
'fogg-select_url' => 'Wybierz adres URL',
'fogg-save_local_file' => 'Zapisz w formacie Ogg',
- 'fogg-check_for_fogg' => 'Sprawdzanie czy używasz Firefogg ...',
+ 'fogg-check_for_firefogg' => 'Sprawdzanie czy używasz Firefogg ...',
'fogg-installed' => 'Firefogg jest zainstalowany',
- 'fogg-for_improved_uplods' => 'Dla poprawy przesyłania:',
+ 'fogg-for_improved_uploads' => 'Dla poprawy przesyłania:',
'fogg-please_install' => '<a href="$1">Zainstaluj Firefogg</a>. Więcej <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">o Firefogg</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Wybrany przez Ciebie plik jest już w formacie Ogg lub nie jest plikiem wideo',
'fogg-transcoding' => 'Kodowanie wideo do formatu Ogg',
'fogg-encoding-done' => 'Kodowanie zakończone',
'fogg-save_local_file' => 'Gravar Ogg',
'fogg-check_for_fogg' => 'A procurar o Firefogg...',
'fogg-installed' => 'Firefogg está instalado',
- 'fogg-for_improved_uplods' => 'Para optimizar os carregamentos:',
+ 'fogg-for_improved_uploads' => 'Para optimizar os carregamentos:',
'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>.',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'O ficheiro seleccionado já é de formato Ogg ou não é um ficheiro de vídeo',
'fogg-transcoding' => 'Codificar vídeo para Ogg',
'fogg-encoding-done' => 'Codificação finalizada',
'fogg-select_new_file' => 'Выберите новый файл',
'fogg-select_url' => 'Выберите URL',
'fogg-save_local_file' => 'Сохранить Ogg',
- 'fogg-check_for_fogg' => 'Проверка Firefogg …',
+ 'fogg-check_for_firefogg' => 'Проверка Firefogg …',
'fogg-installed' => 'Firefogg установлен',
- 'fogg-for_improved_uplods' => 'Для улучшенных загрузок:',
+ 'fogg-for_improved_uploads' => 'Для улучшенных загрузок:',
'fogg-please_install' => '<a href="$1">Установить Firefogg</a>. Подробнее <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">о Firefogg</a>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Выбранный файл уже Ogg или не является видео-файлом',
'fogg-transcoding' => 'Перекодирование видео в Ogg',
'fogg-encoding-done' => 'Перекодирование завершено',
'fogg-select_new_file' => 'Vybrať nový súbor',
'fogg-select_url' => 'Vybrať URL',
'fogg-save_local_file' => 'Uložiť Ogg',
- 'fogg-check_for_fogg' => 'Kontroluje sa Firefogg ...',
+ 'fogg-check_for_firefogg' => 'Kontroluje sa Firefogg ...',
'fogg-installed' => 'Firefogg je nainštalovaný',
- 'fogg-for_improved_uplods' => 'Na vylepšenie nahrávania:',
+ 'fogg-for_improved_uploads' => 'Na vylepšenie nahrávania:',
'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>',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Váš vybraný súbor je už Ogg alebo to nie je videosúbor',
'fogg-transcoding' => 'Prebieha prekódovanie videosúboru do Ogg',
'fogg-encoding-done' => 'Prekódovanie dokončené',
'fogg-select_new_file' => 'Välj ny fil',
'fogg-select_url' => 'Välj URL',
'fogg-save_local_file' => 'Spara Ogg',
- 'fogg-check_for_fogg' => 'Kollar om Firefogg är installerat...',
+ 'fogg-check_for_firefogg' => 'Kollar om Firefogg är installerat...',
'fogg-installed' => 'Firefogg är installerat',
- 'fogg-for_improved_uplods' => 'För förbättrade uppladdningar:',
+ 'fogg-for_improved_uploads' => 'För förbättrade uppladdningar:',
'fogg-please_install' => '<a href="$1">Installera Firefogg</a>. Mer <a href="http://commons.wikimedia.org/wiki/Commons:Firefogg">om Firefogg</a> (på engelska).',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Den valda filen är redan i formatet Ogg eller också är den inte en videofil över huvud taget',
'fogg-transcoding' => 'Kodar om videon till Ogg...',
'fogg-encoding-done' => 'Kodningen har avslutats',
'fogg-select_new_file' => 'Yeni dosyayı seç',
'fogg-select_url' => 'URLyi seç',
'fogg-save_local_file' => "Ogg'u kaydet",
- 'fogg-check_for_fogg' => 'Firefogg kontrol ediliyor ...',
+ 'fogg-check_for_firefogg' => 'Firefogg kontrol ediliyor ...',
'fogg-installed' => 'Firefogg yüklendi',
- 'fogg-for_improved_uplods' => 'Gelişmiş yüklemeler için:',
+ 'fogg-for_improved_uploads' => 'Gelişmiş yüklemeler için:',
'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',
- '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>',
+ '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>',
'fogg-passthrough_mode' => 'Seçtiğiniz dosya zaten Ogg ya da bir video dosyası değil',
'fogg-transcoding' => "Video Ogg'a kodlanıyor",
'fogg-encoding-done' => 'Kodlama tamamlandı',
'fogg-select_new_file' => 'Selessiona file novo',
'fogg-select_url' => 'Selessiona indirisso (URL)',
'fogg-save_local_file' => 'Salva come Ogg',
- 'fogg-check_for_fogg' => "So' drio sercar el Firefogg...",
+ 'fogg-check_for_firefogg' => "So' drio sercar el Firefogg...",
'fogg-installed' => 'El Firefogg el xe instalà',
'fogg-transcoding' => "So' drio codificar el video in formato Ogg",
'fogg-encoding-done' => 'Codifica conpletà',
'fogg-select_new_file' => 'Chọn tập tin mới',
'fogg-select_url' => 'Chọn URL',
'fogg-save_local_file' => 'Lưu thành Ogg',
- 'fogg-check_for_fogg' => 'Đang tìm cho Firefogg …',
+ 'fogg-check_for_firefogg' => 'Đang tìm cho Firefogg …',
'fogg-installed' => 'Firefogg đã được cài đặt',
- 'fogg-for_improved_uplods' => 'Để tải lên tiện hơn:',
+ 'fogg-for_improved_uploads' => 'Để tải lên tiện hơn:',
'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>',
- '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>',
+ '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>',
'fogg-preview' => 'Xem trước video',
'fogg-hidepreview' => 'Ẩn phần xem trước',
'fogg-help-sticky' => 'Trợ giúp (nhấn chuột để giữ)',
* It controls the invocation of the mvUploader class based on local config.
*/
-var mwUploadFormTarget = '#mw-upload-form';
+var mwUploadFormSelector = '#mw-upload-form';
// Set up the upload form bindings once all DOM manipulation is done
var mwUploadHelper = {
init: function() {
// An API URL (we won't submit directly to action of the form)
'api_url': wgServer + wgScriptPath + '/api.php',
'form_rewrite': true,
- 'target_edit_from': mwUploadFormTarget,
+ 'edit_form_selector': mwUploadFormSelector,
'new_source_cb': function( orgFilename, oggName ) {
$j( '#wpDestFile' ).val( oggName );
$j( '#wpDestFile' ).doDestCheck( {
if ( $j( '#wpUploadFileURL' ).length != 0 ) {
$j( '#wpUploadFileURL' ).baseUploadInterface( {
'api_url': wgServer + wgScriptPath + '/api.php',
- 'target_edit_from': mwUploadFormTarget
+ 'edit_form_selector': mwUploadFormSelector
} );
}
}