removed output-disable in dbms-output fetching procedure
[mediawiki.git] / js2 / mwEmbed / skins / ctrlBuilder.js
blob85c289150c6542695d0861da3b539d7be5dd6431
1 // set the dismissNativeWarn flag:
2 _global['dismissNativeWarn'] = false;
4 /**
5 * Msg text is inherited from embedVideo (we should move it here (although can't load ctrlBuilder without parent EmbedVideo obj)
8 /**
9 * base ctrlBuilder object
10 *       @param the embedVideo element we are targeting
12 var ctrlBuilder = function( embedObj ) {
13         return this.init( embedObj );
17  * controlsBuilder prototype:
18  */
19 ctrlBuilder.prototype = {
20         init:function( embedObj, opt ) {
21                 var _this = this;
22                 this.embedObj = embedObj;
24                 // check for skin overrides for ctrlBuilder
25                 if ( _global[ embedObj.skin_name + 'Config'] ) {
26                         // clone as to not override prototype:  
27                         var _this = $j.extend( true, { }, this, _global[ embedObj.skin_name + 'Config'] );
28                         return _this;
29                 }
30                 return this;
31         },
32         pClass : 'mv-player',
33         long_time_disp: true,
34         body_options : true,
35         // default volume layout is "vertical"
36         volume_layout : 'vertical',
37         height:29,
38         supports: {
39                   'options':true,
40                   'borders':true
41         },
42         getControls:function() {
43                 // set up local pointer to the embedObj
44                 var embedObj = this.embedObj;
45                 // set up loadl ctrlBuilder ref
46                 var _this = this;
48                 js_log( 'f:controlsBuilder:: opt:' + this.options );
49                 this.id = ( embedObj.pc ) ? embedObj.pc.pp.id:embedObj.id;
50                 this.available_width = embedObj.playerPixelWidth();
51                 
52                 // Make pointer to the embedObj
53                 this.embedObj = embedObj;
54                 var _this = this;
55                 for ( var i in embedObj.supports ) {
56                         _this.supports[i] = embedObj.supports[i];
57                 };
59                 // Special case vars:
60                 if ( ( embedObj.roe ||
61                           embedObj.wikiTitleKey ||
62                                 ( embedObj.media_element.timedTextSources &&
63                                 embedObj.media_element.timedTextSources() )
64                         )  && embedObj.show_meta_link  )
65                         this.supports['closed_captions'] = true;
68                 // Append options to body (if not already there)
69                 if ( _this.body_options && $j( '#mv_vid_options_' + this.id ).length == 0 )
70                         $j( 'body' ).append( this.components['mv_embedded_options'].o( this ) );
72                 var o = '';
73                 for ( var i in this.components ) {
74                         if ( this.supports[i] ) {
75                                 if ( this.available_width > this.components[i].w ) {
76                                         // Special case with playhead don't add unless we have 60px
77                                         if ( i == 'play_head' && this.available_width < 60 )
78                                                 continue;
79                                         o += this.components[i].o( this  );
80                                         this.available_width -= this.components[i].w;
81                                 } else {
82                                         js_log( 'not enough space for control component:' + i );
83                                 }
84                         }
85                 }
86                 return o;
87         },
88          /*
89          * addControlHooks
90          * to be run once controls are attached to the dom
91          */
92         addControlHooks:function( $tp ) {
93                 // set up local pointer to the embedObj
94                 var embedObj = this.embedObj;
95                 var _this = this;
96                 // var embed_id = (embedObj.pc!=null)?embedObj.pc.pp.id:embedObj.id;            
98                 if ( !$tp )
99                         $tp = $j( '#' + embedObj.id );
100                 
101                 
102                 // add play hook:
103                 $tp.find( '.play-btn,.play-btn-large' ).unbind().btnBind().click( function() {
104                         embedObj.play();
105                 } );
107                 // add recommend firefox if we have non-native playback:
108                 if ( embedObj.doNativeWarningCheck() ) {
109                         $j( '#dc_' + embedObj.id ).hover(
110                                 function() {
111                                         if ( $j( '#gnp_' + embedObj.id ).length == 0 ) {
112                                                 var toppos = ( embedObj.instanceOf == 'mvPlayList' ) ? 25:10;
113                                                 $j( this ).append( '<div id="gnp_' + embedObj.id + '" class="ui-state-highlight ui-corner-all" ' +
114                                                         'style="position:absolute;display:none;background:#FFF;top:' + toppos + 'px;left:10px;right:10px;">' +
115                                                         gM( 'mwe-for_best_experience' ) +
116                                                 '<br><input id="ffwarn_' + embedObj.id + '" type=\"checkbox\">' +
117                                                         gM( 'mwe-do_not_warn_again' ) +
118                                                 '</div>' );
119                                                 $j( '#ffwarn_' + embedObj.id ).click( function() {
120                                                         if ( $j( this ).is( ':checked' ) ) {
121                                                                 // set up a cookie for 7 days:
122                                                                 $j.cookie( 'dismissNativeWarn', true, { expires: 7 } );
123                                                                 // set the current instance
124                                                                 _global['dismissNativeWarn'] = true;
125                                                                 $j( '#gnp_' + embedObj.id ).fadeOut( 'slow' );
126                                                         } else {
127                                                                 _global['adismissNativeWarn'] = false;
128                                                                 $j.cookie( 'dismissNativeWarn', false );
129                                                         }
131                                                 } );
132                                         }
133                                         if ( ( $j.cookie( 'dismissNativeWarn' ) !== true ) &&
134                                                 _global['dismissNativeWarn'] === false  ) {
135                                                 $j( '#gnp_' + embedObj.id ).fadeIn( 'slow' );
136                                         }
137                                 },
138                                 function() {
139                                         $j( '#gnp_' + embedObj.id ).fadeOut( 'slow' );
140                                 }
141                         );
142                 }
144                 if ( $j.browser.msie  &&  $j.browser.version <= 6 ) {
145                         $j( embedObj.id + ' .play-btn-large' ).pngFix();
146                 }
149                 // captions binding:
150                 $tp.find( '.timed-text' ).unbind().btnBind().click( function() {
151                         embedObj.showTextInterface();
152                 } );
154                 // options binding:
155                 $tp.find( '.options-btn' ).unbind().btnBind().click( function() {
156                         embedObj.doOptionsHTML();
157                 } );
159                 // fullscreen binding:
160                 $tp.find( '.fullscreen-btn' ).unbind().btnBind().click( function() {
161                         embedObj.fullscreen();
162                 } );
164                 js_log( " should add slider binding: " + $tp.find( '.play_head' ).length );
165                 $tp.find( '.play_head' ).slider( {
166                         range: "min",
167                         value: 0,
168                         min: 0,
169                         max: 1000,
170                         start: function( event, ui ) {
171                                 var id = ( embedObj.pc != null ) ? embedObj.pc.pp.id:embedObj.id;
172                                 embedObj.userSlide = true;
173                                 $j( id + ' .play-btn-large' ).fadeOut( 'fast' );
174                                 // If playlist always start at 0
175                                 embedObj.start_time_sec = ( embedObj.instanceOf == 'mvPlayList' ) ? 0:
176                                                                 npt2seconds( embedObj.getTimeReq().split( '/' )[0] );
177                         },
178                         slide: function( event, ui ) {
179                                 var perc = ui.value / 1000;
180                                 embedObj.jump_time = seconds2npt( parseFloat( parseFloat( embedObj.getDuration() ) * perc ) + embedObj.start_time_sec );
181                                 // js_log('perc:' + perc + ' * ' + embedObj.getDuration() + ' jt:'+  this.jump_time);
182                                 if ( _this.long_time_disp ) {
183                                         embedObj.setStatus( gM( 'mwe-seek_to', embedObj.jump_time ) );
184                                 } else {
185                                         embedObj.setStatus( embedObj.jump_time );
186                                 }
187                                 // Update the thumbnail / frame
188                                 if ( embedObj.isPlaying == false ) {
189                                         embedObj.updateThumbPerc( perc );
190                                 }
191                         },
192                         change:function( event, ui ) {
193                                 // only run the onChange event if done by a user slide 
194                                 // (otherwise it runs times it should not)
195                                 if ( embedObj.userSlide ) {
196                                         embedObj.userSlide = false;
197                                         embedObj.seeking = true;
198                                         // stop the monitor timer (if we can)
199                                         if ( embedObj.stopMonitor )
200                                                 embedObj.stopMonitor();
202                                         var perc = ui.value / 1000;
203                                         // set seek time (in case we have to do a url seek)
204                                         embedObj.seek_time_sec = npt2seconds( embedObj.jump_time, true );
205                                         js_log( 'do jump to: ' + embedObj.jump_time + ' perc:' + perc + ' sts:' + embedObj.seek_time_sec );
206                                         embedObj.setStatus( gM( 'mwe-seeking' ) );
207                                         embedObj.doSeek( perc );
208                                 }
209                         }
210                 } );
211                 // up the z-index of the default status indicator:
212                 $tp.find( '.play_head .ui-slider-handle' ).css( 'z-index', 4 );
213                 $tp.find( '.play_head .ui-slider-range' ).addClass( 'ui-corner-all' ).css( 'z-index', 2 );
214                 // extended class list for jQuery ui themeing (we can probably refactor this with custom buffering highlighter)
215                 $tp.find( '.play_head' ).append( this.getMvBufferHtml() );
216                         
217                 $opt = $j( '#mv_vid_options_' + embedObj.id );
218                 // videoOptions ... @@todo should be merged with something more like kskin.js:
219                 $opt.find( '.vo_selection' ).click( function() {
220                         embedObj.displayHTML();
221                         embedObj.showPlayerselect( $tp.find( '.videoOptionsComplete' ) );
222                         $opt.hide();
223                         return false;
224                 } );
225                 $opt.find( '.vo_download' ).click( function() {
226                         embedObj.displayHTML();
227                         embedObj.showDownload( $tp.find( '.videoOptionsComplete' ) );
228                         $opt.hide();
229                         return false;
230                 } )
231                 $opt.find( '.vo_showcode' ).click( function() {
232                         embedObj.displayHTML();
233                         embedObj.showShare( $tp.find( '.videoOptionsComplete' ) );
234                         $opt.hide();
235                         return false;
236                 } );
237                 this.doVolumeBinding();
238                 
239                 // check if we have any custom skin hooks to run (only one per skin) 
240                 if ( this.addSkinControlHooks && typeof( this.addSkinControlHooks ) == 'function' )
241                         this.addSkinControlHooks();
242         },
243         doVolumeBinding:function() {
244                 var embedObj = this.embedObj;
245                 var _this = this;
246                 var $tp = $j( '#' + embedObj.id );
247                 $tp.find( '.volume_control' ).unbind().btnBind().click( function() {
248                         js_log( 'clicked volume control' );
249                         $j( '#' + embedObj.id ).get( 0 ).toggleMute();
250                 } );
251                 // add vertical volume display hover
252                 if ( this.volume_layout == 'vertical' ) {
253                         // default volume binding:
254                         var hoverOverDelay = false;
255                         var $tpvol = $tp.find( '.vol_container' );
256                         $tp.find( '.volume_control' ).hover(
257                                 function() {
258                                         $tpvol.addClass( 'vol_container_top' );
259                                         // set to "below" if playing and embedType != native
260                                         if ( embedObj && embedObj.isPlaying && embedObj.isPlaying() && !embedObj.supports['overlays'] ) {
261                                                 $tpvol.removeClass( 'vol_container_top' ).addClass( 'vol_container_below' );
262                                         }
263                                         $tpvol.fadeIn( 'fast' );
264                                         hoverOverDelay = true;
265                                 },
266                                 function() {
267                                         hoverOverDelay = false;
268                                         setTimeout( function doHideVolume() {
269                                                 if ( !hoverOverDelay ) {
270                                                         $tpvol.fadeOut( 'fast' );
271                                                 }
272                                         }, 500 );
273                                 }
274                         );
275                 }
276                 
277                 // setup slider:
278                 var sliderConf = {
279                         range: "min",
280                         value: 80,
281                         min: 0,
282                         max: 100,
283                         slide: function( event, ui ) {
284                                 var perc = ui.value / 100;
285                                 // js_log('update volume:' + perc);
286                                 embedObj.updateVolumen( perc );
287                         },
288                         change:function( event, ui ) {
289                                 var perc = ui.value / 100;
290                                 if ( perc == 0 ) {
291                                         $tp.find( '.volume_control span' ).removeClass( 'ui-icon-volume-on' ).addClass( 'ui-icon-volume-off' );
292                                 } else {
293                                         $tp.find( '.volume_control span' ).removeClass( 'ui-icon-volume-off' ).addClass( 'ui-icon-volume-on' );
294                                 }
295                                 var perc = ui.value / 100;
296                                 embedObj.updateVolumen( perc );
297                         }
298                 }
299                 
300                 if ( this.volume_layout == 'vertical' )
301                         sliderConf['orientation'] = "vertical";
302                 
303                 $tp.find( '.volume-slider' ).slider( sliderConf );
304         },
305         getMvBufferHtml:function() {
306                 return '<div class="ui-slider-range ui-slider-range-min ui-widget-header ' +
307                                 'ui-state-highlight ui-corner-all ' +
308                                 'mv_buffer" style="width:0px;height:100%;z-index:1;top:0px" />';
309         },
310         getComponent:function( component ) {
311                 if ( this.components[ component ] ) {
312                         return this.components[ component ].o( this );
313                 } else {
314                         return false;
315                 }
316         },
317         /*
318         * components take in the embedObj and return some html for the given component.
319         * components can be overwritten by skin javascript
320         */
321         components: {
322                 'borders': {
323                         'w':8,
324                         'o':function( ctrlObj ) {
325                                 return  '';
326                         }
327                 },
328                 'play-btn-large': {
329                         'w' : 130,
330                         'h' : 96,
331                         'o':function( ctrlObj ) {
332                                 // get dynamic position for big play button (@@todo maybe use margin:auto ? )
333                                 return $j( '<div/>' ).attr( {
334                                                                 'title' : gM( 'mwe-play_clip' ),
335                                                                 'class' : "ui-state-default play-btn-large"
336                                                         } )
337                                                         .css( {
338                                                                 'left'  : ( ( ctrlObj.embedObj.playerPixelWidth() - this.w ) / 2 ),
339                                                                 'top'   : ( ( ctrlObj.embedObj.playerPixelHeight() - this.h ) / 2 )
340                                                         } )
341                                                         .wrap( '<div/>' ).parent().html();
342                         }
343                 },
344                 'mv_embedded_options': {
345                         'w':0,
346                         'o':function( ctrlObj ) {
347                                 var o = '<div id="mv_vid_options_' + ctrlObj.id + '" class="videoOptions">' +
348                                 '<div class="videoOptionsTop"></div>' +
349                                 '<div class="videoOptionsBox">' +
350                                 '<div class="block">' +
351                                         '<h6>Video Options</h6>' +
352                                 '</div>' +
353                                         '<div class="block">' +
354                                                 '<p class="short_match vo_selection"><a href="#"><span>' + gM( 'mwe-chose_player' ) + '</span></a></p>' +
355                                                 '<p class="short_match vo_download"><a href="#"><span>' + gM( 'mwe-download' ) + '</span></a></p>' +
356                                                 '<p class="short_match vo_showcode"><a href="#"><span>' + gM( 'mwe-share' ) + '</span></a></p>';
358                                         // link to the stream page if we are not already there:
359                                         if ( ( ctrlObj.embedObj.roe || ctrlObj.embedObj.linkback ) && typeof mv_stream_interface == 'undefined' )
360                                                 o += '<p class="short_match"><a href="javascript:$j(\'#' + ctrlObj.id + '\').get(0).doLinkBack()"><span><strong>Source Page</strong></span></a></p>';
362                                 o += '</div>' +
363                                 '</div><!--videoOptionsInner-->' +
364                                         '<div class="videoOptionsBot"></div>' +
365                                 '</div><!--videoOptions-->';
366                                 return o;
367                         }
368                 },
369                 'fullscreen': {
370                         'w':20,
371                         'o':function( ctrlObj ) {
372                                 return '<div title="' + gM( 'mwe-player_fullscreen' ) + '" class="ui-state-default ui-corner-all ui-icon_link rButton fullscreen-btn">' +
373                                                         '<span class="ui-icon ui-icon-arrow-4-diag"></span>' +
374                                                 '</div>'
375                         }
376                 },
377                 'options': {
378                         'w':26,
379                         'o':function( ctrlObj ) {
380                                 return '<div title="' + gM( 'mwe-player_options' ) + '" class="ui-state-default ui-corner-all ui-icon_link rButton options-btn">' +
381                                                         '<span class="ui-icon ui-icon-wrench"></span>' +
382                                                 '</div>';
383                         }
384                 },
385                 'pause': {
386                         'w':24,
387                         'o':function( ctrlObj ) {
388                                 return '<div title="' + gM( 'mwe-play_clip' ) + '" class="ui-state-default ui-corner-all ui-icon_link lButton play-btn">' +
389                                                         '<span class="ui-icon ui-icon-play"/>' +
390                                                 '</div>';
391                         }
392                 },
393                 'closed_captions': {
394                         'w':23,
395                         'o':function( ctrlObj ) {
396                                 return '<div title="' + gM( 'mwe-closed_captions' ) + '" class="ui-state-default ui-corner-all ui-icon_link rButton timed-text">' +
397                                                         '<span class="ui-icon ui-icon-comment"></span>' +
398                                                 '</div>'
399                         }
400                 },
401                 'volume_control': {
402                         'w':23,
403                         'o':function( ctrlObj ) {
404                                 var o = '';
405                                 if ( ctrlObj.volume_layout == 'horizontal' )
406                                         o += '<div class="ui-slider ui-slider-horizontal rButton volume-slider"></div>';
407                                         
408                                 o += '<div title="' + gM( 'mwe-volume_control' ) + '" class="ui-state-default ui-corner-all ui-icon_link rButton volume_control">' +
409                                                 '<span class="ui-icon ui-icon-volume-on"></span>';
410                                                 
411                                 if ( ctrlObj.volume_layout == 'vertical' ) {
412                                         o += '<div style="position:absolute;display:none;left:0px;" class="vol_container ui-corner-all">' +
413                                                         '<div class="volume-slider" ></div>' +
414                                                 '</div>';
415                                 }
416                                 o += '</div>';
417                                 return o;
418                         }
419                 },
420                 'time_display': {
421                         'w':90,
422                         'o':function( ctrlObj ) {
423                                 return '<div class="ui-widget time-disp">' + ctrlObj.embedObj.getTimeReq() + '</div>';
424                         }
425                 },
426                 'play_head': {
427                         'w':0, // special case (takes up remaining space)
428                         'o':function( ctrlObj ) {
429                                 return '<div class="play_head" style="width: ' + ( ctrlObj.available_width - 34 ) + 'px;"></div>';
430                         }
431                 }
432         }