1 //set the dismissNativeWarn flag:
2 _global
['dismissNativeWarn'] = false;
4 var baseSkin = function(){
20 default_menu_item
:'download',
23 getControls:function( embedObj
){
24 js_log('f:controlsBuilder:: opt:');
25 this.id
= (embedObj
.pc
)?embedObj
.pc
.pp
.id
:embedObj
.id
;
26 this.available_width
= embedObj
.playerPixelWidth();
27 //make pointer to the embedObj
28 this.embedObj
= embedObj
;
30 for(var i
in embedObj
.supports
){
31 _this
.supports
[i
] = embedObj
.supports
[i
];
34 //check for close_captions tracks:
35 if( ( embedObj
.roe
|| embedObj
.timedTextSources() )
36 && embedObj
.show_meta_link
)
37 this.supports
['closed_captions']=true;
40 //get the length of the play_head
41 this.player_head_length
= embedObj
.playerPixelWidth();
42 for( var i
in this.components
){
43 if( this.supports
[i
] ){
44 if( i
!= 'play_head'){
45 this.player_head_length
-= this.components
[i
].w
;
49 for(var i
in this.components
){
50 if( this.supports
[i
] ){
51 if( this.available_width
> this.components
[i
].w
){
52 //special case with playhead don't add unless we have 60px
53 if( i
== 'play_head' && this.player_head_length
< 60 )
55 o
+=this.components
[i
].o();
56 this.available_width
-= this.components
[i
].w
;
58 js_log('not enough space for control component:' + i
);
66 * to be run once controls are attached to the dom
68 addControlHooks:function( embedObj
){
69 //add in drag/seek hooks:
70 if(!embedObj
.base_seeker_slider_offset
&& $j('#mv_seeker_slider_'+embedObj
.id
).get(0))
71 embedObj
.base_seeker_slider_offset
= $j('#mv_seeker_slider_'+embedObj
.id
).get(0).offsetLeft
;
73 //js_log('looking for: #mv_seeker_slider_'+embedObj.id + "\n " +
74 // 'start sec: '+embedObj.start_time_sec + ' base offset: '+embedObj.base_seeker_slider_offset);
76 var $tp
=$j('#' + embedObj
.id
);
78 //@todo: which object is being play()'d (or whatever) ?
79 //We select the element to attach the event to this way:
80 //$tp.find('.ui-icon-play').parent().click(function(){alert(0)}); or we can give the button itself a class - probably better.
82 //add play hook for play-btn and large_play_button
83 $tp
.find('.play-btn,.play-btn-large').unbind().btnBind().click(function(){
84 $j('#' + embedObj
.id
).get(0).play();
86 //add recomend firefox if non-native playback:
87 if( embedObj
.doNativeWarningCheck() ){
88 $j('#dc_'+ embedObj
.id
).hover(
90 if($j('#gnp_' + embedObj
.id
).length
==0){
91 $j(this).append('<div id="gnp_' + embedObj
.id
+ '" class="ui-state-highlight ui-corner-all" ' +
92 'style="position:absolute;display:none;background:#FFF;top:10px;left:10px;right:10px;height:60px;">' +
93 gM('mv_for_best_experience') +
94 '<br><input id="ffwarn_'+embedObj
.id
+'" type=\"checkbox\">' +
95 gM('mv_do_not_warn_again') +
97 $j('#ffwarn_'+embedObj
.id
).click(function(){
98 if( $j(this).is(':checked') ){
99 //set up a cookie for 5 days:
100 $j
.cookie('dismissNativeWarn', true, { expires
: 5 });
101 //set the current instance
102 _global
['dismissNativeWarn'] = true;
103 $j('#gnp_' + embedObj
.id
).fadeOut('slow');
105 _global
['adismissNativeWarn'] = false;
106 $j
.cookie('dismissNativeWarn', false);
111 if( ($j
.cookie('dismissNativeWarn') !== true) &&
112 _global
['dismissNativeWarn'] === false ){
113 $j('#gnp_' + embedObj
.id
).fadeIn('slow');
117 $j('#gnp_' + embedObj
.id
).fadeOut('slow');
122 if( $j
.browser
.msie
&& $j
.browser
.version
<= 6){
123 $j('#big_play_link_' + embedObj
.id
).pngFix();
127 $j('#timed_text_' + embedObj
.id
).unbind().btnBind().click(function(){
128 $j('#' + embedObj
.id
).get(0).showTextInterface();
132 $j('#options_button_' + embedObj
.id
).unbind().btnBind().click(function(){
133 $j('#' +embedObj
.id
).get(0).doOptionsHTML();
136 //fullscreen binding:
137 $j('#fullscreen_' + embedObj
.id
).unbind().btnBind().click(function(){
138 $j('#' +embedObj
.id
).get(0).fullscreen();
141 js_log(" should add slider binding: " + $j('#mv_play_head_'+embedObj
.id
).length
) ;
142 // $j('#mv_play_head_'+embedObj.id).slider({
143 $tp
.find( '.j-scrubber' ).slider({
148 start: function(event
, ui
){
149 var id
= (embedObj
.pc
!=null)?embedObj
.pc
.pp
.id
:embedObj
.id
;
150 embedObj
.userSlide
=true;
151 $j('#big_play_link_'+id
).fadeOut('fast');
152 //if playlist always start at 0
153 embedObj
.start_time_sec
= (embedObj
.instanceOf
== 'mvPlayList')?0:
154 npt2seconds(embedObj
.getTimeReq().split('/')[0]);
156 slide: function(event
, ui
) {
157 var perc
= ui
.value
/1000;
158 embedObj
.jump_time
= seconds2npt( parseFloat( parseFloat(embedObj
.getDuration()) * perc
) + embedObj
.start_time_sec
);
159 //js_log('perc:' + perc + ' * ' + embedObj.getDuration() + ' jt:'+ this.jump_time);
160 embedObj
.setStatus( gM('seek_to')+' '+embedObj
.jump_time
);
161 //update the thumbnail / frame
162 if(embedObj
.isPlaying
==false){
163 embedObj
.updateThumbPerc( perc
);
166 change:function(event
, ui
){
167 //only run the onChange event if done by a user slide:
168 if(embedObj
.userSlide
){
169 embedObj
.userSlide
=false;
170 embedObj
.seeking
=true;
171 //stop the monitor timer (if we can)
172 if(embedObj
.stopMonitor
)
173 embedObj
.stopMonitor();
175 var perc
= ui
.value
/1000;
176 //set seek time (in case we have to do a url seek)
177 embedObj
.seek_time_sec
= npt2seconds( embedObj
.jump_time
, true );
178 js_log('do jump to: '+embedObj
.jump_time
+ ' perc:' +perc
+ ' sts:' + embedObj
.seek_time_sec
);
179 embedObj
.doSeek(perc
);
183 //@todo: identify problem with volume button jumping...
184 $tp
.find('.k-volume-slider').slider({
189 slide: function(event
, ui
) {
190 embedObj
.updateVolumen(ui
.value
/100);
192 change: function(event
, ui
){
193 var level
= ui
.value
/100;
195 $tp
.find('.k-volume span').addClass('ui-icon-volume-off');
197 $tp
.find('.k-volume span').removeClass('ui-icon-volume-off');
199 //only run the onChange event if done by a user slide:
200 if(embedObj
.userSlide
){
201 embedObj
.userSlide
=false;
202 embedObj
.seeking
=true;
203 // var perc = ui.value/100;
204 embedObj
.updateVolumen(level
);
208 //up the z-index of the default status indicator:
209 // $j('#mv_play_head_'+embedObj.id + ' .ui-slider-handle').css('z-index', 4);
210 // $j('#mv_play_head_'+embedObj.id + ' .ui-slider-range').addClass('ui-corner-all').css('z-index', 2);
211 //extended class list for jQuery ui themeing (we can probably refactor this with custom buffering highliter)
212 $j('#' + embedObj
.id
+ ' .j-scrubber').prepend( ctrlBuilder
.getMvBufferHtml() );
215 //adds options and bindings: (we do this onClick for faster vidoe tag startup times)
216 var addMvOptions = function(){
217 if($j('#' + embedObj
.id
+ ' .k-menu').length
!= 0 )
220 $j('#' + embedObj
.id
).prepend( ctrlBuilder
.components
['mv_embedded_options'].o( embedObj
) );
222 //by default its hidden:
223 $tp
.find('.k-menu').hide();
226 for(i
=0; i
< ctrlBuilder
.menu_items
.length
; i
++){
227 $tp
.find('.k-' + ctrlBuilder
.menu_items
[i
] + '-btn').click(function(){
228 var mk
= $j(this).attr('rel');
229 $target
= $j('#' + embedObj
.id
+ ' .menu-'+mk
).hide();
230 //gennerate the menu html not already done:
231 if( $target
.children().length
== 0 ){
232 //call the function show{Menuitem} with target:
233 embedObj
['show' + mk
.charAt(0).toUpperCase() + mk
.substring(1)](
234 $j('#' + embedObj
.id
+ ' .menu-'+mk
)
237 //slide out the others
238 $j('#' + embedObj
.id
+ ' .menu-screen').hide();
239 $target
.fadeIn("fast");
240 //don't follow the # link
246 //options menu display:
247 $tp
.find('.k-options').click(function(){
248 if($j('#' + embedObj
.id
+ ' .k-menu').length
== 0 )
250 //set up the text and menu:
251 var $ktxt
= $j(this).find('.ui-icon-k-menu');
252 var $kmenu
= $tp
.find('.k-menu');
253 if( $kmenu
.is(':visible') ){
254 $kmenu
.fadeOut("fast",function(){
255 $ktxt
.html ( gM('menu_btn') );
257 $tp
.find('.play-btn-large').fadeIn('fast');
259 $kmenu
.fadeIn("fast", function(){
260 $ktxt
.html ( gM('close_btn') );
262 $tp
.find('.play-btn-large').fadeOut('fast');
267 $tp
.find('.k-volume').unbind().btnBind().click(function(){
271 var hoverOverDelay
=false;
272 /*$j('#volume_control_'+embedObj.id).unbind().btnBind().click(function(){
273 $j('#' +embedObj.id).get(0).toggleMute();
277 $j('#vol_container_' + embedObj.id).addClass('vol_container_top');
278 //set to "below" if playing and embedType != native
279 if(embedObj && embedObj.isPlaying() && !embedObj.supports['overlays']){
280 $j('#vol_container_' + embedObj.id).removeClass('vol_container_top').addClass('vol_container_below');
283 $j('#vol_container_' + embedObj.id).fadeIn('fast');
284 hoverOverDelay = true;
287 hoverOverDelay= false;
288 setTimeout(function doHideVolume(){
290 $j('#vol_container_' + embedObj.id).fadeOut('fast');
296 $j('#volume_bar_'+embedObj.id).slider({
297 orientation: "vertical",
302 slide: function(event, ui) {
303 var perc = ui.value/100;
304 //js_log('update volume:' + perc);
305 embedObj.updateVolumen(perc);
307 change:function(event, ui){
308 var perc = ui.value/100;
310 $j('#volume_control_'+embedObj.id + ' span').removeClass('ui-icon-volume-on').addClass('ui-icon-volume-off');
312 $j('#volume_control_'+embedObj.id + ' span').removeClass('ui-icon-volume-off').addClass('ui-icon-volume-on');
314 //only run the onChange event if done by a user slide:
315 if(embedObj.userSlide){
316 embedObj.userSlide=false;
317 embedObj.seeking=true;
318 var perc = ui.value/100;
319 embedObj.updateVolumen(perc);
325 getMvBufferHtml:function(){
326 return '<div class="ui-slider-horizontal ui-corner-all ui-slider-buffer" />';
335 'mv_embedded_options':{
337 'o':function( embedObj
){
339 '<div class="k-menu ui-widget-content" ' +
340 'style="width:' + embedObj
.playerPixelWidth() + 'px; height:' + embedObj
.playerPixelHeight() + 'px;">' +
341 '<ul class="k-menu-bar">';
342 //output menu item containers:
343 for(i
=0; i
< ctrlBuilder
.menu_items
.length
; i
++){
344 var mk
= ctrlBuilder
.menu_items
[i
];
345 o
+= '<li class="k-' + mk
+ '-btn" rel="' + mk
+ '">' +
346 '<a href="#" title="' + gM( mk
) +'">' + gM( mk
) +'</a></li>';
349 //we have to substract the width of the k-menu-bar
350 '<div class="k-menu-screens" style="width:' + ( embedObj
.playerPixelWidth() -75) +
351 'px; height:' + (embedObj
.playerPixelHeight() - ctrlBuilder
.height
) + 'px;">';
353 //output menu item containers:
354 for(i
=0; i
< ctrlBuilder
.menu_items
.length
; i
++){
355 o
+= '<div class="menu-screen menu-' + ctrlBuilder
.menu_items
[i
] + '"></div>';
365 return '<button class="play-btn ui-state-default ui-corner-all" title="' +
366 gM('play_clip') + '" ><span class="ui-icon ui-icon-play"></span></button>'
369 'play_head':{ // scrubber
370 'w':0, //special case (takes up remaining space)
372 return '<div class="ui-slider ui-slider-horizontal ui-corner-all j-scrubber"' +
373 ' style="width:' + ( ctrlBuilder
.player_head_length
- 30 ) + 'px;"></div>'
379 return '<div class="k-timer">' + seconds2npt ( ctrlBuilder
.embedObj
.getDuration() ) + '</div>';
385 return '<button class="ui-state-default ui-corner-all k-volume">' +
386 '<span class="ui-icon ui-icon-volume-on"></span>' +
388 '<div class="ui-slider ui-slider-horizontal k-volume-slider"></div>';
390 //vertical volume control:
391 /* return '<div title="' + gM('volume_control') + '" id="volume_control_'+ctrlBuilder.id+'" class="ui-state-default ui-corner-all ui-icon_link rButton">' +
392 '<span class="ui-icon ui-icon-volume-on"></span>' +
393 '<div style="position:absolute;display:none;" id="vol_container_'+ctrlBuilder.id+'" class="vol_container ui-corner-all">' +
394 '<div class="volume_bar" id="volume_bar_' + ctrlBuilder.id + '"></div>' +
403 return '<div title="' + gM('closed_captions') + '" id="timed_text_' + ctrlBuilder
.id
+'" ' +
404 'class="ui-state-default ui-corner-all ui-icon_link rButton">' +
405 '<span class="ui-icon ui-icon-comment"></span></div>';
411 return '<button class="ui-state-default ui-corner-all k-fullscreen" title="' + gM('player_fullscreen') + '">' +
412 '<span class="ui-icon ui-icon-arrow-4-diag"></span></button>'
418 return '<button class="ui-state-default ui-corner-bl k-options" title="'+ gM('player_options') + '" >' +