1 //set the dismissNativeWarn flag:
2 _global
['dismissNativeWarn'] = false;
5 * Msg text is inherited from embedVideo (we should move it here (although can't load ctrlBuilder without parent EmbedVideo obj)
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:
19 ctrlBuilder
.prototype = {
20 init:function( embedObj
, opt
){
22 this.embedObj
= embedObj
;
24 //check for skin overrides for ctrlBuilder
25 if( _global
[ embedObj
.skin_name
+ 'Config'] ){
26 //clone as to not overide prototype:
27 var _this
= $j
.extend(true, {}, this, _global
[ embedObj
.skin_name
+ 'Config']);
35 //default volume layout is "vertical"
36 volume_layout
: 'vertical',
48 getControls:function(){
49 //set up local pointer to the embedObj
50 var embedObj
= this.embedObj
;
51 //set up loadl ctrlBuilder ref
54 js_log('f:controlsBuilder:: opt:' + this.options
);
55 this.id
= (embedObj
.pc
)?embedObj
.pc
.pp
.id
:embedObj
.id
;
56 this.available_width
= embedObj
.playerPixelWidth();
57 //make pointer to the embedObj
58 this.embedObj
=embedObj
;
60 for(var i
in embedObj
.supports
){
61 _this
.supports
[i
] = embedObj
.supports
[i
];
66 (embedObj
.media_element
.timedTextSources
&&
67 embedObj
.media_element
.timedTextSources() )
68 ) && embedObj
.show_meta_link
)
69 this.supports
['closed_captions']=true;
72 //append options to body (if not already there)
73 if( _this
.body_options
&& $j('#mv_vid_options_' + this.id
).length
== 0 )
74 $j('body').append( this.components
['mv_embedded_options'].o( this ) );
77 for( var i
in this.components
){
78 if( this.supports
[i
] ){
79 if( this.available_width
> this.components
[i
].w
){
80 //special case with playhead don't add unless we have 60px
81 if( i
== 'play_head' && this.available_width
< 60 )
83 o
+=this.components
[i
].o( this );
84 this.available_width
-= this.components
[i
].w
;
86 js_log('not enough space for control component:' + i
);
94 * to be run once controls are attached to the dom
96 addControlHooks:function(){
97 //set up local pointer to the embedObj
98 var embedObj
= this.embedObj
;
100 //add in drag/seek hooks:
101 if(!embedObj
.base_seeker_slider_offset
&& $j('#mv_seeker_slider_'+embedObj
.id
).get(0))
102 embedObj
.base_seeker_slider_offset
= $j('#mv_seeker_slider_'+embedObj
.id
).get(0).offsetLeft
;
104 //js_log('looking for: #mv_seeker_slider_'+embedObj.id + "\n " +
105 // 'start sec: '+embedObj.start_time_sec + ' base offset: '+embedObj.base_seeker_slider_offset);
106 var $tp
=$j('#' + embedObj
.id
);
109 $tp
.find('.play-btn').unbind().btnBind().click(function(){
110 $j('#' + embedObj
.id
).get(0).play();
113 //do play-btn-large binding:
114 $tp
.find('.play-btn-large' ).unbind().btnBind().click(function(){
115 $j('#' + embedObj
.id
).get(0).play();
118 //add recommend firefox if we have non-native playback:
119 if( embedObj
.doNativeWarningCheck() ){
120 $j('#dc_'+ embedObj
.id
).hover(
122 if($j('#gnp_' + embedObj
.id
).length
==0){
123 $j(this).append('<div id="gnp_' + embedObj
.id
+ '" class="ui-state-highlight ui-corner-all" ' +
124 'style="position:absolute;display:none;background:#FFF;top:10px;left:10px;right:10px;">' +
125 gM('mwe-for_best_experience') +
126 '<br><input id="ffwarn_'+embedObj
.id
+'" type=\"checkbox\">' +
127 gM('mwe-do_not_warn_again') +
129 $j('#ffwarn_'+embedObj
.id
).click(function(){
130 if( $j(this).is(':checked') ){
131 //set up a cookie for 7 days:
132 $j
.cookie('dismissNativeWarn', true, { expires
: 5 });
133 //set the current instance
134 _global
['dismissNativeWarn'] = true;
135 $j('#gnp_' + embedObj
.id
).fadeOut('slow');
137 _global
['adismissNativeWarn'] = false;
138 $j
.cookie('dismissNativeWarn', false);
143 if( ($j
.cookie('dismissNativeWarn') !== true) &&
144 _global
['dismissNativeWarn'] === false ){
145 $j('#gnp_' + embedObj
.id
).fadeIn('slow');
149 $j('#gnp_' + embedObj
.id
).fadeOut('slow');
154 if( $j
.browser
.msie
&& $j
.browser
.version
<= 6){
155 $j( embedObj
.id
+ ' .play-btn-large' ).pngFix();
160 $j('#timed_text_' + embedObj
.id
).unbind().btnBind().click(function(){
161 $j('#' + embedObj
.id
).get(0).showTextInterface();
165 $tp
.find('.options-btn').unbind().btnBind().click(function(){
166 $j('#' +embedObj
.id
).get(0).doOptionsHTML();
169 //fullscreen binding:
170 $tp
.find('.fullscreen-btn').unbind().btnBind().click(function(){
171 $j('#' +embedObj
.id
).get(0).fullscreen();
174 js_log(" should add slider binding: " + $j('#'+embedObj
.id
+ ' .play_head').length
) ;
175 $tp
.find('.play_head').slider({
180 start: function(event
, ui
){
181 var id
= (embedObj
.pc
!=null)?embedObj
.pc
.pp
.id
:embedObj
.id
;
182 embedObj
.userSlide
=true;
183 $j(id
+ ' .play-btn-large').fadeOut('fast');
184 //if playlist always start at 0
185 embedObj
.start_time_sec
= (embedObj
.instanceOf
== 'mvPlayList')?0:
186 npt2seconds(embedObj
.getTimeReq().split('/')[0]);
188 slide: function(event
, ui
) {
189 var perc
= ui
.value
/1000;
190 embedObj
.jump_time
= seconds2npt( parseFloat( parseFloat(embedObj
.getDuration()) * perc
) + embedObj
.start_time_sec
);
191 //js_log('perc:' + perc + ' * ' + embedObj.getDuration() + ' jt:'+ this.jump_time);
192 if( _this
.long_time_disp
){
193 embedObj
.setStatus( gM('mwe-seek_to', embedObj
.jump_time
) );
195 embedObj
.setStatus( embedObj
.jump_time
);
197 //update the thumbnail / frame
198 if(embedObj
.isPlaying
==false){
199 embedObj
.updateThumbPerc( perc
);
202 change:function(event
, ui
){
203 //only run the onChange event if done by a user slide:
204 if(embedObj
.userSlide
){
205 embedObj
.userSlide
=false;
206 embedObj
.seeking
=true;
207 //stop the monitor timer (if we can)
208 if(embedObj
.stopMonitor
)
209 embedObj
.stopMonitor();
211 var perc
= ui
.value
/1000;
212 //set seek time (in case we have to do a url seek)
213 embedObj
.seek_time_sec
= npt2seconds( embedObj
.jump_time
, true );
214 js_log('do jump to: '+embedObj
.jump_time
+ ' perc:' +perc
+ ' sts:' + embedObj
.seek_time_sec
);
215 embedObj
.setStatus( gM('mwe-seeking') );
216 embedObj
.doSeek(perc
);
220 //up the z-index of the default status indicator:
221 $tp
.find('.play_head .ui-slider-handle').css('z-index', 4);
222 $tp
.find('.play_head .ui-slider-range').addClass('ui-corner-all').css('z-index', 2);
223 //extended class list for jQuery ui themeing (we can probably refactor this with custom buffering highliter)
224 $tp
.find('.play_head').append( this.getMvBufferHtml() );
226 $opt
= $j('#mv_vid_options_'+embedObj
.id
);
227 //videoOptions ... @@todo should be merged with something more like kskin.js:
228 $opt
.find('.vo_selection').click(function(){
229 embedObj
.displayHTML();
230 embedObj
.showPlayerselect( $tp
.find('.videoOptionsComplete') );
234 $opt
.find('.vo_download').click(function(){
235 embedObj
.displayHTML();
236 embedObj
.showDownload( $tp
.find('.videoOptionsComplete') );
240 $opt
.find('.vo_showcode').click(function(){
241 embedObj
.displayHTML();
242 embedObj
.showShare( $tp
.find('.videoOptionsComplete') );
246 this.doVolumeBinding();
248 //check if we have any custom skin hooks to run (only one per skin)
249 if( this.addSkinControlHooks
&& typeof( this.addSkinControlHooks
) == 'function')
250 this.addSkinControlHooks();
252 doVolumeBinding:function(){
253 var embedObj
= this.embedObj
;
255 var $tp
=$j('#' + embedObj
.id
);
256 //default volume binding:
257 var hoverOverDelay
=false;
258 $tp
.find('.volume_control').unbind().btnBind().click(function(){
259 $j('#' +embedObj
.id
).get(0).toggleMute();
262 $j('#vol_container_' + embedObj
.id
).addClass('vol_container_top');
263 //set to "below" if playing and embedType != native
264 if(embedObj
&& embedObj
.isPlaying
&& embedObj
.isPlaying() && !embedObj
.supports
['overlays']){
265 $j('#vol_container_' + embedObj
.id
).removeClass('vol_container_top').addClass('vol_container_below');
268 $j('#vol_container_' + embedObj
.id
).fadeIn('fast');
269 hoverOverDelay
= true;
272 hoverOverDelay
= false;
273 setTimeout(function doHideVolume(){
275 $j('#vol_container_' + embedObj
.id
).fadeOut('fast');
281 $j('#volume_bar_'+embedObj
.id
).slider({
282 orientation
: "vertical",
287 slide: function(event
, ui
) {
288 var perc
= ui
.value
/100;
289 //js_log('update volume:' + perc);
290 embedObj
.updateVolumen(perc
);
292 change:function(event
, ui
){
293 var perc
= ui
.value
/100;
295 $j('#' + embedObj
.id
+ ' .volume_control span').removeClass('ui-icon-volume-on').addClass('ui-icon-volume-off');
297 $j('#' + embedObj
.id
+ ' .volume_control span').removeClass('ui-icon-volume-off').addClass('ui-icon-volume-on');
299 //only run the onChange event if done by a user slide:
300 if(embedObj
.userSlide
){
301 embedObj
.userSlide
=false;
302 embedObj
.seeking
=true;
303 var perc
= ui
.value
/100;
304 embedObj
.updateVolumen(perc
);
309 getMvBufferHtml:function(){
310 return '<div class="ui-slider-range ui-slider-range-min ui-widget-header ' +
311 'ui-state-highlight ui-corner-all '+
312 'mv_buffer" style="width:0px;height:100%;z-index:1;top:0px" />';
314 getComponent:function( component
) {
315 if( this.components
[ component
] ){
316 return this.components
[ component
].o( this );
322 * components take in the embedObj and return some html for the given component.
323 * components can be overwritten by skin javascript
328 'o':function( ctrlObj
){
335 'o':function( ctrlObj
){
336 //get dynamic position for big play button (@@todo maybe use margin:auto ? )
337 return $j('<div/>').attr({
338 'title' : gM('mwe-play_clip'),
339 'class' : "ui-state-default play-btn-large"
342 'left' : ((ctrlObj
.embedObj
.playerPixelWidth() - this.w
)/2),
343 'top' : ((ctrlObj
.embedObj
.playerPixelHeight() - this.h
)/2)
345 .wrap('<div/>').parent().html();
348 'mv_embedded_options':{
350 'o':function( ctrlObj
){
351 var o
= '<div id="mv_vid_options_'+ctrlObj
.id
+'" class="videoOptions">'+
352 '<div class="videoOptionsTop"></div>'+
353 '<div class="videoOptionsBox">'+
354 '<div class="block">'+
355 '<h6>Video Options</h6>'+
357 '<div class="block">'+
358 '<p class="short_match vo_selection"><a href="#"><span>'+gM('mwe-chose_player')+'</span></a></p>'+
359 '<p class="short_match vo_download"><a href="#"><span>'+gM('mwe-download')+'</span></a></p>'+
360 '<p class="short_match vo_showcode"><a href="#"><span>'+gM('mwe-share')+'</span></a></p>';
362 //link to the stream page if we are not already there:
363 if( ctrlObj
.embedObj
.roe
&& typeof mv_stream_interface
== 'undefined' )
364 o
+='<p class="short_match"><a href="javascript:$j(\'#'+ctrlObj
.id
+'\').get(0).doLinkBack()"><span><strong>Source Page</strong></span></a></p>';
367 '</div><!--videoOptionsInner-->' +
368 '<div class="videoOptionsBot"></div>' +
369 '</div><!--videoOptions-->';
375 'o':function( ctrlObj
){
376 return '<div title="' + gM('mwe-player_fullscreen') + '" class="ui-state-default ui-corner-all ui-icon_link rButton fullscreen-btn">'+
377 '<span class="ui-icon ui-icon-arrow-4-diag"></span>'+
383 'o':function( ctrlObj
){
384 return '<div title="' + gM('mwe-player_options') + '" class="ui-state-default ui-corner-all ui-icon_link rButton options-btn">' +
385 '<span class="ui-icon ui-icon-wrench"></span>' +
391 'o':function( ctrlObj
){
392 return '<div title="' + gM('mwe-play_clip') + '" class="ui-state-default ui-corner-all ui-icon_link lButton play-btn">'+
393 '<span class="ui-icon ui-icon-play"/>'+
399 'o':function( ctrlObj
){
400 return '<div title="' + gM('mwe-closed_captions') + '" id="timed_text_'+ctrlObj
.id
+'" class="ui-state-default ui-corner-all ui-icon_link rButton">'+
401 '<span class="ui-icon ui-icon-comment"></span>'+
407 'o':function( ctrlObj
){
409 if ( ctrlObj
.volume_layout
== 'horizontal' )
410 o
+='<div class="ui-slider ui-slider-horizontal rButton volume-slider"></div>';
412 o
+= '<div title="' + gM('mwe-volume_control') + '" class="ui-state-default ui-corner-all ui-icon_link rButton volume_control">' +
413 '<span class="ui-icon ui-icon-volume-on"></span>';
415 if( ctrlObj
.volume_layout
== 'vertical'){
416 o
+='<div style="position:absolute;display:none;" id="vol_container_'+ctrlObj
.id
+'" class="vol_container ui-corner-all">' +
417 '<div class="volume_bar" id="volume_bar_' + ctrlObj
.id
+ '"></div>' +
426 'o':function( ctrlObj
){
427 return '<div class="ui-widget time-disp">' + ctrlObj
.embedObj
.getTimeReq() + '</div>';
431 'w':0, //special case (takes up remaining space)
432 'o':function( ctrlObj
){
433 return '<div class="play_head" style="width: ' + ( ctrlObj
.available_width
- 30 ) + 'px;"></div>';